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'
Move
return dfto the end of the function (or move it toelseblock), and makeread_wb()call return value: