0

i'm currently working on a project and I seem to have encountered a logical bug. My project is in pure python and consists of two files: ui.py and read.py.

The ui handles a simple cmd ui and a cache file to save user settings.

Read gets data from the cache file via import from ui in order to parse some files ( the file parsing isn't related to the problem) Here is the code for ui:

def read_cache():
    with open("cache.txt", "r+") as f:
        byt = f.read()
        byt = byt.split()
    return byt


def write_cache(a, b):
    with open("cache.txt", "w") as f:
        f.write(a + "\n" + b)


def ui():
    g = raw_input("Use cache file? (y/n): ")

    if g == "y":
        i = read_cache()
        return i

    elif g == "n":
        zipname = raw_input("Zip file name: ")
        direc = raw_input("Zip file folder directory: ")
        write_cache(zipname, direc)
        i = [zipname, direc]
        return i
    else:
        print("ERROR: Please input a valid y/n \n")
        ui()

And here is the code for read (only related parts where the error occurrs):

import ui

x = ui.ui()
zipname = x[0]
direc = x[1]

The error is: Traceback (most recent call last): File "read.py", line 11, in <module> zipname = x[0] TypeError: 'NoneType' object has no attribute '__getitem__'

And it seems to occur when I input an invalid input during the y\n question, and than input a valid one. AKA something goes wrong in the else clause in ui.ui()

Any ideas? I tried importing only ui() from ui, I tried running ui in ui and assigning a var there.

Thanks in advance for the help.

Edit: changing the code to return ui() seems to fix the problem but I don't understand how. Can someone explain please?

Second edit: I still don't know why return ui() works but my whole code could be better build by changing everything to a while loop with an if loop nested. Than there is no need for recursion. Thanks @dercz and @zondo

Solain
  • 1
  • 2
  • 2
    Your `ui` function should `return ui()` instead of just `ui()`. – zondo Jul 09 '16 at 15:08
  • @zondo I'm not trying to return ui(), I'm trying to recurse ui() in case of an invalid input so the user can input a valid input without relaunching the script. – Solain Jul 09 '16 at 15:45
  • @Solain: zondo is right, since ui() finally is about to return this i thing, you need to do "return ui()". note that python does not recognize tail recursion, so you might do better (wrt memory usage) with some sort of while loop. – dercz Jul 09 '16 at 15:58
  • @dercz thanks for the help but I still don't understand why return fixed the problem. Shouldn't simply ui() recurse the function? and what do you mean by implementing a while loop? as in replace the if with a while loop? – Solain Jul 09 '16 at 16:31
  • @Solain: it did recur, but didn't pass the result "up the call stack". – dercz Jul 09 '16 at 19:17
  • 1
    @Solain: Python doesn't make special cases for calling a function within itself. Even within `ui()`, `ui()` is still just a function. When you do just `ui()`, you are calling it, but you aren't saying what to do with the result. Some recursive functions call themselves more than once in the same call. If Python automatically returned as soon as the recursion happens, that wouldn't be possible. Since you gave no `return` statement, your function automatically returned `None`. – zondo Jul 09 '16 at 20:48

0 Answers0