1

I've written a program that performs some complex tasks. I thought the best way to make sure my code is neat and concise was to define multiple functions. Unfortunately, by doing this, I have come across a problem where I am having to return multiple values from various functions for use in other functions and am getting tripped up by it all.

Here is essentially my program but simplified, paste it in IDLE and it should work for you.

def function_zero():
    a = ['1', '2', '3']
    b = ['4', '5', '6']
    c = ['0']
    d = ['0']
    return a, b, c, d

def function_one(a):
    for i in a:
        function_two(i)
#   m, l = function_two(i)    

def function_two(i):
    morel = []
    lessl = []
    sum_i = int(i)*2
    if sum_i >= 3:
        morel.append(i)
    if sum_i <= 3:
        lessl.append(i)
#   return m, l

def function_three(a, b, c, d):
#def function_three(a, b, c, d, m, l):
   print a, b, c, d
   #print m, l

def main():
    a, b, c, d = function_zero()
    function_one(a)
    function_three(a, b, c, d)
#   function_three(a, b, c, d, e, f)    

if __name__ == '__main__':
    main()

Function zero parses a report, generating values a, b and so on. Function one actually uses itertools and izip to merge a and b together, but for simplicity this is hidden. Essentially what this does is perform a command which requires two arguments, and it's important that these commands are done in iteration.

Function two introduces the main problem here, list objects l and m. I do not know where these should be initiated, if I initiate them outside the functions, it can become messy, so I've done it inside function two. I also have severe problems trying to print them in function three (Function three is a reporting function) due to NameError's and unresolved references.

Without having to rewrite the functions and making major modifications (this would mean I would have to rewrite my program if someone suggested a simpler way of doing this, and if I adopted it, it may mean that I lose functionality elsewhere). Can anyone tell me how I would sort of pass m and l which are initiated in function two, up to function one for them to be accessible in function three?

Any advice would be greatly appreciated, as you can see from the commented code - I have tried to fix the problem but I thought I would ask for some help before hacking away helplessly.

3
  • 2
    Could you give a minimal reproducible example with a less abstract set of functions? Commented Dec 11, 2016 at 23:46
  • You demonstrate how to pass variables around when you save references to the values returned by function_zero and when you call function_one with an argument of one of those references. Do something similar with function_two. Commented Dec 11, 2016 at 23:48
  • Instead of passing individual i to function_two pass the whole of a and return a partioned into m, l = function_two(a). It is unclear what you plan to do with those partitioned values. BTW there is an itertools recipe called partition() that might be useful. Commented Dec 11, 2016 at 23:56

2 Answers 2

1

I believe the answer below provides a solution to your problem. Please see that I wasn't able to find it possible to reference m and l because every time you wanted to print these values - only the last value would be printed. This is because your function_one overwrites it on each iteration. So I added two new values, n and o and these save the values returned by your function. It gets a bit messy in the end, but it works! You weren't far off with your commented out code, I think you just needed to spend a minute more debugging and you would have noticed the issue.

def function_zero():
    a = ['1', '2', '3']
    b = ['4', '5', '6']
    c = ['0']
    d = ['0']
    return a, b, c, d


def function_one(a):
    n = []
    o = []
    for ai in a:
        function_two(ai)
        m, l = function_two(ai)
        n.append(m)
        o.append(l)
    return m, l, n, o

def function_two(ai):
    m = []
    l = []
    sum_ai = int(ai)*2
    if sum_ai >= 3:
        m.append(ai)
    if sum_ai <= 3:
        l.append(ai)
    return m, l

def function_three(a, b, c, d, n, o):
    print a, b, c, d
    print n
    print o

def main():
    a, b, c, d = function_zero()
    m, l, n, o = function_one(a)
    function_three(a, b, c, d, n, o)


if __name__ == '__main__':
    main()
Sign up to request clarification or add additional context in comments.

Comments

1

I can see what you are trying to do, but maybe let me help you clarify some things around python and programming.

The way of programming should go:

  1. Define some variables
  2. Do something with those variables.
  3. Get a result.

Now if you keep following that you can go as deep as you like into writing a program. With yours what you want to do is:

  1. Define some variables (a,b,c,d)
  2. Send them to function 1 to do some stuff...
  3. Pass forward again some variables out of function 1 into function 2.
  4. Get a result from function 2 and store that in function 1.
  5. Get a result from function 1 and use that in your main() however you need.

I would look at defining your variables using a class, this acts as a data structure of sorts:

class variables:
    def __init__(self):
        '''
        Create a class, store some variables.
        '''
        self.a = ['1', '2', '3']
        self.b = ['4', '5', '6']
        self.c = ['0']
        self.d = ['0']

And then in your main using those variables with the functions:

def main():
    var = variables()
    result = function_one(var.a)
    # Do something with the results.

I think you might have been getting confused thinking that variables in one definition/method could be accessed globally by another method. This is not the case unless you specify global variables. And a method itself should always be something that you need to consistently repeat without too much dependency on something else. It should really just take some variables in and spit a result out. Don't try to interconnect too many methods - it gets messy.

I hope this helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.