1

I'm having issue with allowing a function to call on variables set by another function. I believe I know how to do this with single variables, but my code requires it be done with multiple variables, a challenge I've struggled with for hours. I've read much about ways others seem to have done this but I can't find success in implementing them.

#gathers the user's requests
def ask():
    userw = int(input('How wide? '))
    userh = int(input('How tall? '))
    userc = input('What string to use? ')
    userc_len = int(len(userc))
    return (userw, userh, userc, userc_len)

#draws the rows of the box. First the top with the topbot function, then the body with body(), then the bottom with topbot again
def draw(w, h, c, c_len):
    def topbot(w_, c_):
        for x in range(w_):
            print (c_, end ='')
            print ('\n')
    def body(w_, h_, c_, c_len_):
        for x in range(h_-2):
            print (c_, end = '')
            for x in range(w_-2):
                print(' ' * c_len_, end = '')
            print (c_)

    topbot(w, c)
    body(w, h, c, c_len)
    topbot(w, c)

#begins draw    
draw(userw, userh, userc, userc_len)   

The problem begins when the draw function tries to begin with the arguments of userw, userh, userc, userc_len, but can't find them:

NameError: name 'userw' is not defined

is returned when I try to run it.

  1. Is it correct to define topbot and body within the draw function and manage the arguments how I did?
  2. How do I return the four variables from ask in a manner such that draw can then use them as arguments?
jep
  • 13
  • 4
  • I don't understand why you thought `draw(ask(userw), ask(userh), ask(userc), ask(userc_len))` would work; `ask` doesn't take any arguments, why would you want to call it four times, and how could e.g. `userw` possibly be defined at that point? Instead you want to call it *once* and get all four returned values, e.g. `userw, userh, userc, userc_len = ask()`, or just pass them straight to `draw`: `draw(*ask())` (see http://stackoverflow.com/q/36901/3001761). – jonrsharpe Jun 18 '16 at 06:41
  • I didn't, I just used that to illustrate what I want to do. – jep Jun 18 '16 at 06:45
  • So that's not even your actual code? Please give a [mcve]. – jonrsharpe Jun 18 '16 at 06:46
  • I did it that way because I don't know what code to use, but I've edited it. Hopefully that makes it more clear what I want to do and what I'm asking about. – jep Jun 18 '16 at 06:56
  • is there really any need to be passing around `c_len`? Since the string doesn't change, it might be more clear to just use `len(c)` – juanpa.arrivillaga Jun 18 '16 at 07:27
  • you're right, I made a variable for len(c) to keep myself organized but in hindsight it does just make things more compilctaed – jep Jun 18 '16 at 07:39

2 Answers2

1

ask() is a function which will return 4 values. So,

returnValues = ask()
draw = draw(*returnValues) 
or simply, draw = draw(*ask())

Also, end = ' ' is not correct. Instead of that you can just use print(c_,''). Include Validations wherever necessary. Like what if I type "hi" for "How wide?". In this case the program should tell me that this is wrong.

Srinath
  • 26
  • 2
  • @jep Just for the sake of clarity, `returnValues` will be a tuple, something like (4,5,'o',1), so you could have used `draw = draw(returnValues[0], returnValues[1], returnValues[2], returnValues[3])` however, using the `*returnValues` is certainly nicer and obviously more extensible. It is known as the "splat operator" for variable unpacking. – juanpa.arrivillaga Jun 18 '16 at 07:25
1

I was able to get draw() to accept the inputs from your ask() function (in Python IDLE) just by changing the last line of your code to this:

draw(*ask())

The * will unpack the variables from the ask() call and pass that along to draw(). The output looks kind of funny, and I'm not sure whether that's what you're looking for or not, but at least it got the variables in there correctly.

coralvanda
  • 6,431
  • 2
  • 15
  • 25