Skip to content
Advertisement

List index out range while ready xyz file

This is the file that i am trying to read (it is a longer list with more bodies):

Sun 332946.0 0.0 0.0 0.0 0.0 0.0 0.0

Mercury 0.055 0.3598570518147997 -0.06132511797541504 -0.03811110768962459 -0.000716045178241433 0.02901045859848441 0.002432467783842063

Venus 0.815 -0.3935053177409041 -0.6082860993904631 0.01457222641991683 0.01684066443595474 -0.01108032188877406 -0.001122023332246253

It is supposed to be read as a label,mass, array of position, array of velocity. This done by:

def new_particle(input_handle):
    """
    Initialises a Particle3D instance given an input file handle. This
    function reads in a line in the file and spilts it into list items
    where each is labels and initialised using the '__init__' method.
    
    The input file should contain one line per particle in the following format:
    <label>   <mass>  <pos> <y> <z>    <vx> <vy> <vz>
    
    :param inputFile: Readable file handle in the above format

    :return Particle3D instance
    """   
    
    lines = input_handle.readline() 
    
    tokens = lines.split(" ") 
    label = str(tokens[0])
    mass = float(tokens[1]) 
    pos = np.array(tokens[2:5],float)
    vel = np.array(tokens[5:8],float)
            
    return Particle3D(label, mass, pos, vel)

and to read this file I have used this loop:

particle_list = [] 
with open(input("Enter file name: ")) as f:
    # Reading the opened file that contains initial conditions
    n = len(f.readlines()) 
    for i in range(n):
       particle_list.append(p3d.new_particle(f))  

but i keep getting the error that the mass is list index out of range

Advertisement

Answer

You are consuming the file at this step

n = len(f.readlines())

f.readlines() will move the pointer to EOF, so the next calls to f.readlines() will be empty.

So, when you call again lines = input_handle.readlines() it will be empty, same goes for tokens = lines.split(" ") and that’s why accessing it will give you index out of range.

Try to iterate over the lines with this

particle_list = [] 
with open(input("Enter file name: ")) as f:
    lines = f.readlines()
    for line in lines:
       particle_list.append(p3d.new_particle(line))

and change the method to take a line as input like this

def new_particle(line):
    """
    Initialises a Particle3D instance given an input file handle. This
    function reads in a line in the file and spilts it into list items
    where each is labels and initialised using the '__init__' method.
    
    The input file should contain one line per particle in the following format:
    <label>   <mass>  <pos> <y> <z>    <vx> <vy> <vz>
    
    :param inputFile: Readable file handle in the above format

    :return Particle3D instance
    """
    
    tokens = line.split(" ") 
    label = str(tokens[0])
    mass = float(tokens[1]) 
    pos = np.array(tokens[2:5],float)
    vel = np.array(tokens[5:8],float)
            
    return Particle3D(label, mass, pos, vel)

Now each line is passed to the method and then split by space and your tokens array should have values in it.

Advertisement