Newbie Question : "grep"

M

moogyd

Hello,

I am attempting to write my first Python script to extract some
information from a file, and place it into another file.
(I am trying to find the physical postions of 4 cells within an FPGA)
I have a working solution, and would appreciate any comments.

for line in lines:

if "placed" in line:
if "i_a/i_b/ROM/" in line:
pos = (line.split()[4]).split("_")[1]
if "B18" in line:
print " i_a/i_b/ROM/B18 [7:6] LOC =", pos
elif "B14" in line:
print " i_a/i_b/ROM/B14 [5:4] LOC =", pos
elif "B10" in line:
print " i_a/i_b/ROM/B10 [3:2] LOC =", pos
elif "B6" in line:
print " i_a/i_b/ROM/B6 [1:0] LOC =", pos
else:
print "Error"

Specific questions
- Use for "Phrase" in line or line.find("Phrase") >= 0 ?
- If I increase number of elements I am searching for, then I have
more elif...elif. Is there a cleaner solution?

Thanks for any feedback.

Steven
 
L

Larry Bates

Hello,

I am attempting to write my first Python script to extract some
information from a file, and place it into another file.
(I am trying to find the physical postions of 4 cells within an FPGA)
I have a working solution, and would appreciate any comments.

for line in lines:

if "placed" in line:
if "i_a/i_b/ROM/" in line:
pos = (line.split()[4]).split("_")[1]
if "B18" in line:
print " i_a/i_b/ROM/B18 [7:6] LOC =", pos
elif "B14" in line:
print " i_a/i_b/ROM/B14 [5:4] LOC =", pos
elif "B10" in line:
print " i_a/i_b/ROM/B10 [3:2] LOC =", pos
elif "B6" in line:
print " i_a/i_b/ROM/B6 [1:0] LOC =", pos
else:
print "Error"

Specific questions
- Use for "Phrase" in line or line.find("Phrase") >= 0 ?
- If I increase number of elements I am searching for, then I have
more elif...elif. Is there a cleaner solution?

Thanks for any feedback.

Steven
Something like (not tested):

def search(search_gates, line):
for gate, index in search_gates:
pos = (line.split()[4]).split("_")[1]
if gate in line:
return " i_a/i_b/ROM/%s %s LOC =%s" % (gate, index, pos)


return "Error"


search_gates=[('B6', '[1:0]'), 'B10', '[3:2]'),
'B14', '[5:4]'), 'B17', '[7:6]')]

for line in lines:
print search(search_gates, line)

-Larry
 
E

Erik Johnson

- If I increase number of elements I am searching for, then I have
more elif...elif. Is there a cleaner solution?

I'm not sure exactly what your lines look like, but this script implies that
every line that matches 'i_a/i_b/ROM' is one of the known list you are
looking for. Maybe that's exactly right...

Below is some code that I think is an incremental improvement over writing
lots of alternative if-statements.
I beleive it has the same behaviour, though it is totally untested:

tags = [
['B18', (7, 6)],
['B14', (5, 4)],
['B10', (3, 2)],
['B6', (1, 0)],
]

for line in lines:
if "placed" in line:
if "i_a/i_b/ROM/" in line:
pos = (line.split()[4]).split("_")[1]
found = False
for (tag, (start, end)) in tags:
if tag in line:
found = True
print " i_a/i_b/ROM/%s [%i:%i] LOC =" %\
(pos, tag, start, end)
break

This way, you just need to maintain your data structure (tags), instead
of writing lots of repettitive code.
If there is a definite pattern to the part that looks like a slice (what I
am calling (start, end)), then you could
programmatically generate that as well, of course.

The list of things you are looking for could be in a separate file, etc.
The sensible thing to do sort of depends on how big this list of stuff you
are looking for is going to grow and how much you are going to use this
program. Do what makes sense for you.

You may want to explore the 're' module as well (regular expressions)
http://docs.python.org/modindex.html , which may or may not improve
performance, readability, maintainability, etc.

See also section 10.10 of the Python Tutorial if you are interested in code
performance issues: http://docs.python.org/tut/tut.html

Hope that helps,
-ej
 
E

Erik Johnson

Sorry, I forgot to paste the modified version of my code in the post:. I
think this is the same behaviour:

for line in lines:
if "placed" in line:
if "i_a/i_b/ROM/" in line:
pos = (line.split()[4]).split("_")[1]
found = False

for (tag, (start, end)) in tags:
if tag in line:
found = True
print " i_a/i_b/ROM/%s [%i:%i] LOC =" %\
(pos, tag, start, end)
break

if not found:
print "Error"
 
A

attn.steven.kuo

Sorry, I forgot to paste the modified version of my code in the post:. I
think this is the same behaviour:

for line in lines:
if "placed" in line:
if "i_a/i_b/ROM/" in line:
pos = (line.split()[4]).split("_")[1]
found = False

for (tag, (start, end)) in tags:
if tag in line:
found = True
print " i_a/i_b/ROM/%s [%i:%i] LOC =" %\
(pos, tag, start, end)
break

if not found:
print "Error"



Instead of using a sentinal value (i.e., found),
one can use the 'else' clause of a 'for' loop...


pos = (line.split()[4]).split("_")[1]
for (tag, (start,end)) in tags:
if tag in line:
print " i_a/i_b/ROM/%s [%i:%i] LOC=%s" %\
(pos,tag,start,end)
break
else
print "Error"
 
M

moogyd

Sorry, I forgot to paste the modified version of my code in the post:. I
think this is the same behaviour:
for line in lines:
if "placed" in line:
if "i_a/i_b/ROM/" in line:
pos = (line.split()[4]).split("_")[1]
found = False
for (tag, (start, end)) in tags:
if tag in line:
found = True
print " i_a/i_b/ROM/%s [%i:%i] LOC =" %\
(pos, tag, start, end)
break
if not found:
print "Error"

Instead of using a sentinal value (i.e., found),
one can use the 'else' clause of a 'for' loop...

pos = (line.split()[4]).split("_")[1]
for (tag, (start,end)) in tags:
if tag in line:
print " i_a/i_b/ROM/%s [%i:%i] LOC=%s" %\
(pos,tag,start,end)
break
else
print "Error"

Thanks for the responses.

I had an inkling what the solution may be, but I wondering whether I
could avoid the nested loops (i.e. loop every line and then loop every
pattern), maybe using maps or list comprehensions (this is just
intellectual curiosity as the current solution obviously does the job.

Steven
 
L

Larry Bates

Sorry, I forgot to paste the modified version of my code in the post:. I
think this is the same behaviour:
for line in lines:
if "placed" in line:
if "i_a/i_b/ROM/" in line:
pos = (line.split()[4]).split("_")[1]
found = False
for (tag, (start, end)) in tags:
if tag in line:
found = True
print " i_a/i_b/ROM/%s [%i:%i] LOC =" %\
(pos, tag, start, end)
break
if not found:
print "Error"
Instead of using a sentinal value (i.e., found),
one can use the 'else' clause of a 'for' loop...

pos = (line.split()[4]).split("_")[1]
for (tag, (start,end)) in tags:
if tag in line:
print " i_a/i_b/ROM/%s [%i:%i] LOC=%s" %\
(pos,tag,start,end)
break
else
print "Error"

Thanks for the responses.

I had an inkling what the solution may be, but I wondering whether I
could avoid the nested loops (i.e. loop every line and then loop every
pattern), maybe using maps or list comprehensions (this is just
intellectual curiosity as the current solution obviously does the job.

Steven

You can certainly get it down pretty small if you turn it into a function
as I did, and use a list comprehension, but I think it is hard to read.

def search(line):
global search_gates
for gate, index in search_gates:
pos = (line.split()[4]).split("_")[1]
if gate in line:
return " i_a/i_b/ROM/%s %s LOC =%s" % (gate, index, pos)


return "Error"


search_gates=[('B6', '[1:0]'), 'B10', '[3:2]'),
'B14', '[5:4]'), 'B17', '[7:6]')]

print '\n'.join([search(line) for line in lines])

-Larry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top