Forums: » Register « |  Free Tools |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support |

New Free Tools on Dev Shed!

#1
April 15th, 2013, 04:50 PM
 danipoak
Registered User

Join Date: Jan 2013
Posts: 25
Time spent in forums: 4 h 36 m 34 sec
Reputation 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
April 15th, 2013, 06:12 PM
 b49P23TIvg
Contributing User

Join Date: Aug 2011
Posts: 4,159
Time spent in forums: 1 Month 3 Weeks 2 Days 9 h 8 m 45 sec
Reputation Power: 455
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.
__________________
[code]Code tags[/code] are essential for python code!

#3
April 15th, 2013, 06:36 PM
 danipoak
Registered User

Join Date: Jan 2013
Posts: 25
Time spent in forums: 4 h 36 m 34 sec
Reputation 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
April 15th, 2013, 07:13 PM
 b49P23TIvg
Contributing User

Join Date: Aug 2011
Posts: 4,159
Time spent in forums: 1 Month 3 Weeks 2 Days 9 h 8 m 45 sec
Reputation Power: 455
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
April 15th, 2013, 09:42 PM
 danipoak
Registered User

Join Date: Jan 2013
Posts: 25
Time spent in forums: 4 h 36 m 34 sec
Reputation Power: 0
Quote:
 Originally Posted by b49P23TIvg Look at your data! It's fixed width. This matters. Code: ```with open('1billion.txt') as inf: lines = inf.readlines() 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
April 17th, 2013, 11:49 AM
 danipoak
Registered User

Join Date: Jan 2013
Posts: 25
Time spent in forums: 4 h 36 m 34 sec
Reputation Power: 0
Quote:
 Originally Posted by b49P23TIvg Look at your data! It's fixed width. This matters. Code: ```with open('1billion.txt') as inf: lines = inf.readlines() 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
April 17th, 2013, 12:15 PM
 b49P23TIvg
Contributing User

Join Date: Aug 2011
Posts: 4,159
Time spent in forums: 1 Month 3 Weeks 2 Days 9 h 8 m 45 sec
Reputation Power: 455
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.

Quote:
 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 12:20 PM.

 Viewing: Dev Shed Forums > Programming Languages > Python Programming > Parsing the previous line