1

My program tui.py consists of about 70 functions, which are sorted groupwise into four different documents:

  • tui.py
  • tbt.py
  • ens.py
  • hmm.py.

Most functions call at least one other function, some also call a function located in another *.py file.

I already tried putting an __init__ function (as below) in my "main" document (tui.py) and creating an additional main document, in which I put the content of tui.__init__ (not putting as a function there).

tui.py

(partly, to keep it as simple as possible)

import shutil
import os
from tbt import *
from ens import *
from hmm import *

def window () :
    print ( '\n//======================================================\\\\' )
    print ( '||\t\t\t\t\t\t\t||' )
    print ( '||\t\t\t\t\t\t\t||' )
    print ( '||\tR E ad-in of saved variables from file(s) E\t||' )
    print ( '||\tDe L etion of saved files or created dirs L\t||' )
    print ( '||\tStart of computation  . . . . . . . . . . B\t||' )
    print ( '||\tShow this window . . . . . . . . . .  . . W\t||' )
    print ( '||\tExit program  . . . . . . . . . . . . . . Q\t||' )
    print ( '||\t\t\t\t\t\t\t||' )
    print ( '||\t\t\t\t\t\t\t||' )
    print ( '\\\\======================================================//\n' )

def erase (content) : # simplified version, to keep the code comprehensible
    shutil.rmtree (  os.path.join (pathname, filename) )
    return pathname, filename

def compute (content, hmm) : # here needs to be ens.py, hmm.py, tbt.py included.
    content, hmm = tbt_init (content, hmm)
    return content, hmm

def __init__ (self, content, hmm) :
    window ()
    give_in = input ( '\tWhat comes next? ' )

    while give_in != 'q' and give_in != 'Q' :
        if len (give_in) > 1 : # check wether exactly one command was put in.
            give_in = input ( 'Type and execute the commands one by one. ' )
        elif give_in == 'N' :
            give_in = input ( '\tAnd now? [Window with W.] ' )
        elif give_in == 'e' or give_in == 'E' :
            content, hmm = read_file (content, hmm)
            give_in = 'N'
        elif give_in == 'l' or give_in == 'L' :
            pathname, filename = erase (content)
            give_in = 'N'
        elif give_in == 'b' or give_in == 'B' :
            content, hmm = compute (content, hmm)
            give_in = 'N'
        elif give_in == 'w' or give_in == 'W' :
            window (verbose)
            give_in = 'N'
        else :
            give_in = input ( 'Unknown command. Exit program with Q. ' )
    if give_in == 'q' or give_in == 'Q' : # The if statement isn't really needed indeed, but it's there, just in case.
        quit ()
    quit () # This also isn't really needed indeed, but it's there, just in case.
    return content, hmm

tbt.py

def tbt_init (content, hmm) :
    # some other stuff
    os.mkdir (content ['path'])
    pathname, filename = erase (content) # this lies in tui.py
    return content, hmm

This version doesn't give me any output.

Having all four files imported into every other file doesn't help either. I also need to import the python modules (os, shutil) in every subfile although they're already imported into tui.py

What's wrong here to execute the code above? How would it be a working code?

EDIT: I got the following errors, depending on changing three lines in the source files:

snippets in original form

# tui.py
from tbt import * 
content, hmm = tbt_init (content, hmm)
# tbt.py
## nothing imported here
pathname, filename = erase (content)

  File "tui.py", line 62, in <module>
    content, hmm = compute (content, hmm)
  File "tui.py", line 44, in compute
    content, hmm = tbt_init (content, hmm)
  File /home/user/tbt.py, line 5, in tbt_init
    pathname, filename = erase (content) # this lies in tui.py
NameError: name 'erase' is not defined

letting 'erase' be found by 'tbt.py'

# tui.py
from tbt import * 
content, hmm = tbt_init (content, hmm)
# tbt.py
from tui import *
pathname, filename = erase (content)

  File "tui.py", line 5, in <module>
    from tbt import *
  File "/home/user/tbt.py", line 2, in <module>
    from tui import *
  File "/home/user/tui.py", line 62, in <module>
    content, hmm = compute (content, hmm)
  File "/home/user/tui.py", line 44, in compute
    content, hmm = tbt_init (content, hmm)
NameError: name 'tbt_init' is not defined

making absolute module names

# tui.py
import tbt
content, hmm = tbt.tbt_init (content, hmm)
# tbt.py
## nothing imported
pathname, filename = erase (content)

  File "tui.py", line 63, in <module>
    content, hmm = compute (content, hmm)
  File "tui.py", line 45, in compute
    content, hmm = tbt.tbt_init (content, hmm)
  File "/home/user/tbt.py", line 5, in tbt_init
    pathname, filename = erase (content) # this lies in tui.py
NameError: name 'erase' is not defined

letting 'erase' being found

# tui.py
import tbt
content, hmm = tbt.tbt_init (content, hmm)
# tbt.py
import tui
pathname, filename = tui.erase (content)

  File "tui.py", line 6, in <module>
    import tbt
  File "/home/user/tbt.py", line 2, in <module>
    import tui
  File "/home/user/tui.py", line 63, in <module>
    content, hmm = compute (content, hmm)
  File "/home/user/tui.py", line 45, in compute
    content, hmm = tbt.tbt_init (content, hmm)
AttributeError: module 'tbt' has no attribute 'tbt_init'
Nepumuk
  • 243
  • 1
  • 3
  • 13
  • Are your other files located all in the same directory? Do you get any errors? – Lucan Sep 18 '19 at 11:00
  • if all the files are in the same directory you should be able to import them just as you mentioned – Optimus Sep 18 '19 at 11:01
  • @Tortoise They are all in the same directory (not sub-directory), in which I also run `python3 tui.py`. The code works fine until it's supposed to call `erase (content)` in `tui.py`. I get `content ['pathname'], content ['filename'], success = erase (content)` `NameError: name 'erase' is not defined`. – Nepumuk Sep 18 '19 at 11:12
  • @Optimus The code compiles without errors, but it doesn't do anything (visible to the eye). But it should give me at least the `window ()` as output… Shouldn't it? – Nepumuk Sep 18 '19 at 11:15
  • Calling your entry point `__init__` is not necessary, you should be able to import and consume functions from other python files so I would try taking things back to basics by testing `import` and external functions in a new folder - it's not clear; from what we have, why it isn't working for you – Lucan Sep 18 '19 at 11:33
  • When putting all functions into separate files (and `import "file"`ing or `from "file" import *`ing them), it seems that the errors just become worse… – Nepumuk Sep 18 '19 at 12:59
  • The thing is that I need to import the python files (and modules) in which the used functions are defined. But when I do, it shows me the window again… – Nepumuk Sep 18 '19 at 14:17

1 Answers1

1

Try changing your __init__ method:

tui.py

import numpy as np
import pandas as pd
import shutil
import os
import tbt

def window () :
    print ( '\n//======================================================\\\\' )
    print ( '||\t\t\t\t\t\t\t||' )
    print ( '||\t\t\t\t\t\t\t||' )
    print ( '||\tR E ad-in of saved variables from file(s) E\t||' )
    print ( '||\tDe L etion of saved files or created dirs L\t||' )
    print ( '||\tStart of computation  . . . . . . . . . . B\t||' )
    print ( '||\tShow this window . . . . . . . . . .  . . W\t||' )
    print ( '||\tExit program  . . . . . . . . . . . . . . Q\t||' )
    print ( '||\t\t\t\t\t\t\t||' )
    print ( '||\t\t\t\t\t\t\t||' )
    print ( '\\\\======================================================//\n' )

def erase (content) : # simplified version, to keep the code comprehensible
    shutil.rmtree (  os.path.join (content ['rootpath'], content ['indir']) )
    return content ['rootpath'], content ['indir']

def compute (content, hmm) : # here needs to be ens.py, hmm.py, tbt.py included.
    content, hmm = tbt.tbt_init (content, hmm)
    return content, hmm

def main () :
    content = {
        'rootpath' : os.path.abspath ( os.getcwd () ),
        'indir' : 'a',
        'outdir' : 'output',
        'datafile' : 'datei.csv',
        'configfile' : 'contents.txt',
        'savefile' : 'contents.txt',
        'model' : np.arange (4),
        'datafiles' : [os.path.join (os.getcwd (), 'data.csv'), os.path.join (os.getcwd (), 'data.dat')],
        'data' : pd.DataFrame ( np.arange (15).reshape (3, 5) ),
        'result' : None,
    }
    hmm = {
        'hmm_a' : np.random.rand (9).reshape (3, 3),
        'hmm_b' : np.zeros (3),
        'hmm_mu' : np.random.rand (1),
        'hmm_pi' : np.random.rand (3),
    }

    window ()
    give_in = input ( '\tWhat comes next? ' )

    while give_in != 'q' and give_in != 'Q' :
        if len (give_in) > 1 : # check wether exactly one command was put in.
            give_in = input ( 'Type and execute the commands one by one. ' )
        elif give_in == 'N' :
            give_in = input ( '\tAnd now? [Window with W.] ' )
        elif give_in == 'e' or give_in == 'E' :
            content, hmm = read_file (content, hmm)
            give_in = 'N'
        elif give_in == 'l' or give_in == 'L' :
            pathname, filename = erase (content)
            give_in = 'N'
        elif give_in == 'b' or give_in == 'B' :
            content, hmm = compute (content, hmm)
            give_in = 'N'
        elif give_in == 'w' or give_in == 'W' :
            window (verbose)
            give_in = 'N'
        else :
            give_in = input ( 'Unknown command. Exit program with Q. ' )
    if give_in == 'q' or give_in == 'Q' : # The if statement isn't really needed indeed, but it's there, just in case.
        quit ()
    quit () # This also isn't really needed indeed, but it's there, just in case.
    return content, hmm

if __name__== "__main__":
    main()

tbt.py

import os
import tui

def tbt_init (content, hmm) :
    # some other stuff
    pathname, filename = tui.erase (content) # this lies in tui.py
    return content, hmm
Community
  • 1
  • 1
Šimon Kocúrek
  • 1,591
  • 1
  • 12
  • 22