-1
Traceback (most recent call last):
  File "N:\Starry\Planetary Orbits Ver 8.py", line 121
    UpdateDisplay(pos) # Updates the 3D displays position of Masses
  File "N:\Starry\Planetary Orbits Ver 8.py", line 100, in UpdateDisplay
    Stars[i].pos = pos[i]
IndexError: list index out of range

I've been getting this error and I can't find out why, I've checked to see that the Numpy Arrays and Lists have values in them, as shown below in the Python Shell:

Number of stars: 2
Please enter The x position of the Star: 0
Please enter The y position of the Star: 0
Please enter The z position of the Star: 0
Please enter the Radius of the Star: 10
Please enter the Mass of the Star: 5000000
Please enter the X speed of Star: 0
Please enter the Y speed of Star: 0
Please enter the Z speed of Star: 0
Please enter The x position of the Star: 100
Please enter The y position of the Star: 0
Please enter The z position of the Star: 0
Please enter the Radius of the Star: 10
Please enter the Mass of the Star: 5000000
Please enter the X speed of Star: 0
Please enter the Y speed of Star: 0
Please enter the Z speed of Star: 0
[(0, 0, 0), (100, 0, 0)]  # Printed PositionList #
[(0, 0, 0), (0, 0, 0)]    # Printed MomentumList #
[5000000, 5000000]        # Printed MassList #
[10, 10]                  # Printed RadiusList #
[[  0   0   0]            # Printed Pos Array#
 [100   0   0]]  
[[0 0 0]                  # Printed Momentum Array #
 [0 0 0]]
[[5000000]                # Printed Masses Array #
 [5000000]]
[10 10]                   # Printed Radii Array #

These values show items are going into the lists and arrays, so surely this code would select an item inside the array?

for i in range(Nstars):
    UpdateDisplay(pos) 

Here is the full program for reference:

Nstars = int(input("Number of stars: "))  # change this to have more or fewer stars  
G = 6.7e-11 # Universal gravitational constant

# Typical values
Msun = 2E30
Rsun = 2E9
vsun = 0.8*sqrt(G*Msun/Rsun)
dt = 10.0   #Reprensents the change in time
Nsteps = 0
time = clock()
Nhits = 0

#~~~~~~~~~~~~~~~~~~~~~~~~~~~ Global Data ~~~~~~~~~~~~~~~~~~~~~~~~~~~#

Stars = []
colors = [color.red, color.green, color.blue,
          color.yellow, color.cyan, color.magenta]
PositionList = []
MomentumList = []
MassList = []
RadiusList = []
pos = None
Radii = None
Masses = None
F = None
Momentum = None

#~~~~~~~~~~~~~~~~~~~~~~~~~~~ Global Data ~~~~~~~~~~~~~~~~~~~~~~~~~~~#

def Calculations(SpeedX, SpeedY, SpeedZ, x, y, z, Mass, Radius):
    px = Mass*(SpeedX)
    py = Mass*(SpeedY)
    pz = Mass*(SpeedZ)
    PositionList.append((x,y,z))
    MomentumList.append((px,py,pz))
    MassList.append(Mass)
    RadiusList.append(Radius)

def StarCreation(Stars,x,y,z,Radius):
    Stars = Stars+[sphere(pos=(x,y,z), radius=Radius, color=colors[i % 6],
                   make_trail=True, interval=10)]


def DataCollection():
    x = input("Please enter The x position of the Star: ")
    y = input("Please enter The y position of the Star: ")
    z = input("Please enter The z position of the Star: ")
    Radius = input("Please enter the Radius of the Star: ")
    StarCreation(Stars,x,y,z,Radius)
    Mass = input("Please enter the Mass of the Star: ")
    SpeedX = input("Please enter the X speed of Star: ")
    SpeedY = input("Please enter the Y speed of Star: ")
    SpeedZ = input("Please enter the Z speed of Star: ")
    Calculations(SpeedX, SpeedY, SpeedZ, x, y, z, Mass, Radius)

def Momenta(Momentum, Masses):
    vcm = sum(Momentum)/sum(Masses) # velocity of center of mass
    Momentum = Momentum-Masses*vcm # make total initial momentum equal zero

def ListToArray(PositionList, MomentumList, MassList, RadiusList):
    global pos
    pos = array(PositionList)
    global Momentum
    Momentum = array(MomentumList)
    global Masses
    Masses = array(MassList)
    Masses.shape = (Nstars,1) # Numeric Python: (1 by Nstars) vs. (Nstars by 1)
    global Radii
    Radii = array(RadiusList)
    Momenta(Momentum, Masses)

def Forces(pos, Radii, Masses):
    # Compute all forces on all stars
    r = pos-pos[:,newaxis] # all pairs of star-to-star vectors (Where r is the Relative Position Vector
    for n in range(Nstars):
        r[n,n] = 1e6  # otherwise the self-forces are infinite
    rmag = sqrt(sum(square(r),-1)) # star-to-star scalar distances
    hit = less_equal(rmag,Radii+Radii[:,newaxis])-identity(Nstars)
    hitlist = sort(nonzero(hit.flat)[0]).tolist() # 1,2 encoded as 1*Nstars+2
    global F
    F = G*Masses*Masses[:,newaxis]*r/rmag[:,:,newaxis]**3 # all force pairs

def SelfForces(F):
    F[n,n] = 0

def UpdateMomentaPositions(Momentum, pos, Masses):
    Momentum = Momentum+sum(F,1)*dt         
    pos = pos+(Momentum/Masses)*dt

def UpdateDisplay(pos):
    Stars[i].pos = pos[i]


#~~~~~~~~~~~~~~~~~~~~~~~~~ Actual Proagram ~~~~~~~~~~~~~~~~~~~~~~~~~#

for i in range(Nstars):
    DataCollection()

ListToArray(PositionList, MomentumList, MassList, RadiusList)
print (PositionList)
print (MomentumList)
print (MassList)
print (RadiusList)
print (pos)
print (Momentum)
print (Masses)
print (Radii)

while True:

    rate(100) # No more than 100 loops per second on fast computers
    Forces(pos, Radii, Masses)# Computes all the forces between masses

    for n in range(Nstars):
        SelfForces(F) # No self forces

    UpdateMomentaPositions(Momentum, pos, Masses) # Updates the Momentum and Positions of Stars

    for i in range(Nstars):
        UpdateDisplay(pos) # Updates the 3D displays position of Masses
P. Camilleri
  • 12,664
  • 7
  • 41
  • 76

1 Answers1

2

Your issue is that you never actually add any stars to Stars when you call StarCreation function. You actually only reassign a local Stars list that shadows the global Stars with that line :

Stars = Stars+[sphere(pos=(x,y,z), radius=Radius, color=colors[i % 6],
               make_trail=True, interval=10)]

You have two solutions to that issue :

  1. You can modify global Stars list inplace via either Stars+=[sphere(...)] or Stars.append(sphere(...))
  2. Or tell python that Stars is a global variable and that it shouldn't be shadowed, like this :

.

def StarCreation(Stars,x,y,z,Radius):
    global Stars
    Stars = Stars+[sphere(pos=(x,y,z), radius=Radius, color=colors[i % 6],
               make_trail=True, interval=10)]

Edit : the mistake I assumed didn't exist , sorry.

jadsq
  • 3,033
  • 3
  • 20
  • 32
  • Thanks anyway, i think the problem was that i didnt call i in the function so it should be like. for i in range(Nstars): UpdateDisplay(pos, i) – Benjamin Anderson Nov 10 '16 at 16:25
  • @BenjaminAnderson That's wasn't an issue (I mean your correction is far better but the original code wasn't a problem for python) and it could not have caused the error you mentioned. Trying to use a variable that is not defined will raise a `NameError` not an `IndexError`. – jadsq Nov 10 '16 at 16:55