Solved

Python 3.4  - passing variable from one function to another - Global variable

Posted on 2014-12-04
10
303 Views
Last Modified: 2014-12-07
I have two functions - one feeds the other. The functions are
def TWODim(Original):

and

def ONEinsertion(Original):

TWODim  SHOULD feed a two dimensional list (Original) to the ONEinsertion function but does not appear to do so. I feel I should be using the global variable approach within the TWODim function, but am not sure how to do this. This is how the function currently looks

def TWODim(Original):
      newlist = []
      for i in Original:
            while len(Original) != 0:
                  newlist.append(Original[0:2])
                  Original = Original[2:]
      Original = newlist
      return Original


Could someone take a look and let me know the problem ?

Many thanks for your help
test-ONEinsertion.py
0
Comment
Question by:jameskane
  • 5
  • 4
10 Comments
 
LVL 20

Expert Comment

by:Mark Brady
ID: 40482049
Can you post what is in "Original". Post an example of it.

It looks like you are looping Original but inside the loop you are changing Original to a new value . #Original = Original[2:]
Not the best idea when you are in a loop to change the object you are looping.

What exactly are you trying to out at the end of the function? If you can post an example of the Original value going into the function and an example of what you want to have returned I will help you write a function to do it.
0
 
LVL 25

Expert Comment

by:clockwatcher
ID: 40482133
There's very little reason to ever use a global variable and while it's not clear what you're trying to achieve here, it's pretty definite that you don't want to be using one here.

Your TWODim function breaks up a one dimensional list into a two dimensional (list of two element length lists).   In other words, given this:

(1, 2, 3, 4, 5, 6, 7, 8)

It returns this:

((1,2), (3,4), (5,6), (7,8))
>>> from test1 import TWODim
>>> print TWODim((1,2,3,4,5,6,7,8))
[(1, 2), (3, 4), (5, 6), (7, 8)]

Open in new window


If you think it's doing something other than that or its returning something different you'll need to post more of your code so we have an idea of what you're trying to do and where things are going wrong.  But that's what that function does and what it returns.
0
 

Author Comment

by:jameskane
ID: 40482469
Whooh !!!  very many thanks for taking an interest in this !

Here is an example of what I am doing. I start of (for example) with a list ]['6','12','45', '23','8','32','5','5'] and transform it eventually to [[1, 6, 12], [1, 45, 23], [1, 8, 32], [1, 5, 5]]. I did this in three stages with the three .PY files attached. The example input and outputs are hard wired into the .py files. This is shown graphically below.

['6','12','45', '23','8','32','5','5']
!
!------------------------------------------------------>test-invertc-ellimination.py
v
[6, 12, 45, 23, 8, 32, 5, 5]
!
!------------------------------------------------------>test-create2D.py
v
[[6, 12], [45, 23], [8, 32], [5, 5]]
!
!----------------------------------------------------->test-ONEinsertion.py
v
[[1, 6, 12], [1, 45, 23], [1, 8, 32], [1, 5, 5]]

I could combine the 3 .py files into one, but what I really want to do is turn each of them into a function which I will call like
Function1(Original)
Function2(Original)
Function3(Original)

The output of Function 1 should drive Function2 and Function2 output should drive Function3.  I am unable to achieve this.... see my example in original posting of my attempt.

(footnote - the sum of the elements in the original list is always an even number)

Thanks for the help.
test-invertc-ellimination.py
test-create2D.py
test-ONEinsertion.py
0
 
LVL 25

Expert Comment

by:clockwatcher
ID: 40483201
You probably want to read up on functions and modules but basically you use import to pull in other python files/modules into your program.  So (changing the '-' character in your filenames to something more python friendly), what you're after looks like this:

test_invertc_elimination.py
def Function1(mylist):
    newlist = []
    for m in mylist:
        MC= int(m[:])
        newlist.append(MC)
    return newlist

Open in new window


test_Create2D.py
def Function2(Original):
    newlist = []
    while len(Original) != 0:
         newlist.append(Original[0:2])
         Original = Original[2:]
    return newlist

Open in new window


test_ONEinsertion.py
def Function3(Original):
    Original2 = Original[:]
    newlist=[]
    for i in Original2:
        temp = Original2[0]
        temp.insert(0,1)
        newlist.append(temp)
        Original2 = Original2[1:]
    return newlist

Open in new window


driver.py
import test_Create2D
import test_ONEinsertion
import test_invertc_elimination

def main():
    mylist = ['6','12','45', '23','8','32','5','5']
    print(mylist)
    integer_list = test_invertc_elimination.Function1(mylist)
    print(integer_list)
    twod_list = test_Create2D.Function2(integer_list)
    print(twod_list)
    inserted_list = test_ONEinsertion.Function3(twod_list)
    print(inserted_list)

if __name__ == '__main__':
    main()

Open in new window


You run the thing with:

    python driver.py
test-invertc-elimination.py
test-Create2D.py
test-ONEinsertion.py
driver.py
0
 
LVL 25

Expert Comment

by:clockwatcher
ID: 40483220
Weird... The experts-exchange upload changed the underscore in the filenames to a dash.  If you use the files, you'll need to change that back.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:jameskane
ID: 40484665
"Weird... The experts-exchange upload changed the underscore in the filenames to a dash.  If you use the files, you'll need to change that back."

even more weird, I only see underscores - no dashes at all !!

Thanks clockwatcher for  putting all this together.  I ran the Driver.PY  and it worked. Just modified it to take its input from outside. (note, I changed the names of my original py files to something more sensible !)

import Create2D
import ONEinsertion
import Kill_invert_cs
mylist = ['6','12','45', '23','8','32','5','5','9','5']
def main(mylist):
   print(mylist)
    integer_list = Kill_invert_cs.Function1(mylist)
    print(integer_list)
    twod_list = Create2D.Function2(integer_list)
    print(twod_list)
    inserted_list = ONEinsertion.Function3(twod_list)
    print(inserted_list)

#if __name__ == '__main__':
main(mylist)


Although it works, there is one thing I don't understand.  
- function 1 takes mylist as its argument and returns mylist. HOWEVER, function 2  takes 'Original' as its argument - why not 'mylist' -  which has been returned from  function 1 ?  I would not have expected that to work (but it does !)
- similarly function 3 takes 'Original' as its argument, although function 2 returns 'mylist '

I'm missing something here in my understanding.
0
 

Author Comment

by:jameskane
ID: 40484702
I am now trying to export this to my Apache server and run in cgi mode.  I use template.cgi for getting python stuff to run on the server. (uploaded it as .PY because the Expert Exchange system will not accept .CGI uploads.

I am also uploading OrderFormTHREE.py ( read as .cgi) with the functions and driver integrated into that template.

This should allow me to run the .PY (converted to cgi)  files on the Apache server.

However, I am getting the following error message :

Server error!

The server encountered an internal error and was unable to complete your request.

Error message:
End of script output before headers: OrderFormTHREE.cgi
If you think this is a server error, please contact the webmaster.
Error 500
localhost
Apache/2.4.10 (Win32) OpenSSL/1.0.1i PHP/5.5.15


Would you take a look to see if there are any obvious  errors ?

thanks again
template.py
OrderFormTHREE.py
0
 
LVL 25

Accepted Solution

by:
clockwatcher earned 500 total points
ID: 40484854
I'm not sure I understand your first question but I think you may be getting confused by the variable that you're passing to your function and the function parameter having the same name.   I think you may think they refer to the same thing because they have the same name or something.  Not exactly sure where your confusion is coming in.  But a function parameter's scope is local to the function.  So the following:
 
def plusone(n):
    n = n + 1
    return n

i = 1
n = 4
print(plusone(i))
print(n)
print(i)
print(plusone(n))
print(n)

Open in new window

should print:
2
4
1
5
4

Open in new window

What plusone knows as n is separate from what the main scope knows as n.  Not sure if that helps or just confuses you more.  Explaining variable storage and functional scope is much easier to do with a drawing rather than words or code examples.  

Glancing at OrderFormTHREE.cgi, you've got a few wacky things going on.  You said you renamed your programs but your imports still refer to the old names:

import test_Create2D
import test_ONEinsertion
import test_invertc_elimination

Your function calls look like they refer to the new names (but those wouldn't be available because you haven't imported those routines):

      Kill_invert_cs.Function1(mylist)
      Create2D.Function2(integer_list)
      ONEinsertion.Function3(twod_list)

And lastly, you've also defined the functions locally within OrderFormTHREE.  So not sure exactly what you're doing or trying to do.  But if you've got three files called (Kill_invert_cs.py, Create2D.py, and ONEinsertion.py) in the same folder as OrderFormTHREE.cgi (and you want to keep your functions in those files rather than in OrderFormTHREE), then OrderFormTHREE.cgi should probably look like this:
#!C:\Python34\python.exe
import cgi
import mysql.connector as conn
import Create2D
import ONEinsertion
import Kill_invert_cs

def htmlTop():
      print("""Content-type:text/html\n\n
             <!DOCTYPE html>
             <html lang="en">
                 <head>
                  <meta charset="utf-8"/>
                  <title> My Server-side template</title>
             </head>
             <body>""")

def htmlTail():
      print(""" its done</body>
             </html>""")
      
def connectDB():
      db=conn.connect(host='localhost' ,user='root' ,passwd='' ,db='pizza')
      cursor = db.cursor()
      return db, cursor

def getData():
      formData = cgi.FieldStorage()
      #dropSize = []
      dropSize = formData.getlist('drop')
      dropName = formData.getlist('drop')
      return dropSize, dropName

def main(mylist):
      print(mylist)
      integer_list = Kill_invert_cs.Function1(mylist)
      print(integer_list)
      twod_list = Create2D.Function2(integer_list)
      print(twod_list)
      inserted_list = ONEinsertion.Function3(twod_list)
      print(inserted_list)

#main program
if __name__== "__main__":
      try:
            htmlTop()
            xyz = getData()
            mylist=xyz[0]
            main(mylist)
            
            htmlTail()
      except:
            cgi.print_exception()

Open in new window

0
 

Author Closing Comment

by:jameskane
ID: 40485481
"but I think you may be getting confused by the variable that you're passing to your function and the function parameter having the same name." EXACTLY -  now I understand, the example you gave was very helpful.

The approach of importing the functions (.PY) and using the main(mylist)  function really  simplifies things - I can see how it facilitates re-using functions in different programs as well.

The code is working perfectly now ( added in another function as well !)

Thank again for the expertise, taking the time to explain and also for your patience with those dumb mistakes !!

james
0
 
LVL 25

Expert Comment

by:clockwatcher
ID: 40485572
Glad to have been able to help.  :-)
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Flask is a microframework for Python based on Werkzeug and Jinja 2. This requires you to have a good understanding of Python 2.7. Lets install Flask! To install Flask you can use a python repository for libraries tool called pip. Download this f…
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
Learn the basics of strings in Python: declaration, operations, indices, and slicing. Strings are declared with quotations; for example: s = "string": Strings are immutable.: Strings may be concatenated or multiplied using the addition and multiplic…
Learn the basics of lists in Python. Lists, as their name suggests, are a means for ordering and storing values. : Lists are declared using brackets; for example: t = [1, 2, 3]: Lists may contain a mix of data types; for example: t = ['string', 1, T…

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now