I am having trouble with returning a DataFrame after some exception handling. What I'm doing is checking for a FileNotFoundError when reading in an excel file, if found then I am printing an error message and then re-running the function and trying to return the df then. However, on the second run, even if the file is found, it returns the df as a NoneType instead data from the excel file and raises an AttributeError when other functions try and use the df as a parameter.
Here's the code for the first function:
def read_wb():
try:
wb_name = input("What is the name of your workbook (add .xlsx): ")
df = pd.read_excel(wb_name)
return df
except FileNotFoundError:
print("Ooops... It looks like this file is spelled wrong or it's not in the same folder of the script. Try again.")
read_wb()
Here is the error that I am getting if an error was caught and read_wb() is ran under the except statement:
def main():
141 df = read_wb()
--> 142 df = modify_df(df)
143 df = return_ws(df)
144 repeat = input("Do want to run another file ('y' or 'n'): ").lower()
AttributeError: 'NoneType' object has no attribute 'loc'
I've tried moving the "return df" to the end of the except statement and even placing it on the same indent level as try and except, it still returns a NoneType. Any help would be appreciated, Thanks.
Here is the full error message:
AttributeError Traceback (most recent call last)
c:\Users\vn54jdq\Downloads\WFS Review Folders\Hams Filter Project.ipynb Cell 20 in <cell line: 146>()
145 main()
146 if __name__ == "__main__":
--> 147 main()
c:\Users\vn54jdq\Downloads\WFS Review Folders\Hams Filter Project.ipynb Cell 20 in main()
139 def main():
140 df = read_wb()
--> 141 df = modify_df(df)
142 df = return_ws(df)
143 repeat = input("Do want to run another file ('y' or 'n'): ").lower()
c:\Users\vn54jdq\Downloads\WFS Review Folders\Hams Filter Project.ipynb Cell 20 in modify_df(df)
18 tic = time.perf_counter()
19 ## This first part of the script goes through the list product_cat and product_cat_type.
20 ## If found, then it will mark a 'n' in the Chemical (Y/N) columns so it can be counted as an exclusion.
21 ## Then it searches for product types that are in the key flags that we are searching for like chemical...etc
---> 23 df.loc[df[df['Product Category'].str.contains(r'(?:\b(?=\w)|(?!\w))(?:{})(?:\b(?<=\w)|(?<!\w))'.format('|'.join(sorted(map(re.escape, product_cat), key=len, reverse=True))), case=False, regex=True).fillna(False)].index, "Chemical (Y/N)"] = 'n'
24 df.loc[df[df['Product Type'].str.contains(r'(?:\b(?=\w)|(?!\w))(?:{})(?:\b(?<=\w)|(?<!\w))'.format('|'.join(sorted(map(re.escape, values_flattened), key=len, reverse=True))), case=False, regex=True).fillna(False)].index, "Chemical (Y/N)"] = 'n'
25 df.loc[df[df['Product Type'].str.contains(r'(?:\b(?=\w)|(?!\w))(?:{})(?:\b(?<=\w)|(?<!\w))'.format('|'.join(sorted(map(re.escape, chem_values_flattened), key=len, reverse=True))), case=False, regex=True).fillna(False)].index, "Chemical (Y/N)"] = 'y'
AttributeError: 'NoneType' object has no attribute 'loc'
CodePudding user response:
Move return df
to the end of the function (or move it to else
block), and make read_wb()
call return value:
def read_wb():
try:
wb_name = input("What is the name of your workbook (add .xlsx): ")
df = pd.read_excel(wb_name)
except FileNotFoundError:
print("Ooops... It looks like this file is spelled wrong or it's not in the same folder of the script. Try again.")
return read_wb()
return df
CodePudding user response:
def read_wb():
while True:
try:
wb_name = input("What is the name of your workbook (add .xlsx): ")
df = pd.read_excel(wb_name)
except FileNotFoundError:
print("Ooops... It looks like this file is spelled wrong or it's not in the same folder of the script. Try again.")
read_wb()
return df