Search code examples
pythonfunctionenumerate

How to use two enumerate statements in one function in python?


I am trying to take two statements and put them into the same function. This is part of a long query to import a list of csv files (all different lengths, headers, footers, and columns) into one Excel sheet for importing into a database. I would like to set up functions that can be called to streamline the process.

Right now, if I run the following code, it works and I can use the two parameters: beginFile and endFile to determine the start and end of the data for importing.

beginning = 'eventID'
ending = 'The Line Listing is wrong'

beginFile = 0
endFile = 0

with open("testbooklet.csv") as myFile:
    for num, line in enumerate(myFile, 1):
        if beginning in line:
            beginFile = num
            
with open("testbooklet.csv") as myFile:
    for num, line in enumerate(myFile, 1):
        if ending in line:
            endFile = num
            
print(beginFile,endFile)

However; if I place this into a function, then I receive two different error messages, depending on how I write the function. For this first function, the error message is AttributeError: 'function' object has no attribute 'endFile'.

beginning = 'eventID'
ending = 'The Line Listing is wrong'

beginFile = 0
endFile = 0

# Define Function to find the first and last file lines
def fileinfo(file_name):
    global beginFile
    global endFile
    
    for num, line in enumerate(file_name, 1):
        if beginning in line:
            fileinfo.beginFile = num

# def endfileinfo(file_name):        
    for num, line in enumerate(file_name, 1):
        if ending in line:
            fileinfo.endFile = num

MyFile = open("testbooklet.csv")             
fileinfo(MyFile)
print(fileinfo.beginFile, fileinfo.endFile)

For this function, the error code is: NameError: name 'endFile' is not defined

beginning = 'eventID'
ending = 'The Line Listing is wrong'

beginFile = 0
endFile = 0

def fileinfo(file_name):
    global beginFile
    
    for num, line in enumerate(file_name, 1):
        if beginning in line:
            beginFile = num
   
    global endFile
            
    for num, line in enumerate(file_name, 1):
        if ending in line:
            endFile = num

            
MyFile = open("testbooklet.csv")
fileinfo(MyFile)
print(beginFile)
print(endFile)

This is a simplistic version of the data that I'm using for testing:

enter image description here


Solution

  • Don't use global variables that get mutated by functions. Instead let the function return whatever you need, and get both informations in one sweep:

    def fileinfo(file):
        beginFile = None
        endFile = None
        for num, line in enumerate(file, 1):
            if beginning in line:
                beginFile = num
            if ending in line:
                endFile = num
                break  # No need to continue
        return beginFile, endFile  # return this information to caller
    
    
    myFile = open("testbooklet.csv")             
    beginFile, endFile = fileinfo(myFile)
    print(beginFile, endFile)