-1

I have tried to organize my Python (Python version 3.9.2) project better and have created following file structure (I am using VS Code on Macbook Air M2). When I try to call a function in the "function file structure" I get the following error message:

NameError: name 'getAssetHoldings' is not defined

# File structure:
# main.py
my_functions
 _init_.py
 stock_functions.py
 utility_functions.py

# Content of files:
#main.py:
import my_functions
import pandas as pd
import seaborn as sns

# load transaction file
filepath_transact = os.path.abspath(f"/Users/Sandbox/Data/transactions.csv")
df_sq = pd.read_csv(filepath_transact,encoding = "ISO-8859-1",sep=';')

# get asset holdings (function resides in stock_functions.py)
df_assets = getAssetHoldings(df_sq)
print('Assets:', '\n',df_assets,'\n')

#_init.py:
from .stock_functions import *
from .utility_functions import *
print('hello')

#stock_functions.py:
import pandas as pd
import yfinance as yf
import pandas_market_calendars as mcal

def getAssetHoldings(df):
    df_numberAssets_k = df_transactions[df_transactions['Transaktionen'].isin(['Buy'])]
    df_numberAssets_k = df_numberAssets_k[['Symbol','Quantity']]
    df_numberAssets_v = df_transactions[df_transactions['Transaktionen'].isin(['Sell'])]
    df_numberAssets_v = df_numberAssets_k[['Symbol','Quantity']]
    ....
    return df_current_assets 

I tried to restart the kernel and import the libraries and functions several times.

Roberto S
  • 3
  • 2
  • 1
    What does it say when you run it? – brando f Feb 18 '23 at 14:55
  • NameError: name 'getAssetHoldings' is not defined – Roberto S Feb 18 '23 at 14:59
  • If I've read your file structure right, in your `main.py`, you have to call the function using dot notation: `my_functions.getAssetHoldings(...)`. Another solution may be importing everything with `from my_functions import *` but I don't like it very much – Scarlet Feb 18 '23 at 15:06
  • Maybe try putting 'from my_functions.stock_functions import getAssetHoldings' at the top of main. – brando f Feb 18 '23 at 15:09
  • @Scarlet: I tried your suggestions and I get the following error message: AttributeError: module 'my_functions' has no attribute 'getAssetHoldings' – Roberto S Feb 18 '23 at 15:15
  • @brandof: thank you for your suggestion. If I do this I get the following: 'ModuleNotFoundError: No module named my_functions.stock_functions' – Roberto S Feb 18 '23 at 15:17
  • 1
    Does this answer your question? [How do I call a function from another .py file?](https://stackoverflow.com/questions/20309456/how-do-i-call-a-function-from-another-py-file) – Redox Feb 18 '23 at 15:34
  • I also faced a problem like yours but I somehow managed to [solve it](https://github.com/Scarlet06/multivariate-polynomial/blob/main/test.py) I think we need to be a little bit more specific and detailed. You have the main folder with `main.py` file and `my_functions` subfolder which has `__init__.py` (double '_'), `stock_functions.py`, `utility_functions.py`. If it is right and still doesn't work, I suppose you are not executing the main.py file in its folder and you need to add it to the syspath: [link](https://linuxhint.com/sys-path-append-python/) Otherways I dont have any more ideas – Scarlet Feb 18 '23 at 21:16
  • @scarlet: thank you very much for your detailed answer. Your answer solved my problem! thank you very much! It was the first time I was using this approach with the subfolders and the error was so silly: for '_init_.py 'is used only one underline "'_init_.py'... thank you every one to help solve my problem. Very much appreciated!! – Roberto S Feb 19 '23 at 08:42

1 Answers1

1

To close this question, I write here the solutions proposed in the comments. To be more clear I re-write the main structure of the question:

│
├─ main.py
│
└─ my_functions/
     ├─ _init_.py
     ├─ stock_functions.py
     └─ utility_functions.py

As @Roberto stated, the problem was that the __init__.py file needs the double underscore. And inside the main.py file, the function has to ba called through the dot notation my_functions.getAssetHoldings(...) since the module is imported with the line import my_functions.

Scarlet
  • 106
  • 5