alli
alli

Reputation: 105

Loop inside of a loop concurrency

I have a program that calls info from a txt file. Each line in the text file corresponds to an entire file in a different directory. I want to read info from the txt file (line 1) and write it in an output file with info from corresponding file in directory (file 1). I need my code to work for multiple files. How can I get each loop to correspond with each other to produce the correct output?

import datetime
import glob

f = open('\\_spec_final.t15', 'w')
infofile = open('info.txt', 'rt')
num_lines = sum(1 for line in 'info.txt')
count = 0
while count <= num_lines
    for line in infofile: 
        lat = float(line[88:94]) 
        lon = float(line[119:127])
        year = int(line[190:194])
        month = int(line[195:197])
        day = int(line[198:200])
        hour = int(line[201:203])
        minute = int(line[204:206])
        second = int(line[207:209])
        dur = float(line[302:315])
        numpoints = float(line[655:660])
        fov = line[481:497] # field of view?
        sza = float(line[418:426])
        snr = 0.0000 
        roe = 6396.2 
        res = 0.5000
        lowwav = float(lowwav)
        highwav = float(highwav)
        spacebw = (highwav - lowwav)/ numpoints

        d = datetime.datetime(year, month, day, hour, minute, second)
        f.write('{:>12.5f}{:>12.5f}{:>12.5f}{:>12.5f}{:>8.1f}'.format(sza,roe,lat,lon,snr)) # line 1
        f.write("\n")
        f.write('{:>10d}{:>5d}{:>5d}{:>5d}{:>5d}{:>5d}'.format(year,month,day,hour,minute,second)) # line 2
        f.write("\n")
        f.write( ('{:%Y/%m/%d %H:%M:%S}'.format(d)) + "UT Solar Azimuth:" + ('{:>6.3f}'.format(sza)) + " Resolution:" + ('{:>6.4f}'.format(res)) + " Duration:" + ('{:>6.2f}'.format(dur))) # line 3
        f.write("\n")
        f.write('{:>21.13f}{:>26.13f}{:>24.17e}{:>12f}'.format(lowwav,highwav,spacebw,numpoints)) # line 4
        f.write("\n")

        path = '/Users/140803/*' 
        files = glob.glob(path)
        for file(count) in files:
            g = open(file, 'r')
            #do stuff
            g.close()

f.close()
infofile.close()

Upvotes: 2

Views: 64

Answers (2)

Mad Physicist
Mad Physicist

Reputation: 114478

Based on the conversation, it appears that you do not need to have an inner loop at all. You have multiple nested loops that do not need to exist. I have rewritten portions of your code without them here.

Specifically, if you want to iterate over something and count it at the same time, do not do something like

for count in range(3):
    for item in iterator:
        print("%d %s" % (count, item))

The output of those loops will be something like

0 item1
0 item2
0 item3
1 item1
1 item2
1 item3
2 item1
2 item2
2 item3

What you do want is the enumerate function, which runs a counter along side your iterator:

for count, item in enumerate(iterator):
    print("%d %s" % (count, item))

This will print

0 item1
1 item2
2 item3

Also, I replaced all open() ... close() constructs with with ...:

import datetime
import glob

path = '/Users/140803/*' 
files = glob.glob(path)

with open('\\_spec_final.t15', 'w') as f:
    with open('info.txt', 'rt') as infofile:
        for count, line in enumerate(infofile): 
            lat = float(line[88:94]) 
            lon = float(line[119:127])
            year = int(line[190:194])
            month = int(line[195:197])
            day = int(line[198:200])
            hour = int(line[201:203])
            minute = int(line[204:206])
            second = int(line[207:209])
            dur = float(line[302:315])
            numpoints = float(line[655:660])
            fov = line[481:497] # field of view?
            sza = float(line[418:426])
            snr = 0.0000 
            roe = 6396.2 
            res = 0.5000
            lowwav = float(lowwav)
            highwav = float(highwav)
            spacebw = (highwav - lowwav)/ numpoints

            d = datetime.datetime(year, month, day, hour, minute, second)
            f.write('{:>12.5f}{:>12.5f}{:>12.5f}{:>12.5f}{:>8.1f}'.format(sza,roe,lat,lon,snr)) # line 1
            f.write("\n")
            f.write('{:>10d}{:>5d}{:>5d}{:>5d}{:>5d}{:>5d}'.format(year,month,day,hour,minute,second)) # line 2
            f.write("\n")
            f.write( ('{:%Y/%m/%d %H:%M:%S}'.format(d)) + "UT Solar Azimuth:" + ('{:>6.3f}'.format(sza)) + " Resolution:" + ('{:>6.4f}'.format(res)) + " Duration:" + ('{:>6.2f}'.format(dur))) # line 3
            f.write("\n")
            f.write('{:>21.13f}{:>26.13f}{:>24.17e}{:>12f}'.format(lowwav,highwav,spacebw,numpoints)) # line 4
            f.write("\n")

            with open(files[count], 'r') as g:
                #do stuff (to g presumably)

While using a counter on files may actually be what you want, I find this highly unlikely. I think that you are actually trying to generate a file name based on the info you just loaded and to open that. The problem with globbing is that it is not even guaranteed to return the results it the same order between two different runs of the same program.

Upvotes: 2

nbryans
nbryans

Reputation: 1517

After running files = glob.glob(path), files contains a list of filename strings. When you run for file in files:, the variable file will contain a string filename. Thus, you can modify the loop as follows:

for file in files:
    with open(file) as g: #<--- file is the filename
        #do stuff

There is no need to use a counter since the loop already goes through each file in filename.

Upvotes: 0

Related Questions