views:

90

answers:

2

Need to create a function with two params, a filename to open and a pattern.

The pattern will be a search string.

Eg. the function will open sentence.txt that has something like "The quick brown fox" (can possibly be more than one line)

The pattern will be "brown fox"

So if found, as this will be, it should return a line number and index of the character the found string starts on. Else, return -1.

Catch is I've never programmed in python before so I don't know the syntax. Previously coded in C, C#, Java, VB, etc..

EDIT:

.....Id

.....Name

#

my intent was for you to write HW3 code as iteration or

nested iterations that explicitly index the character

string as an array; i.e, the Python index() also known as

string.index() function is not allowed for this homework.

#

filename = raw_input('Enter filename: ')

pattern = raw_input('Enter pattern: ')

def findPattern(fname, pat):

Reading in one whole chunk

filetext = open(fname).read()
if pat in filetext:
    print("Found it -- chunk")
else:
    print("Nothing -- chunk")

Reading in line by line

for search in open(fname):
    if pat in search:
        print("Found it -- line")
    else:
        print("Nothing -- line")    

findPattern(filename, pattern)

+1  A: 

Here's a very simple grep. You could hack it out to use regular expressions pretty trivially. globbing wouldn't be much more difficult with glob. Also, the code you want is in there spread between grep and main so that might be of more interest than a custom grep ;)

def grep(filename, needle):
    with open(filename) as f_in:
        matches = ((i, line.find(needle), line) for i, line in enumerate(f_in))
        return [match for match in matches if match[0] != -1]

def main(filename, needle):
    matches = grep(filename, needle)
    if matches:
        print "{0} found on {1} lines in {2}".format(needle, len(matches), filename) 
        for line in matches:
            print "{0}:{1}:{2}".format(*line)
        return 1
    else:
        return -1

if __name__=='__main__':
    import sys
    filename = sys.argv[1]
    needle = sys.argv[2]
    return sys.exit(main(filename, needle))

Note that I haven't tested this code so there might be slight bugs. If it compiles, it should run fine though.

Also, you should tell your teacher that signalling failure with return codes is a terrible way to do things. If the caller of the function that you're going to write needs to know if no matches were found, it can just check for an empty list.

aaronasterling
Is this python 3.0 or 2.x?
JoshD
@JoshD, it should be both.
aaronasterling
Ah, I just didn't recognize the with keyword. I guess I should use that... Also, excellent answer! +1
JoshD
A: 

you can simulate simple "grep" with the "in" operator

def grep(filename, pattern):
    for n,line in enumerate(open(filename)):
        if pattern in line:
             print line, n

To get index, you can use str.index() or str.find()

ghostdog74
I'd have to profile to be sure but I think that using `in` and _then_ `index` is just not going to be as fast as using `find` and getting it over with.
aaronasterling
Well, if you use find(), its only going to get you a position number. Its not going to print out the line where pattern is found. Anyway, I have already mentioned the function is only simulating a simple grep.
ghostdog74
I need to do this without grep. I've just been looking through the python docs on regular expressions http://docs.python.org/library/re.html but am not sure what I'd use. Here is where I'm at, using both reading the text as a whole chunk or by line. However by line will read both, and answer both. So it can and will post both a 'found it' for the first line and then a 'nothing' because it still reads the second line.Check edit for code
John Redyns