1

I want to be able to return the value assigned to a variable assigned to an active function, but if that function is not active, I want to be able to return 0 for the same variable, but assigned to a different function. The code block below is what I want to do this with:

def draw(x):
    if not hasattr(draw, 'counter'):
         draw.counter = 0
    draw.counter += 1
    global drawing
    q.put(x)
    process = False
    drawingLock.acquire()
    if not drawing:
        process = True
        drawing = True
    drawingLock.release()
    if process:
        if not q.empty():
            x()
        drawingLock.acquire()
        drawing = False
        drawingLock.release()
    print('`draw` has been called {} times'.format(draw.counter))
    h = draw.counter
    def walk():
        if not hasattr(walk, "counter"):
            walk.counter = 0
        walk.counter += 1
        penup()
        forward(letter_width + space_width)
        pendown()
        print('`walk` has been called {} times'.format(walk.counter))
        global w
        w = 0 if walk is False else walk.counter
    onkey(walk, "space")
    def draw_newline():
        # This funtion will pick up the turtle and move it to a second line below HELLO
        penup()
        goto(xcor() -(((space_width + letter_width)*(draw.counter)) + (space_width * w)) , ycor() -(letter_height + letter_height/2))
        pendown()
    def handle_enter():
        draw.counter = 0
        walk.counter = 0
    def Carriage_functions():
        draw_newline()
        handle_enter()
    onkey(Carriage_functions, "Return")

As you can see, this walk() function:

    def walk():
        if not hasattr(walk, "counter"):
            walk.counter = 0
        walk.counter += 1
        penup()
        forward(letter_width + space_width)
        pendown()
        print('`walk` has been called {} times'.format(walk.counter))
        global w
        w = 0 if walk is False else walk.counter
    onkey(walk, "space")

draws a space in the turtle graphics window every time SPACE is pressed on the keyboard, and it also counts how many times it has been executed through:

if not hasattr(walk, "counter"):
        walk.counter = 0
    walk.counter += 1

Then, I assign this value to the globally declared variable 'w' to be used in the next function (draw_newline()) like this:

global w
w = 0 if walk is False else walk.counter

The issue is that whenever I assign the w to the draw newline()'s goto() function, like so:

goto(xcor() -(((space_width + letter_width)*(draw.counter)) + (space_width * w)) , ycor() -(letter_height + letter_height/2))

I get this error:

in draw_newline
goto(xcor() -(((space_width + letter_width)*(draw.counter)) + (space_width * w)) , ycor() -(letter_height + letter_height/2))
NameError: name 'w' is not defined

even though w is globally defined! What am I doing wrong here?

EDIT: I have even tried this:

def walk():
    if not hasattr(walk, "counter"):
        walk.counter = 0
    global counter
    walk.counter += 1
    penup()
    forward(letter_width + space_width)
    pendown()
    print('`walk` has been called {} times'.format(walk.counter))
    global h
    h = walk.counter
if walk == False:
    w = 0
elif walk == True:
    w = h

and still no luck. I am just getting this error:

NameError: free variable 'w' referenced before assignment in enclosing scope

Even when I put the same code block after the draw_newline() function, I still get the same error.

R. Kap
  • 559
  • 1
  • 8
  • 30
  • Please fix your indentation. – senshin Dec 17 '15 at 22:19
  • do you press `return` before `space`? `w` is declared global within `walk` only. Why don't you assign a value to it globally? I cannot see such statement. BTW: your code is unnecessarily complicated (e.g. why use the function namespace for a local? `walk.counter`) – Pynchia Dec 17 '15 at 22:28
  • @senshin I fixed whatever indentation error I saw. – R. Kap Dec 17 '15 at 22:28
  • @Pynchia Yes, but that is because I want the user to be able to press them in any order, and still get the desired action of a carriage return when pressing `Enter`. That is why I want `w` to return `0` if `walk()` is not active, otherwise `walk.counter`'s value. – R. Kap Dec 17 '15 at 22:30
  • 1
    My point is that nobody has assigned a value to `w` if `return` is pressed first. – Pynchia Dec 17 '15 at 22:31
  • @Pynchia Well, if I assign the value to `w` outside the `walk()` function, then I get `AttributeError: 'function' object has no attribute 'counter'`. – R. Kap Dec 17 '15 at 22:32
  • @Pynchia Okay, so I assign a **global** variable to `w` and assign `0` to `w` in the `draw_newline()` function, but now, the program is "seeing" `w` as ONLY ZERO, so even if I press space BEFORE I press enter, w still remains zero. – R. Kap Dec 17 '15 at 22:39
  • Then when is `w` supposed to be initialized? – Pynchia Dec 17 '15 at 22:40
  • 2
    Pynchia is right. You want to initialize w to 0 once ever, before stuff happens, or replace w with an attribute/function to return 0 or walk.counter – Kenny Ostrom Dec 17 '15 at 22:41
  • @Pynchia `w` is supposed to be initialized whenever `draw_newline()` is called when the user chooses to draw a new line, but it should carry the value from the `walk.counter` in the `walk()` function, however, if `walk()` is inactive, `w` should equal 0. – R. Kap Dec 17 '15 at 22:43
  • Please explain what the meaning of `w = 0 if walk is None else walk.counter` is. Why should a function be `None`? Maybe you meant `w` instead of `walk` originally? – Pynchia Dec 17 '15 at 22:45
  • I had never seen that either, but http://stackoverflow.com/questions/394809/does-python-have-a-ternary-conditional-operator – Kenny Ostrom Dec 17 '15 at 22:48
  • @KennyOstrom oh, yes, I am fine with the epression, it's the variable being tested... (i.e. the function itself) – Pynchia Dec 17 '15 at 22:49
  • @Pynchia How else would I say `w = 0 if walk # Is not initialized`? I tried `False`, but that did not really work either, so I thought that the logical approach would be to assin 0 to `w` if `walk` is `None` (not active). – R. Kap Dec 17 '15 at 22:50
  • `walk` is the function where that line lives... I do not get it I am sorry. I give up and go to bed. Good luck, I hope you'll find a better way around this. When things get so muddy, it usually means the design is wrong and there is some technical debt to be paid (i.e. study) :) – Pynchia Dec 17 '15 at 22:52
  • @Pynchia Yeah, I guess. I am starting out in Python, as I have only really been at it for about a few months, so I guess I still have a lot more to learn. Well, thanks anyway! – R. Kap Dec 17 '15 at 22:54

0 Answers0