0

Sorry if I asked a silly question or made an obvious mistake as OOPS is not my strong point!

I have a project for which I am using Python. I have written all the code in a single function and it works as expected, giving proper output dataframe.

But when I try to break that one function into multiple functions all present in different .py files, all the files present in one local directory, the output then gets changed. The output dataframe then contains all nan values.

main.py (only one file which contains all the code)

    def fn():
        .
        .
        .
        return x

Here x is the expected result and it works. But if I do this:

sub_module1.py (file #1)

class a:
    def __init__(self):
        pass:
    
    def fn1(self, para1):
        .
        .
        return x


sub_module2.py (file #2)

class b:
    def__init__(self):
        pass:

    def fn2(self, para2):
        .
        .
        return y


main.py (file #3)

from sub_module1 import a
from sub_module2 import b

x1 = a().fn1(para1)
x2 = b().fn2(para2)

def fn3(some parameters):
    # some logic which makes use of x1 and x2
    return new_x

new_x has nan values which don't make sense to me as the code is the same as used in main.py. The only difference is that instead of using one single function for the whole code, I have broken down the code into multiple functions which are stored in different python files but in the same directory and then I am calling those functions into one single python file(main.py) to get the output.

Any help is appreciated!

spectre
  • 717
  • 7
  • 21
  • In `fn1()` and `fn2()` you are returning `a` and `b` respectively. Are these supposed to be class instance objects of `a` and `b`? – Lihka_nonem Apr 30 '22 at 11:31
  • @Lihka_nonem I am new to OOPS so I dont know what instance objects are. Also I have edited the question to change the variables names being returned from `fn1()` and `fn2()` from `a` and `b` to `x` and `y` so that there is no confusion between class name and the variable being returned by the function. Basically `fn1()` and `fn2()` are returning 2 variables `x` and `y` respectively which are then being used by importing their respective classes in the `main.py` file. – spectre May 01 '22 at 06:23
  • 1
    The code you have there will not work. You would need `def __init__(self):` and `def fn1(self, para1):` and `def fn2(self, para2)`. Is that actually what you have? I think your "retyping" has introduced enough mistakes that we can't analyze it. – Tim Roberts May 01 '22 at 06:27
  • @TimRoberts Thank you. Typo on my part! Yes I have edited the question. There are 3 `.py` files, first one has `class a:` which has a function `fn1(self, para1)` which returns a. Similarly file 2 has `class b:` which consists of a function `fn2(self, para2)` which returns `b`. Third file has a function which calls both the functions. – spectre May 01 '22 at 11:05
  • @spectre, Please refer these - [link1](https://towardsdatascience.com/practical-python-class-vs-instance-variables-431fd16430d), [link2](https://www.pythonlikeyoumeanit.com/Module4_OOP/ClassInstances.html) – Lihka_nonem May 01 '22 at 12:26
  • There's simply not enough information here. Remember, as one example, that globals do not cross file boundaries. If you have a global `data` in `main.py` and a `data` in `sub_module1.py`, they are unrelated. Updates to one will not be seen in the other. – Tim Roberts May 03 '22 at 17:26

1 Answers1

1

From what I can gather, there is an issue with the logic inside fn3() or the way you are calling fn3().

If you are calling fn3() as shown below -

# main.py (file #3)

from sub_module1 import a
from sub_module2 import b

x1 = a().fn1(para1)
x2 = b().fn2(para2)

def fn3(some parameters):
    # some logic which makes use of x1 and x2
    return new_x

if __name__ == '__main__':
    new_x = fn3(some parameters)

Then what will happen is that x1 and x2 values will not have the values returned by your methods as their initialization is done outside the scope of f3(). Also, I hope some parameters include x1 and x2. If it doesn't, it's better to make sure that you are doing that explicitly. I would rewrite your code to do the following -

# main.py (file #3)

from sub_module1 import a
from sub_module2 import b

def fn3(some parameters, x1, x2):
    # some logic which makes use of x1 and x2
    return new_x

if __name__ == '__main__':
    x1 = a().fn1(para1)
    # print(x1) for sanity checking.
    x2 = b().fn2(para2)
    # print(x2) for sanity checking.
    new_x = fn3(some parameters, x1, x2)

The alternate approach is to get the values of x1 and x2 inside fn3(). Then your code would look as follows -

# main.py (file #3)

from sub_module1 import a
from sub_module2 import b

def fn3(some parameters):
    x1 = a().fn1(para1)
    # print(x1) for sanity checking.
    x2 = b().fn2(para2)
    # print(x2) for sanity checking.
    # some logic which makes use of x1 and x2
    return new_x

if __name__ == '__main__':
    new_x = fn3(some parameters)

If this still returns new_x as a NAN value, I would debug line by line what's happening inside fn3() as the issue surely lies over there.

Lihka_nonem
  • 352
  • 1
  • 8
  • There is not nearly enough information in his question to formulate anything approaching an answer. You're making a series of assumptions about what he wants that are not supported by the code. – Tim Roberts May 01 '22 at 23:02
  • @Lihka_nonem Thank you for your input. My implementation was correct but as you suggested to check the implementation of `fn3()`, it was indeed the culprit. Also the code implementation and the links you gave were helpful. +1 for the effort bud! – spectre May 03 '22 at 14:38
  • @TimRoberts Sorry about that. The reason I could not post more details about the code was because it was confidential. But other than that I will try to be more descriptive next time for sure! – spectre May 03 '22 at 14:39