Search code examples
python-3.xfile-handling

how to pass a filename as function parameter in python?


I've got a problem to solve that says . Write a function in python that will take a file name fname and a string s as input. It will return whether s occurs inside the file. It's possible that the file is extremely large so it cannot be read into memory in one shot and I've done a solution for that like this

import fileinput
def FileAndString(s,filename):
    
    inname =input(filename)
    s =s
    fname= open(fileinput.input(files ='inname'))
    flag = 0
    index = 0
    for line in fname:
        index += 1
        if s in line:
            flag = 1
            break
    if flag == 0:
        print("string", s, "not found")
    else:
        print('String', s, 'Found In Line', index)
FileAndString('goal','fname.txt')

and I'm getting an error like this

  traceback (most recent call last):
  File "c:/Users/hp/Desktop/test/repo/file.py", line 19, in <module>
  File "c:/Users/hp/Desktop/test/repo/file.py", line 10, in FileAndString
    index += 1
  File "C:\Users\hp\AppData\Local\Programs\Python\Python38\lib\fileinput.py", line 248, in __next__
    line = self._readline()
  File "C:\Users\hp\AppData\Local\Programs\Python\Python38\lib\fileinput.py", line 366, in _readline
    self._file = open(self._filename, self._mode)
FileNotFoundError: [Errno 2] No such file or directory: 'inname'

and my question is: is this the right way to do it? how to pass that fname.txt or any file as a parameter


Solution

  • As others has already answered, the problem you're having with your code is that you're not opening the file you're giving the function. You're trying to open a string-representation of the variable, not the actual variable.

    Here is the solution you're after:

    def string_in_file(fname, s):
        # Use a context-manager to automatically
        # handle closing of files after you're done.
        with open(fname, "r") as F:
            # Read one line at a time, keeping only
            # that one line in memory.
            for line in F.readlines():
                if s in line:
                    return True
            # If none of the lines in the for-loop
            # are True, then the string is not in the file.
            return False
    

    Or if you want a single-line solution (which doesn't work the same way, but gives similar results):

    string_in_file = lambda fname, s: any(s in line for line in open(fname))