Calificación:
  • 1 voto(s) - 5 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Calcular PI con Sucesión Nilakantha
#1
Buenas!


Ando medio perdido...

Basandome en pi = 3 + 4/(2*3*4) - 4/(4*5*6) + 4/(6*7*8) - 4/(8*9*10) + 4/(10*11*12) ... etc

Ando queriendo crear lo siguiente (es una matriz?):

calculo=[[2, 3, 4], [4, 5, 6], [6, 7, 8]]

Con lo siguiente:
Código:
nilakantha=[2,3,4]
print("Inicial:",nilakantha)
print()

pi=3+4/(nilakantha[0]*nilakantha[1]*nilakantha[2])

iterar=input("Iterar?:")
print()

calculo=[]
i=1
while i<=int(iterar):
    nilakantha.append(nilakantha[-1]+1)
    del nilakantha[0]
    nilakantha.append(nilakantha[-1]+1)
    del nilakantha[0]
    print("Paso:",i, nilakantha)
    calculo.append(nilakantha)
    i+=1

print()
print(calculo)

Pero...

Pero me queda asi:
calculo=[[8, 9, 10], [8, 9, 10], [8, 9, 10]]

Alguna idea?

Saludos y gracias!!!
Responder
#2
Hola. Transcribo lo que te respondí en el mail para que sirva a otros usuarios:

Cita:Cuando en la penúltima línea de tu bucle hacés esto...

  1. calculo.append(nilakantha)


...el lenguaje está pasando como argumento a la función append() una referencia de la lista nilakantha, no una copia. Como en cada ejecución del bucle vos trabajás sobre la misma lista, eliminando los primeros dos elementos y agregando dos nuevos, esos cambios se reflejan en las listas que ya agregaste a calculo en iteraciones anteriores.

Ya que en Python no podemos decidir si un objeto se pasa por referencia o por valor, sino que todos los objetos se pasan indistintamente por referencia (no obstante, este problema no lo tendrías con los cuatro tipos de dato básicos ni con las tuplas porque son todos inmutables), la solución más sencilla es, en esa misma línea, usar la propiedad de slicing omitiendo los valores de inicio y fin para que retorne una copia exacta (pero no una referencia) de la lista que querés agregar.

  1. calculo.append(nilakantha[:])


Recordá que esto es lo mismo que:

  1. calculo.append(nilakantha[0:len(nilakantha)])


Te dejo un artículo sobre estas cuestiones relativas a las variables en Python y cómo se diferencian de otros lenguajes: https://recursospython.com/guias-y-manua...lenguajes/.

Y la sección sobre slicing en el tutorial: https://tutorial.recursospython.com/mas-...lecciones/.

Saludos!
Responder
#3
Esta "previa" de codigo anda genial, incluso le tiro 1.000.000 de iteraciones y va muy bien!
Gracias!!!
Responder
#4
Bueno, ahí quedó...

Código:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Calculemos PI
# Sucesión Nilakantha:
# pi = 3 + 4/(2*3*4) - 4/(4*5*6) + 4/(6*7*8) - 4/(8*9*10) + 4/(10*11*12) ... etc

nilakantha = [2,3,4]
print("Inicial:",nilakantha)
print()

pi = 0
# pi = 3 + 4/(nilakantha[0]*nilakantha[1]*nilakantha[2])

print(pi)
iterar = input("Iterar?:")
print()

calculo = [[2,3,4]]
i = 1
while i <= int(iterar):
    nilakantha.append(nilakantha[-1]+1)
    del nilakantha[0]
    nilakantha.append(nilakantha[-1]+1)
    del nilakantha[0]
    print("Paso:",i, nilakantha)
    calculo.append(nilakantha[:])
    i += 1

print()
print(calculo)
print()

total = len(calculo)
pos = 0

pi = 3 + 4/(calculo[pos][0]*calculo[pos][1]*calculo[pos][2])
print("pi = 3 + 4/( 2 * 3 * 4 )")
print("Inicio",pi)

pos += 1

while pos < total:
            
    if pos % 2 == 0:
        pi = pi + 4/(calculo[pos][0]*calculo[pos][1]*calculo[pos][2])
        print("Suma",pos)
        print("pi =",pi," + 4/(",calculo[pos][0],"*",calculo[pos][1],"*",calculo[pos][2],")")
    else:
        pi = pi - 4/(calculo[pos][0]*calculo[pos][1]*calculo[pos][2])
        print("Resta",pos)
        print("pi =",pi," - 4/(",calculo[pos][0],"*",calculo[pos][1],"*",calculo[pos][2],")")
    pos += 1
    
print(pi)

Mi duda es ahora si matemáticamente es correcto hacer este tipo de operación...

Cuac!
Responder
#5
¡Muy bueno! El método que usaste es uno de los tantos posibles para hacer aproximaciones de Pi, así que matemáticamente es correcto.

Saludos
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)