1. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Jan 2013
Posts
25
Rep Power
0

Parsing the previous line

I have some output data that looks like this:
Code:
1tally 276        nps =*********
+                                    tally energy deposition averaged over a cell 54-61 heart
tally type 6    track length estimate of heating.
particle(s): photon

this tally is all multiplied by  1.60200E-10
cell  a is (54 55 56 57 58 59 60 61)

masses
cell:        a
7.68768E+02

cell (54 55 56 57 58 59 60 61)
1.13944E-19 0.0561
1analysis of the results in the tally fluctuation chart bin (tfc) for tally 276 with nps =1000000000    print table 160
I have a program written that finds the second to last line in this section and puts it into a table for me. Currently the program searches for the line:

Code:
1tally 276        nps =*********
And then it knows 12 lines after this is where the data is that I want. The problem is that sometimes it is 13 or 14 lines after that section. The only way to consistantly find it it is that it is always above the line that reads:

Code:
1analysis of the results in the tally fluctuation chart bin (tfc) for tally 276 with nps =1000000000    print table 160
I can tell the program to find that line but I cannot figure out how to tell python to read the line above rather than below and put that into the table. Here is what my code looks like.

Code:
def reports(output):
with open(output) as f:
count = 1                  #this defines the number of tallies in the output file
x = 6                    #this is the first tally number
r = str('1tally   %d        nps =*********' % x) #r is a variable used to help find the point where the results start.
c = 0 #intilizes the c variable used in the while loop
#The following while loop skips each line until it comes across the line defined in r
#import numpy as np
#import matplotlib.pyplot as plt
Dose = []
SEM = []

while count < 31:
while c != r:
c = line.strip()
line = f.readline() #Reads lines until it gets to dose and SEM seciton

numbers = line.strip().split()
Dose.append(numbers[0])
SEM.append(numbers[1])
count += 1
x += 10
if x < 100:
r = str('1tally  %d        nps =*********' %x)
elif x > 100:
r = str('1tally %d        nps =*********' %x)

table = open('Report.txt', 'w')
table.write('================================================================ \n')
table.write('MCNPX Simulation For XXXXX                                       \n')
table.write('================================================================ \n')
table.write('================================================================ \n')
table.write('Dose (grey)          SEM             \n')
table.write('================================================================ \n')
for (D,S) in zip(Dose,SEM,):
table.write(str(D).ljust(8) + '     ' +
str(S) + '\n')
print('Report created')
table.close()
2. Code:
# the previous value
last = None
for i in range(4):
print('current: {},      previous: {}'.format(i,last))
last = i

# several previous values
import string

ring = [None]*4
n = 0

for i in string.ascii_lowercase:
print('current: {},     3 values ago: {}'.format(i, ring[((n - 3) + len(ring)) % len(ring)]))
ring[n % len(ring)] = i
n += 1

# read the whole dang file
with open('simulation.result') as inf:

for (i, line,) in enumerate(lines):
if 'analysis of the results in the tally fluctuation chart bin (tfc) for tally' in line:
print(lines[i-1].strip())
May the gammas be at your back.
3. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Jan 2013
Posts
25
Rep Power
0
Many thanks. I made a couple of modifications. In the line I am looking for the number starts at 6 and increases by 10 to a certain number. So I added a variable in so that it will change. I also tried to add a couple of variables so that it writes the data to an array which I can later output to a table if necessary. The code runs without any errors but it also does not give the output that I want (it gives nothing) as far as I can tell. Here is what the code looks like:

Code:
with open('1billion.txt') as inf:
x = 6 #first tally number
Dose = []
SEM = []
for (i, line,) in enumerate(lines):
if '1analysis of the results in the tally fluctuation chart bin (tfc) for tally %d with nps =1000000000    print table 160' %x in line:
numbers = (lines[i-1].strip())
print(numbers)
Dose.append(numbers[0])
SEM.append(numbers[1])
x += 10
print(Dose)
There aren't any secrets in this data so you can get the full input file here:

https://dl [dot] dropboxusercontent [dot] com/u/14334980/1billion.txt
4. Look at your data! It's fixed width. This matters.
Code:
with open('1billion.txt') as inf:

x = 6 #first tally number
Dose = []
SEM = []
for (i, line,) in enumerate(lines):
# changed to %4d format
if '1analysis of the results in the tally fluctuation chart bin (tfc) for tally%4d with nps =1000000000    print table 160' %x in line:
NO___THIS__IS__A__STRING = (lines[i-1].strip())  #numbers
print(NO___THIS__IS__A__STRING)

#### and just to spare you further pain, the line is a string.
#### This is your dang dose.  ['1', '1', '1', '1', '9', '1', '9', '9', '1', '1', '1', '1', '5', '1', '1', '1', '4', '1', '9', '5', '1', '8', '8', '9', '1', '7']

######Dose.append(numbers[0])  ##########wrong
######SEM.append(numbers[1])  ##########wrong

fields = NO___THIS__IS__A__STRING.split()
numbers = list(map(float,fields))   # NOW THESE ARE NUMBERS

Dose.append(numbers[0])
SEM.append(numbers[1])

x += 10
print(Dose)
5. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Jan 2013
Posts
25
Rep Power
0
Originally Posted by b49P23TIvg
Look at your data! It's fixed width. This matters.
Code:
with open('1billion.txt') as inf:

x = 6 #first tally number
Dose = []
SEM = []
for (i, line,) in enumerate(lines):
# changed to %4d format
if '1analysis of the results in the tally fluctuation chart bin (tfc) for tally%4d with nps =1000000000    print table 160' %x in line:
NO___THIS__IS__A__STRING = (lines[i-1].strip())  #numbers
print(NO___THIS__IS__A__STRING)

#### and just to spare you further pain, the line is a string.
#### This is your dang dose.  ['1', '1', '1', '1', '9', '1', '9', '9', '1', '1', '1', '1', '5', '1', '1', '1', '4', '1', '9', '5', '1', '8', '8', '9', '1', '7']

######Dose.append(numbers[0])  ##########wrong
######SEM.append(numbers[1])  ##########wrong

fields = NO___THIS__IS__A__STRING.split()
numbers = list(map(float,fields))   # NOW THESE ARE NUMBERS

Dose.append(numbers[0])
SEM.append(numbers[1])

x += 10
print(Dose)
Ugh I should have gotten that one. I'm gonging to go ahead and pull the "I just became a father two weeks ago and am suffering from extreme lack of sleep" card. I had a line in the old code to take care of the fixed width data but just forgot it here. You can tell my code isn't very efficient but I think I'm starting to get the for loops which improves it a lot. Thanks again!
6. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Jan 2013
Posts
25
Rep Power
0
Originally Posted by b49P23TIvg
Look at your data! It's fixed width. This matters.
Code:
with open('1billion.txt') as inf:

x = 6 #first tally number
Dose = []
SEM = []
for (i, line,) in enumerate(lines):
# changed to %4d format
if '1analysis of the results in the tally fluctuation chart bin (tfc) for tally%4d with nps =1000000000    print table 160' %x in line:
NO___THIS__IS__A__STRING = (lines[i-1].strip())  #numbers
print(NO___THIS__IS__A__STRING)

#### and just to spare you further pain, the line is a string.
#### This is your dang dose.  ['1', '1', '1', '1', '9', '1', '9', '9', '1', '1', '1', '1', '5', '1', '1', '1', '4', '1', '9', '5', '1', '8', '8', '9', '1', '7']

######Dose.append(numbers[0])  ##########wrong
######SEM.append(numbers[1])  ##########wrong

fields = NO___THIS__IS__A__STRING.split()
numbers = list(map(float,fields))   # NOW THESE ARE NUMBERS

Dose.append(numbers[0])
SEM.append(numbers[1])

x += 10
print(Dose)
Code:
for (i, line,) in enumerate(lines):
you use the enumerate command. As I understand enumerate it simply numbers each line 1-whatever. If I remove the command the code doesn't work and gives an error of too many values to unpack. Why is this command necessary?
7. One way to cause wrong number of values to unpack

>>> a, b = [9]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: need more than 1 value to unpack

As far as I can tell, these two statement-groups are functionally the same
Code:
for i in range(len(lines)):   # boring
line = lines[i]
block

for (i, line,) in enumerate(lines):  # exciting, new
block
The pattern is so common I've assumed there must be a performance gain for using enumerate.

Originally Posted by python documentation
New in version 2.3.
Oh. enumerate isn't so new. I don't recall being aware of enumerate before python3.[/edit]
Last edited by b49P23TIvg; April 17th, 2013 at 11:20 AM.