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:
CodePudding user response:
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)
CodePudding user response:
Don't use two loops. The first one is reading all of the file, so there's nothing for the second loop to read. You could fix this with file.seek(0)
to return to the beginning, but there's no need in this case -- just test both conditions in a single loop.
You also should use parameters and return values rather than global variables.
def fileinfo(file, beginning, ending):
beginFile = 0
endFile = 0
for num, line in enumerate(file, 1):
if beginning in line:
beginFile = num
if ending in line:
endFile = num
return beginFile, endFile
with open("testbooklet.csv") as MyFile:
begin, end = fileinfo(MyFile)