Para los que quizás no entiendan el código, acá quise hacer una explicación super detallada
Introducción al pensamiento computacional
Introducción al pensamiento computacional
Introducción al cómputo
Introducción a los lenguajes de programación
Introducción a Python
Preparación de tu computadora
Elementos básicos de Python
Asignación de variables
Cadenas y entradas
Programas ramificados
Iteraciones
Bucles for
Programas numéricos
Representación de flotantes
Enumeración exhaustiva
Aproximación de soluciones
Búsqueda Binaria
Funciones, alcance y abstracción
Funciones y abstracción
Scope o Alcance
Especificaciones del código
Recursividad
Fibonnacci y la Recursividad
Tipos estructurados, mutabilidad y funciones de alto nivel
Funciones como objetos
Tuplas
Rangos
Listas y mutabilidad
Diccionarios
Pruebas y debugging
Pruebas de caja negra
Pruebas de caja de cristal
Debugging
Excepciones y afirmaciones
Manejo de excepciones
Excepciones y control de flujo
Afirmaciones
Conclusiones
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Aportes 528
Preguntas 65
Para los que quizás no entiendan el código, acá quise hacer una explicación super detallada
Hice unas pruebas con varios lenguajes para probar cuanto se demoraban y eso encontré
Para una encontrar la raiz de 121 con un epsilon de 0.0001 realizando 3 mediciones con cada lenguaje este fue el promedio en cada uno.
Go 1.95 segundos
C 8.30 segundos
C++ 13.48 segundos
javaScript 37.15 segundos
Python 364.80 segundos
Como me costó entenderlo, trato aquí de dejarlo lo más aclarado posible, espero les sirva:
Es explicación larga, pero creo yo que clara.
Aún espero xd
.
Les comparto como podrian medir el tiempo de ejecucion de su programa
import time
start_time = time.time()
Importamos la libreria time y guardamos en una variable el tiempo de inicio del programa
print("--- %s seconds ---" % (time.time() - start_time))
Una vez que termine tomamos la hora actual y las restamos y eso nos dara el tiempo de ejecucion de nuestro programa
Me tomo varios minutos entender el programa debido a que me costo un poco entender la explicación de David, voy a tratar de explicar con mis palabras las partes que fueron difíciles de comprender.
Básicamente epsilon es un porcentaje de error en este caso el 0.01 que seria el 1% de error que aceptamos para la respuesta, por eso recibimos 1.97 en vez de 2 como raiz cuadrada de 4. Se puede incrementar la precisión de la respuesta disminuyendo el porcentaje de error que como vemos en el video, puede ser de 0.001 lo que quiere decir que solo aceptamos el .1% de error en vez del 1% pero la computadora tardaría mucho mas tiempo en encontrar la respuesta que en este caso seria 1.99 o aproximado.
En la expresion (respuesta2 - objetivo) >= epsilon simplemente estamos haciendo una comparacion entre el porcentaje de error en cada iteracion con el porcentaje de error de epsilon, asignando valores tenemos que:
respuesta = .012 = .0001 - respuesta = 3.9999, por lo tanto 3.999 es mayor a epsilon que vale .01. el error, entonces en la primera iteracion tenemos que el error es de 399%, tenemos que seguir incrementando la respuesta hasta que el error sea mayo o igual que epsilon que es 1%, cuando se cumpla la condicion el ultimo valor iterado sera la respuesta que mas se aproxime a la raiz cuadrada de dos con el error que le asignamos
🖥📌En el momento en que tengan un bucle infinito pueden oprimir ‘ctrl + c’ para terminar el proceso.
Me siento decepcionado de mi pc 😑
from time import time
objetivo = int(input('Escoge un numero: '))
epsilon = 0.01
paso = epsilon**2
respuesta = 0.0
tiempo_inicio = time()
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
print(abs(respuesta**2 - objetivo), respuesta)
respuesta += paso
tiempo_total = time() - tiempo_inicio
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontro la raiz cuadrada del objetivo')
print(f'Tardo {tiempo_total} segundos')
else:
print(f'La raiz cuadrada de {objetivo} es {respuesta}')
print(f'Tardo {tiempo_total} segundos')
from time import time
objetivo = int(input('Escoge un numero: '))
epsilon = 0.0001
paso = epsilon**2
respuesta = 0.0
tiempo_inicio = time()
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
print(abs(respuesta**2 - objetivo), respuesta)
respuesta += paso
tiempo_total = time() - tiempo_inicio
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontro la raiz cuadrada del objetivo')
print(f'Tardo {tiempo_total} segundos')
else:
print(f'La raiz cuadrada de {objetivo} es {respuesta}')
print(f'Tardo {tiempo_total} segundos')
Este último tardó muchísimo, de hecho se me apagó la laptop y no llegué a saber.
Se demoró 3 dias 😢
Aproximación de soluciones
Es similar a la enumarción exhaustiva, pero no necesita una respuesta exacta, por lo tanto podemos aproximar soluciones con un margen de error que llamaremos epsilon.
Como siempre en programación debemos hacer un trade-off, no podemos ser precisos y rápidos a la ves, por lo tanto cuando nuestro epsilon es muy pequeño esto significa que debemos realizar mas iteraciones para llegar a la aproximación, lo cual significa sacrificar tiempo. Y por otro lado si queremos que nuestro tiempo de ejecución sea lo mas corto posible debemos sacrificar la precisión aumentando el valor de epsilon.
objetivo = int(input('Escoge un numero: '))
epsilon = 0.01 # Definimos un margen de error.
paso = epsilon**2 # Los pasos para buscar la raiz sera igual a epsilon^2
respuesta = 0 # Inicializamos una respuesta 0
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
respuesta += paso
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontró la raiz cuadrada de {objetivo}')
else:
print(f'La raiz cuadrada de {objetivo} es {respuesta}')
Puedes intentar ir moviendo la magnitud de epsilon para obtener una mejor precisión o mejorar el tiempo de ejecución.
import matplotlib.pyplot as plt
import numpy as np
pruebas = np.arange(0.001, 0.05, 0.001)
print(pruebas)
iteraciones = []
objetivo = 17
for epsilon in pruebas:
paso = epsilon**2
respuesta = 0.0
iteracion = 0
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
respuesta += paso
iteracion += 1
print(iteracion)
iteraciones.append(iteracion)
plt.plot(pruebas, iteraciones)
plt.ylabel('Número de iteraciones')
plt.xlabellabel('Epsilon')
Notas de la sesión:
objetivo = int(input('Escoge un número: '))
epsilon = 0.01 #Tolerancia para la aproximación
paso = epsilon**2 #Tamaño del avance
respuesta = 0.0
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
respuesta += paso
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontró la raíz cuadrada de {objetivo}')
else:
print(f'La raiz cuadrada de {objetivo} es {respuesta}')
Diagrama de flujo
Hola,
Les comparto las modificaciones que le hice al código para encontrar el numero de iteraciones y el tiempo transcurrido.
import time
objetivo = int(input('Escoge un numero: '))
epsilon = 0.0001
paso = epsilon**2
respuesta = 0.0
num = 0 #numero para contar iteraciones
start = time.time()
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
respuesta += paso
num += 1
end = time.time()
print(f'Para resolver hizo {num} iteraciones y se demoro {end - start} segundos')
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontro la raiz cuadrada de {objetivo}')
else:
print(f'La raiz cuadrada de {objetivo} es {respuesta}')
Para encontrar la raíz cuadrada de 4 y usando un epsilon de 0.01 se obtuvo que para resolver el problema hizo 19975 iteraciones y se demoro 0.02600 segundos obteniendo que la raíz cuadrada de 4 es 1.9974999999997964.
Por otro lado, al usar el epsilon igual a 0.0001 se obtuvo que para resolver hizo 199997501 iteraciones y se demoro 249.87 segundos obteniendo que la raíz cuadrada de 4 es 1.999975006212548.
El resultado es mas preciso, pero al hacer un redondeo se quitan números decimales llegando que a la conclusión que no es necesaria la alta precisión para este calculo.
Una forma más visual de ver esto.
Ejecutando este código me doy cuenta lo pésima que es mi computadora
Hoy me estoy sintiendo frustada; no he podido entender bien el concepto de epsilon, a pesar de que he revisado el algoritmo varias veces. Algún consejo, ayuda o explicación de alguno que si lo haya entendido bien, se agradece un montón.
En el while, lo que sucede es que en la primera iteración, la diferencia abs(respuesta^2- objetivo) va a ser mucho mayor a epsilon, entonces, a medida que pasan las iteraciones, el valor de respuesta va aumentando a razón paso = 0.0001 y por ende la diferencia abs(respuesta^2-objetivo) se va haciendo mas pequeña.
El ciclo while va a terminar justo en el momento en que la diferencia abs(respuesta^2-objetivo) sea apenitas menor que epsilon.
<br>
Hasta este punto ya tenemos un numero el cual al elevarlo al cuadrado se aproxima a objetivo con un ligero error menor a epsilon, y lo que sigue es simplemente confirmarlo mediante un código usando if statement.
“nosotros sabemos que ya tienes la respuesta aproximada” y con el código de if solo haremos que la computadora nos muestre “algo” si nuestra condición principal es verdadera o True.
Dare una explicación para quienes quieran entender todo lo que ocurre dentro del código,
Vamos a hacer el ejemplo con el numero 1, entonces primero definimos las variables:
numero = int(input('Escribe un numero: ')) #Usaremos el numero 1 para este ejemplo
#Con la var epsilon definimos que tan exactos queremos ser
epsilon = 0.1
#Con paso elevamos epsilon al cuadrado
paso = epsilon**2
#Respuesta guardara el resultado
respuesta = 0.0
Luego viene la parte del ciclo que explicare como funciona:
#Con un loop y la funcion abs que nos retorna el valor absoluto
#La primera condicion nos dice que tanto nos estamos acercando al numero
#La segunda condicion nos protege de numeros negativos.
while abs(respuesta**2 - numero) >= epsilon and respuesta <= numero:
print(abs(respuesta**2 - numero), respuesta)
respuesta += paso
la funcion abs() nos retorna el valor absoluto de algo que pongamos dentro de la función, en este caso estamos diciendo que respuesta en el valor inicial vale 0.0, El resultado de (0.0**2 – 1) = -1 pero el abs lo retorna positivo y decimal, ya que estamos trabajando con respuesta que es decimal, por lo tanto tendríamos 1.0.
Y ahora al final del ciclo respuesta toma el valor de 0.01, debido a que paso es igual a: 0.1^2 = 0.01.
En el siguiente ciclo ahora ejecutara lo siguiente con el nuevo valor de respuesta: (0.01**2 – 1.0) = -0.9999 pero el abs() nos retorna el resultado positivo 0.9999.
Y asi se ejecuta el ciclo hasta que se cumpla la condición, como resultado obtendríamos que la raíz de 1 con una exactitud de 0.1 es= 0.9500000000000007
Quizá le sirve a alguien.
Fue aproximadamente 3 minutos
Después de una hora ejecutándose el programa, murió visual studio code.
1. Usando Debian (Gnu/Linux) puedo saber el tiempo que se demora usando este comando ejecutando desde la terminal
$ time (python3.7 codigo.py <<< "10")
2. Raíz cuadrada de 10 : 0.31 segundos
3. Raíz cuadrada de 100: 0.75 segundos
4. Raíz cuadrada de 1000: 2.16 segundos
5. Raíz cuadrada de 10000: 6.60 segundos
Les pongo mi tiempo, además les dejo el código que nos pone el tiempo de inicio y el tiempo al final de la ejecución
Escoger un número: 4
Current Time = 22:21:46
La raíz cuadrada de 4 es 1.999975006212548
End Time = 22:23:00
# -*- coding: utf-8 -*-
from datetime import datetime
def run():
objetivo = int(input('Escoger un número: '))
epsilon = 0.0001
paso = epsilon**2
respuesta = 0.0
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
print("Current Time =", current_time)
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
respuesta += paso
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontró raíz cuadrada de {objetivo}')
else:
print(f'La raíz cuadrada de {objetivo} es {respuesta}')
now = datetime.now()
end_time = now.strftime("%H:%M:%S")
print("End Time =", end_time)
Algoritmo para aproximacion de raiz cuadrada:
#Numero al que se le calculara la raiz cuadrada
objetivo = int(input('Escoge un numero: '))
#Margen de error para encontrar la raiz cuadrada o aproximacion
epsilon = 0.01
#Valor que se ira sumando secuencialmente hasta encontrar la raiz cuadrada
paso = epsilon**2
#Se comenzara a buscar a la raiz cuadrada desde 0.0 en adelante
respuesta = 0.0
#Mientras que la respuesta al cuadrado no sea igual al objetivo (con un margen de error de 0.01 en epsilon), While seguira ejecutandose.
#Respuesta <= objetivo: codigo defensivo; si respuesta es mayor a objetivo, while seguira infinitamente, y nunca encontrara la raiz cuadrada (la raiz cuadrada nunca seria mas grande que el objetivo)
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
#print(abs(respuesta**2 - objetivo), respuesta)
respuesta += paso
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontro la raiz cuadrada {objetivo}')
else:
print(f'La raiz cudrada de {objetivo} es {respuesta}')```
Con la librería datetime puede saber el tiempo de computo y con una variable que vaya contando cada vez que entra al cicilo while saben cuantas iteraciones. Espero sea de ayuda.
#Aproximación
from datetime import datetime
objetivo = int(input('Ingresa un número entero: '))
epsilon = 0.01 #Presicion
paso = epsilon**2 #incremento por iteración
respuesta = 0
ite = 0
instanteInicial = datetime.now()
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
ite += 1
respuesta += paso
print(f'Iteración número {ite}')
instanteFinal = datetime.now()
tiempo = instanteFinal - instanteInicial
segundos = tiempo.seconds
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontró la raiz cuadrada de {objetivo}')
else:
print(f'La raiz cuadrada de {objetivo} es {respuesta} y el tiempo de computo fue {segundos} segundos')
coloque una cifra de 10 digitos , ya se pasaron 2 horas y no para, la pc esta recaliente!!! 😭.
como lo paroooo???
Compañeros,
.
El siguiente recurso online puede ser de mucha utilidad para visualizar como se ejecuta cada línea de una pieza de código. Es como una herramienta para hacer debug pero creando un entorno visual donde se se puede observar por ejemplo a las variables como si fueran cajas y como los valores son metidos en ellas. Esto permite abstraer y coprender mucho mejor el proceso dentro de una pieza de código.
.
Espero les sirva. Saludos.
.
https://pythontutor.com/index.html
.
Objetivo: 4
Epsilon: 0.01 --> Menos del segundo
Epsilon: 0.001 --> 2.09 seg
Epsilon: 0.0001 --> 2 min 3 seg
Epsilon: 0.00001 --> mas de 40 min
Lo modifiqué un poco para que fuera más eficiente con números grandes!
objetivo = int(input('Escoge un número: '))
epsilon = 0.01
paso = epsilon**2
respuesta = 0.0
while respuesta * respuesta < objetivo:
respuesta += 1
respuesta -= 1
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
respuesta += paso
if abs(respuesta ** 2 - objetivo) >= epsilon:
print(f'No se encontró la raiz cuadrada de {objetivo}')
else:
print(f'La raiz cuadrada de {objetivo} es {respuesta}')
Utilizando un epsilon de 0.01 son 19975 iteraciones con un resultado de 1.9974999999997964
Utilizando un epsilon de 0.001 son 1999750 iteraciones con un resultado de 1.9974999999997964
La diferencia en iteraciones es de 1 979 775 para un mismo resultado
Conclusión: Lo ideal es encontrar un equilibrio en los valores para obtener la mayor ganancia
se demoro 6 minutos
Aproximadamente 3 min y 19.975 iteraciones
yo estaba intentando entender como:
import time
objetivo = int(input('escoge un numero: ')) # ejemplo 9
start_time = time.time()
# vamos a encontar la raiz de cualquier numero por aproximacion
epsilon = 0.001 # que tan preciso queremops er
paso = epsilon**2
respuesta = 0.0
contador = 0
# ----- 0.1 - 9 = 8.999 es mayor que 0.1 y menor que 9 ambas son verdaderas por lo que sigue el loop
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
#print(abs(respuesta**2 - objetivo))
respuesta += paso # aqui suma 0.0 + 0.1 = 0.1 y compara en el while
contador += 1
if abs(respuesta**2 - objetivo) >=epsilon:
print('no hay raiz cuadrada del ', objetivo)
else:
print(f'la raiz cuadrada de {objetivo} es {respuesta}')
print("--- %s seconds ---" % (time.time() - start_time))
print(contador)
Mi PC sufrio con esto 🤣
objetivo = 4
epsilon = 0.001
el resultado fue de 199749 iteracionnes en 2:39:27 segundo.
Dios mio jaja, yo esperando que el procesador del profe se muera jaja.
El primer resultado fue con un epsilon de 0.0001 y el siguiente con 0.01
objetivo = int(input('Escoge un numero: '))
epsilon = 0.001
paso = epsilon**2
respuesta = 0.0
i= 0 #iteracion
while abs(respuesta**2 - objetivo) >= epsilon and respuesta<= objetivo:
print(i, ' ', abs(respuesta**2 - objetivo), respuesta)
respuesta += paso
i += 1
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontró la raiz cuadrada de {objetivo}')
else:
print(f'La raiz cuadrada de {objetivo} es {respuesta}')
time (python3.10 aproximacion.py <<< '4')
Es la primera vez que comento, espero les sirva. Comparto mi aporte una vez que comprendí el flujo del código:
while abs(respuesta ** 2 - objetivo) >= epsilon and respuesta <= objetivo:
print(abs(respuesta**2 - objetivo), respuesta)
respuesta += paso
'''
1. La operación "(respuesta**2 - objetivo) da un valor mayor a epsilon y ahí se detiene
2. El valor de respuesta entrega una iteración más
3.El valor de respuesta crece hasta 1.410699999999861
4.Al llevar el valor 1.410699999999861 al (**2 -2) no cumple la primera condicional
5.Resultado: 0.009925510000392102
'''
if abs(respuesta ** 2 - objetivo) >= epsilon:
print('No se encontró la respuesta dle objetivo')
else:
print(f'La raíz cuadrada de {objetivo} es {respuesta}')
Consegui un error en el codigo que puede que alguien mas haya encontrado, pero como son casi 500 comentarios, ni loco reviso a ver, asi que lo comparto.
El error es mandar a parar el while con ‘and respuesta <= objetivo’, esta parte del codigo no hace nada, porque para un objetivo 4 y epsilon 0.01, la respuesta va desde el rango de 0.0001 hasta 1.9974999999997964, siempre va a ser la respuesta menor que el objetivo y por lo tanto esta condicion nunca va a romper el while, esto lo verifique imprimiendo los valores de los resultados, en cambio colocando ‘and respuesta**2 <= objetivo’ y los mismos datos para el calculo, el rango va desde 1e-08 hasta 3.989606759999187, con lo cual de pasarse se romperia el ciclo while, que es lo que queremos.
objetivo = int(input('Da un numero: '))
epsilon= 0.01
paso = epsilon**2
respuesta = 0.0
print(epsilon**2)
while abs(respuesta**2 - objetivo) >= epsilon and respuesta**2 <= objetivo:
print(abs(respuesta**2 - objetivo), respuesta**2)
respuesta += paso
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontro la raiz cuadrada de {objetivo}')
else:
print(f'la raiz cuadrada {objetivo} es {respuesta}')
Hay que buscar el punto en el que el Beneficio Marginal de hacer Trade-Off sea igual a su Costo Marginal.
prueba:
raiz cuadrada de 4
maximo error admitido (epsilon): 0.0001
numero de iteraciones: 199.997.501
resultado: 1.999975006212548
maximo error admitido (epsilon): 0.01
numero de iteraciones: 19.975
resultado: 1.9974999999997964
metodo de la biseccion:
maximo error admitido (epsilon): 0.0001
numero de iteraciones: 1
resultado: 2
raiz cuadrada de 10
maximo error admitido (epsilon): 0.01
numero de iteraciones: 31.607
resultado: 3.1607000000022456
Metodo de la bisección:
maximo error admitido (epsilon): 0.0001
numero de iteraciones: 10
resultado: 3.1622688137755106
Con un epsilon = 0.01
Para resolver hizo 19975 iteraciones y se demoro 10.815094947814941 segundos
La raiz cuadrada de 4 es 1.9974999999997964
Con un epsilon 0.0001 VSC en mi PC fallo
Oucchh
Mi notebook sufrió cuando elegí el número 169 :,v (más de 10 min)
def main():
to_find_num= int(input('Write a number: '))
epsilon=0.01
pass_2=epsilon**2
answer=0.0
while abs(answer**2 - to_find_num) >= epsilon and answer <= to_find_num:
answer += pass_2
if abs(answer**2 - to_find_num) >= epsilon:
print(f'Square root of {to_find_num} does not exists')
else:
print(f'Square root of {to_find_num} is {answer}')
if __name__ == '__main__':
main()
Hice el algoritmo con el método de newton raphson, y se resuelve con muy pocas iteraciones.
objetivo = int(input('Escoge un numero: '))
epsilon = 0.00001
respuesta = 1
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
print(abs(respuesta**2 - objetivo), respuesta)
respuesta =(1/2)*(respuesta+objetivo/respuesta)
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontro la raiz cuadrada {objetivo}')
else:
print(f'La raiz cudrada de {objetivo} es {respuesta}')
Calculé el tiempo de ejecución de la siguiente manera:
from time import time
def raiz():
tiempo_total = 0
objetivo =int(input('Escoge un numero'))
tiempo_inicial = time()
epsilon = 0.01
paso = epsilon**2
respuesta = 0.0
while abs(respuesta**2 - objetivo )>= epsilon and respuesta <= objetivo:
respuesta += paso
if abs(respuesta**2 - objetivo ) >= epsilon:
print(f'No se encontro la raiz cuadrada {objetivo}')
else:
print(f'La Raiz cuadrada de {objetivo} es {respuesta}')
tiempo_final = time()
tiempo_total = tiempo_final -tiempo_inicial
print(f'el tiempo fue de : {tiempo_total}')
raiz()
Buenas por si alguien le interesa estuve modificando un poco el algoritmo y mejoró muchísimo la eficiencia
Pasé de este:
from time import time
objetivo = int(input('Escoge un numero: '))
epsilon = 0.0001
paso = epsilon**2
respuesta = 0.0
tiempo_inicio = time()
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
respuesta += paso
tiempo_total = time() - tiempo_inicio
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontro la raiz cuadrada del objetivo')
print(f'Tardo {tiempo_total} segundos')
else:
print(f'La raiz cuadrada de {objetivo} es {respuesta}')
print(f'Tardo {tiempo_total} segundos')
A este que lo que hice fue hacer una aproximación con epsilon 0.01 y con base a su respuesta lo vuelve a pasar por el bucle pero esta vez con epsilon 0.0001 y pasando a tardar de 191.77 segundos a 0.19 segundos y llegando a la misma respuesta 10.999995457968287:
from time import time
objetivo = int(input('Escoge un numero: '))
epsilon = 0.01
paso = epsilon**2
respuesta = 0.0
tiempo_inicio = time()
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
respuesta += paso
respuesta = respuesta - epsilon
epsilon = 0.0001
paso = epsilon**2
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
respuesta += paso
tiempo_total = time() - tiempo_inicio
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontro la raiz cuadrada del objetivo')
print(f'Tardo {tiempo_total} segundos')
else:
print(f'La raiz cuadrada de {objetivo} es {respuesta}')
print(f'Tardo {tiempo_total} segundos')
tuve que ver 3 veces el video para entenderlo .
y lo consegui, el por que demora si el numero es grande.
Imagina el trayecto de tu casa a la de tu novia, y si no la tienes ni modo nadie te quere jejeje 😃
La variable objetivo es como la distancia de tu casa a la de la novia, entendido…
entonces la variable epsilon en la forma de medir: en Km, mt, pies, cm,mm, etc
Pues asi, mientras mas pequeno la forma de medicion mas exacto el resultado, pero tardaras mucho mas en medir la distancia.
prueva en reducir la variable epsilon, como lo hace el profesor en el minuto 10:30.
Mientras mas pequena sea la presicion mas se demorara el computo.
Una clase de limite =O
y muchos aquí dicen que la universidad no sirve para nada.
Que ventaja entender los conceptos y poder concentrarse en la forma de pensar y como llevar eso a la programacion.
Sigue corriendo pero ya quiero ir a escuchar la otra clase
A trabajar GPU !
Resultados de ejecución variando epsilon:
La raíz cuadrada de 3 es 1.729199999999826
El programa necesito con epsilon = 0.01, 17292 iteraciones
La raíz cuadrada de 3 es 1.7295119999999529
El programa necesito con epsilon = 0.009, 21352 iteraciones
La raíz cuadrada de 3 es 1.7297920000004081
El programa necesito con epsilon = 0.008, 27028 iteraciones
La raíz cuadrada de 3 es 1.730042999999224
El programa necesito con epsilon = 0.007, 35307 iteraciones
La raíz cuadrada de 3 es 1.7303399999988631
El programa necesito con epsilon = 0.006, 48065 iteraciones
La raíz cuadrada de 3 es 1.7306249999993013
El programa necesito con epsilon = 0.005, 69225 iteraciones
La raíz cuadrada de 3 es 1.7308960000014004
El programa necesito con epsilon = 0.004, 108181 iteraciones
La raíz cuadrada de 3 es 1.7311859999955839
El programa necesito con epsilon = 0.003, 192354 iteraciones
La raíz cuadrada de 3 es 1.7314759999813463
El programa necesito con epsilon = 0.002, 432869 iteraciones
La raíz cuadrada de 3 es 1.7317629999477184
El programa necesito con epsilon = 0.001, 1731763 iteraciones
Por si alguien quiere ver la tendencia:
My PC decided to stop my nonsense calculations…🤨
Lo deje en google colab lo detuve a las dos horas porque ya me dio sueño… 😃
La palabra griega épsilon corresponde a la letra e latina. En este caso, usamos la palabra e para indicar error.
La verdad haciendo estos ejercicios me sentí atascado, pero poco a poco ahí vamos; éxito para todos…
PD: Se tardó como 4.4 minutos
Un algoritmo de aproximación es el Método de Gauss-Seidel para resolver sistemas de ecuaciones lineales.
https://es.wikipedia.org/wiki/Método_de_Gauss-Seidel
Les comparto un truco para saber cuantos segundos se tarda en ejecutar la operación!
Importen el modulo time y utilicen la funcion time.time()
Esa función te regresa la cantidad de segundos que han pasado desde 1970 hasta el momento en que la llamas. Se puede jugar con eso y llamar esa funcion al principio del bucle y otra vez al final y hacer una simple resta. Vean:
Miren los segundos que se tardó con diferentes valores de epsilon:
Esto te puede ayudar a entender mejor el algoritmo!
El epsilon es un porcentaje, no una decima y este representa el porcentaje de error que estas dispuesto a tolerar; es como si dijeras “Me da igual si la diferencia es del 1%, pa’ mi es lo mismo”.
Con eso en mente tienes que saber que este algoritmo es uno de numeración exhaustiva como el anterior, tenemos que ir buscando dando ‘pasos’ entre diferentes números para encontrar una raíz aproximada.
Ahora, tienes que tener cuidado cuando fijas un valor para epsilon (margen de error):
1 = 100%
0.1 = 10%
0.01 = 1%
Así se representan los porcentajes en estadistíca.
Ahora traduce las condiciones del bucle while de la siguiente manera:
“Si el margen de error es mayor al 1% y si la raiz aproximada es menor que que el número que ingresé (aquí habría que revisar la segunda condición pues si existen raices mayores que el objetivo, √0.25 = 0.5 ) sigue trabajando”
¿Por qué respuesta ** 2?
Recuerda que son peras con peras y manzanas con manzanas.
La variable respuesta representa una raiz cuadrada y objetivo no, los tienes que poner en una equivalencia para poder trabajar, ya sea (respuesta^2 y objetivo) ó (respuesta y √objetivo).
Al final los condicionales son 2:
“Si el porcentaje de error es mayor al que el usuario puede tolerar, mejor dile que aquí no hay nada”
“Si hay un raíz dentro del porcentaje de error aceptado, imprimelo”
Tener en cuenta que en muchas iteraciones, se necesitaría un buen procesador!
Tiempo en segundos
Mi pc ahun esta buscando una respuesta a 4 jajaja
Cuhete
Se me cerro el virtual studio code cuando intente mayor precisión hahahahaa
akrand@DESKTOP-9DQ7FD8:~/PythonTest$ python3.8 enumeracion.py
Escoge tu número: 4
La raíz cuadrada de 4 es 1.999749999925672
Tiempo de ciclo 0:00:00.715850
akrand@DESKTOP-9DQ7FD8:~/PythonTest$ python3.8 enumeracion.py
Escoge tu número: 4
La raíz cuadrada de 4 es 1.999975006212548
Tiempo de ciclo 0:01:13.542386
Tiempo considerando epsilon como 0.001 y luego 0.0001
con epsilon = 0.001 tardo 9minutos
Todo estuvo muy bien, pero los ultimos 45 segundos fue de lo mejor. Creo que necesitare una nueva computadora.
El profe acomplejo mas de lo que deberia el algorithmo
Este tiene un mejor performance y es mas exacto
val = abs(int(input('numero: ')))
ep = 0.01
out = 0.0
while out ** 2 <= val:
out += ep
print(f"La raiz aproximada de {val} es: {out}")
Hubiese utilizado Python en mis examenes de matematicas. xd
Cada vez que se disminuye la incertidumbre en 10, el número de iteraciones aumenta en 100
Epsilon = 0.1, 198 iteraciones
resultado = 1.9800000000000015
Epsilon = 0.01, 19975 iteraciones,
resultado = 1.9974999999997964
Epsilon = 0.001, 1999750 iteraciones,
resultado = 1.999749999925672
Primero probé con epsilon = 0.001 y tomó 6:19 minutos y con epsilon 0.01 5:68 min, con esto comprobé que el nivel de pelea de mi laptop no es tan elevado
limites!
Tuve que quitar la impresión de cada iteración para disminuir el tiempo …
objetivo = 2
epsilon. 0.001
tiempo = 3 minutos…
no me atrevo a mover nada mas jjajajaja
alguien me puede explicar la matemática atrás y el funcionamiento del código detalladamente
Hice el experimento con 3 Editores, epsilon = 0.0001 y comparé los resultados imprimiendo variables y sin imprimir, este fue el resultado:
VISUAL STUDIO CODE:
-Sin imprimir…
La raiz cudrada de 4 es 1.999975006212548
El tiempo total fue de 206 Seg
#PYCHARM:
-Sin imprimir…
La raiz cudrada de 4 es 1.999975006212548
El tiempo total fue de 94 Seg
-Imprimiendo…
La raiz cudrada de 4 es 1.999975006212548
El tiempo total fue de 5870 Seg
COLAB DE GOOGLE:
-Sin imprimir…
La raiz cudrada de 4 es 1.999975006212548
El tiempo total fue de: 35.93122482299805
se tardo tres horas con epsilon 0.0000000001
Mayor precisión de la respuesta (epsilon más pequeño) es mayor el tiempo de espera. Para un epsilon de 0.01 y con objetivo=13 el programa se ejecutó en 1.41 min. para un epsilon de 0.001, con el mismo objetivo el tiempo fue demasiado, tuve que cortarlo en el tiempo 5 min 😃
9950 iteraciones fueron suficientes para encontrar la raíz de uno, con un margen de error de 0.01(epsilon). Debería subir mi autoestima si mi cerebro solo necesitó una iteración?😃
El tiempo necesario para el cálculo fue 2 minutos y 20 segundos. Sin duda necesito otro ordenador. 😃
objetivo = int (input('Escribe un número'))
epsilon = 0.01
paso = epsilon**2 #que tanto vamos acercarnos en la iteración
iteraciones = 1
respuesta = 0.0
while abs(respuesta**2 -objetivo)>=epsilon and respuesta <=objetivo:
print(iteraciones, abs(respuesta**2 -objetivo), respuesta)
respuesta += paso
iteraciones +=1
if abs(respuesta**2-objetivo)>=epsilon:
print (f'No existe la raíz cuadrada de {objetivo}')
else:
print(f'La raíz cuadrada de {objetivo} es {respuesta}, con un 0.01 de margen de error')
Estoy en la ultima clase del curso y mi maquina todavia esta corriendo con epsilon = 0.0001 y objetivo 4
Este es el codigo que implemente para medir la cantidad de iteraciones y el tiempo de ejecucion:
import time
objetivo = int(input('Escoge un numero: '))
epsilon = 0.0001
paso = epsilon**2
respuesta = 0.0
tiempo = time.time()
contador = 0
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
respuesta += paso
contador += 1
if(abs(respuesta**2 - objetivo) >= epsilon):
print(f'NO se encontro la raiz de {objetivo}')
print(f'El tiempo fue: {time.time() - tiempo}')
print(f'Iteraciones: {contador}')
else:
print(f'La raiz de {objetivo} es {respuesta}')
print(f'El tiempo fue: {time.time() - tiempo} segundos')
print(f'Iteraciones: {contador}')
Para un epsilon de 0.0001 el resultado fue:
Escoge un numero: 4
La raiz de 4 es 1.999975006212548
El tiempo fue: 198.66644668579102 segundos
Iteraciones: 199997501
Hola la verdad este calculo toma mucho tiempo cuando pones 0.0001, yo solo espere 3 minutos y recien iba 3.9999646646, por lo menos tomara de 15 a 20 minutos.
Algo curioso, (al buscar la raiz de 10)
precision: 0.01 = 31607 iteraciones
precision: 0.001 = 3162120 iteraciones
precision: 0.0001 = 316226186 iteraciones
Escoge un numero: 4
La raiz cuadrada de 4 es 1.9974999999997964
Epsilon: 0.01
Iteraciones: 19975
Inicio: 2020-06-10 13:02:54.455827
Fin: 2020-06-10 13:02:54.473089
Escoge un numero: 4
La raiz cuadrada de 4 es 1.999975006212548
Epsilon: 0.0001
Iteraciones: 199997501
Inicio: 2020-06-10 13:04:03.042159
Fin: 2020-06-10 13:05:05.541428
Codigo de clase completo
Después de varias pruebas, la conclusión es que definitivamente a mayor precisión, menor velocidad(Como lo menciona David), en matemáticas la precisión es bastante util y absolutamente necesaria, sin embargo en ciencia de datos tiende a ser más util la velocidad.
Se tardo 50 minutos con 34 segundo según el cronometro.
Se tardó 40 minutos con 14 segundos. 😮
from datetime import date
from datetime import datetime
objetivo = int(input('escoge un numero: '))
epsilon = 0.01
paso = epsilon**2
respuesta = 0.0
now = datetime.now()
while abs(respuesta**2 - objetivo) >= epsilon and respuesta <= objetivo:
print(abs(respuesta**2 - objetivo), respuesta)
respuesta += paso
after = datetime.now()
print(after - now)
if abs(respuesta**2 - objetivo) >= epsilon:
print(f'No se encontro la raiz cuadrada de {objetivo}')
else:
print(f'La raiz cuadrada de {objetivo} es {respuesta}')
Hice pruebas con el programa, y agregué código para que me registrara el tiempo de ejecución en segundos.
➜ DevEd git:(master) ✗ /usr/bin/python3.7 "/mnt/c/Desarrollo/DevEd/Python/Introduccion Pensamiento Computacional/aproximacion.py"
Ingrese un numero: 50
La raiz cuadrada de 50 es 7.0703999999968605
Epsilon es 0.01
Tiempo de ejecucion en segundos fue 0.027286529541015625
➜ DevEd git:(master) ✗ /usr/bin/python3.7 "/mnt/c/Desarrollo/DevEd/Python/Introduccion Pensamiento Computacional/aproximacion.py"
Ingrese un numero: 50
La raiz cuadrada de 50 es 7.070998000634465
Epsilon es 0.001
Tiempo de ejecucion en segundos fue 1.8994719982147217
➜ DevEd git:(master) ✗ /usr/bin/python3.7 "/mnt/c/Desarrollo/DevEd/Python/Introduccion Pensamiento Computacional/aproximacion.py"
Ingrese un numero: 50
La raiz cuadrada de 50 es 7.071060745393172
Epsilon es 0.0001
Tiempo de ejecucion en segundos fue 271.2884180545807
Conforme se hace más reducido el epsilon, el tiempo de ejecución se incrementa drásticamente.
Después de hora y 15 minutos… sospecho que al estar usando VSC para la siguiente clase y teniendo el navegador abierto con varias pestañas, tuvo que ver.
Creo que habría terminado de ejecutarse en unas dos horas, tengo un i5 con 8GB de RAM, con GPU de 2GB dedicado (no compartido), lo menciono por si alguien más se atreve a intentarlo, tenga estos datos de referencia.
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?