Hi,
I am trying to do a simple task in Python but I keep getting error. I have a string stored in a variable and a simple GUI with a button (in 1st.py) which will call another function in a separate file (twond.py) which will split that string and store and return that in 1st.py

The function calling works fine. The function does the job of splitting the string and storing it. But when I ask to print in the main file (1st.py), it shows error global variable not defined. I have tried defining the variable global but it didn't work.

Can anyone help me with this?

Thank you

Here is the code:

#this is the main file 1st.py which has a string stored in variable s and a GUI function that calls the function
#
from Tkinter import *
import string, twond


class App:
    def __init__(self,master):
        frame = Frame(master.title("New Title"))
        frame.pack()
        self.bt=Button(frame, text='click', command=self.first)
        self.bt.grid(row=1, column=0)
    #global L    
    def first(self):
        s = 'this is a string'
        twond.second(str(s))  #this passes the variable s to the function second() in the file twond.py
        
        #print(L) 
        #if I uncomment this i get error message

root = Tk()

app = App(root)

root.mainloop()

#this is the file twond.py which splits the string s  and stores in variable L
#I am trying to make it to pass this variable L back to the main file 1st.py
import string

def second(s):
    global L
    L=string.split(s)
    
    print(s)
    
    print(L)

Why don't you def your function like

def second(s):
    str = string.split(s)
    return str

then you can print it like

print str(second(string))

Why don't you def your function like

def second(s):
    str = string.split(s)
    return str

then you can print it like

print str(second(string))

Thanks Gerard for your reply. I am not sure what are you trying to do. Anyway, I have tried that but it gets error.
My aim is not just to print it in the main file. I am trying to access this variable from the main file 1st.py

Oh I see

import string
global L

def second(s):
    global L
    L=string.split(s)
     print(s)
     print(L)

Then refer to it(after you import it into the main app) like
twond.L

Oh I see

import string
global L

def second(s):
    global L
    L=string.split(s)
     print(s)
     print(L)

Then refer to it(after you import it into the main app) like
twond.L

Defining the variable as Global before the function wouldn't work either. There needs to be a way to pass the variable back onto the main function. I have no idea how...Running out of ideas

Why don't you def your function like

def second(s):
    str = string.split(s)
    return str

then you can print it like

print str(second(string))

I don't understand the problem : if you do like this, you can call the function from the other file doing :
print str(twond.second(string))
and it will work, no ?

I don't understand the problem : if you do like this, you can call the function from the other file doing :
print str(twond.second(string))
and it will work, no ?

No, it would not work. I have tried that. it will come up with an AttributeError.

If there was a way to pass variables from a called function to the main calling function, that will solve the problem.

For example:
Function1 (pass variable a to)--> Function2 (pass variable b to)-->Function1

where Function1 is the main calling function in file named firstfile.py
Function2 is the called function in file named secondfile.py

Ok, I put the whole code down :
Here is what I was saying :
I have written 2 files
1st.py and twond.py

#this is the main file 1st.py which has a string stored in variable s and a GUI function that calls the function
#
from Tkinter import *
import twond


class App:
    def __init__(self,master):
        frame = Frame(master.title("New Title"))
        frame.pack()
        self.bt=Button(frame, text='click', command=self.first)
        self.bt.grid(row=1, column=0)
    #global L    
    def first(self):
        s = 'this is a string'
        splittedString=twond.second(str(s))  #this passes the variable s to the function second() in the file twond.py

        print(splittedString) 

root = Tk()
app = App(root)
root.mainloop()
#this is the file twond.py which splits the string s  and returns the splitted line
# import string : deprecated. Not to be used any more

def second(s):
    return s.split()

When I press the button, my console is displaying :

> ['this', 'is', 'a', 'string']

So, I don't understand what is going wrong with this. I certainly don't have any AttributeError.

Ok, I put the whole code down :
Here is what I was saying :
I have written 2 files
1st.py and twond.py

#this is the main file 1st.py which has a string stored in variable s and a GUI function that calls the function
#
from Tkinter import *
import twond


class App:
    def __init__(self,master):
        frame = Frame(master.title("New Title"))
        frame.pack()
        self.bt=Button(frame, text='click', command=self.first)
        self.bt.grid(row=1, column=0)
    #global L    
    def first(self):
        s = 'this is a string'
        splittedString=twond.second(str(s))  #this passes the variable s to the function second() in the file twond.py

        print(splittedString) 

root = Tk()
app = App(root)
root.mainloop()
#this is the file twond.py which splits the string s  and returns the splitted line
# import string : deprecated. Not to be used any more

def second(s):
    return s.split()

When I press the button, my console is displaying :

> ['this', 'is', 'a', 'string']

So, I don't understand what is going wrong with this. I certainly don't have any AttributeError.

Yea this seems to be working. What I meant was:
in

def second(s):
    return s.split()

if you specify the s.split() as a new variable. the main function will give an error if it tried to receive this new variable.
I am trying to avoid this and pass variable for the def second(s) to main function without any problem so when I have lots of variable in def second(...) I can easily pass them in the main function.

Thanks for your help, I will check it again and let you know if what you suggested works for me.

Cheers

The only variables you can use in the calling program are the returned variables (you can use a intermediate variable in the function but you MUST return it to use it in the main program).

Except if you embed your second function in a class (which is the base of Object Programming :

#this is the file twond.py which splits the string s  and returns the splitted line
class twond:
    def second(self, s):
        self.splittedString=s.split()

Then in your 1st file, you can do

#this is the main file 1st.py which has a string stored in variable s and a GUI function that calls the function
#
from Tkinter import *
import twond


class App:
    def __init__(self,master):
        frame = Frame(master.title("New Title"))
        frame.pack()
        self.bt=Button(frame, text='click', command=self.first)
        self.bt.grid(row=1, column=0)
    #global L    
    def first(self):
        s = 'this is a string'
        t=twond.twond()
        t.second(str(s))  #this passes the variable s to the twond object second() method

        print(t.splittedString) 

root = Tk()
app = App(root)
root.mainloop()

In this example, this wouldn't be a very good design : it's not a good habit to access object attributes directly (better to define a setAttribute and a getAttribute in the twond object to manipulate the attribute).

Another thing you can look at in gui design is "callback" : you pass a function as a parameter to another function so that you can call the first function from the second one... Very useful to avoid nested imports.
I won't develop this more here but you can google "callback" and you'll have informations about that.

The only variables you can use in the calling program are the returned variables (you can use a intermediate variable in the function but you MUST return it to use it in the main program).
Another thing you can look at in gui design is "callback" : you pass a function as a parameter to another function so that you can call the first function from the second one... Very useful to avoid nested imports.

Hmm.. I sort of understand what you mean. But I am still confused with the returning variables.
Let me make it clear with numbers rather than strings.

In the Gui, I have quite a few entry boxes where numbers can be given as inputs. Then it passes those numbers as variables to the second function in twond.py and does calculations using the numbers. A simple example,

Input Temperature in Celcius in Main function in 1st.py file passed on as variable C.
Second function in file twond.py will convert that to Fahrenheit and store in variable F. Now this should be passed back of to main function in 1st.py file.
So when i command print(F) in the main file, it prints the output in Fahrenheit. So now I can use this Fahrenheit and play with this variable.

Main file:
Input: C = 25 (in the entry box)
get F from the second function in twond.py where the equation to convert C to F is.
print (F) : 77
variable A = F+5%
print(A): 80.85

This is what I want to achieve but failing to do pass the new variable back to the main file.

Cheers for all your help. I am looking into the things you suggested.

Input Temperature in Celcius in Main function in 1st.py file passed on as variable C.

so you call, in your Main function

def Main():
    C=int(input("°C ?"))
    F=twond.CelciusToFarenheit(C) # Here, the returned value is stored in F
        # But this F has nothing to do with any F you'll see in the second function (same name but different variables)
        # You'll see later...

Second function in file twond.py will convert that to Fahrenheit and store in variable F.

This is where you have to concentrate ;-)
The Main function doesn't care about where the second function (let's say CelciusToFarenheit) stores its intermediates values.
It only cares about what is returned

def CelciusToFarenheit(C):
    F=1,8C+32 # Main() won't see this F whatever you do
    return F # This will return the value to the calling function (here Main). It returns a Value.
        # It is called F here but it could be called anyway the result would be exactly the same

Now this should be passed back of to main function in 1st.py file.
So when i command print(F) in the main file, it prints the output in Fahrenheit. So now I can use this Fahrenheit and play with this variable.

Let's complete the Main function

def Main():
    C=int(input("°C ?"))
    F=twond.CelciusToFarenheit(C)
    print (F)
    # play with F as much as you want. As soon as the returned value is stored in a variable, it can be used.
    A=F*1.05
    print (A)
commented: Very helpful +1

so you call, in your Main function

def Main():
    C=int(input("°C ?"))
    F=twond.CelciusToFarenheit(C) # Here, the returned value is stored in F
        # But this F has nothing to do with any F you'll see in the second function (same name but different variables)
        # You'll see later...

Yea I get what you did here.

This is where you have to concentrate ;-)
The Main function doesn't care about where the second function (let's say CelciusToFarenheit) stores its intermediates values.
It only cares about what is returned

def CelciusToFarenheit(C):
    F=1,8C+32 # Main() won't see this F whatever you do
    return F # This will return the value to the calling function (here Main). It returns a Value.
        # It is called F here but it could be called anyway the result would be exactly the same

Let's complete the Main function

def Main():
    C=int(input("°C ?"))
    F=twond.CelciusToFarenheit(C)
    print (F)
    # play with F as much as you want. As soon as the returned value is stored in a variable, it can be used.
    A=F*1.05
    print (A)

This is what I finally wanted to do:

from Tkinter import *
import twond

class App:
    def __init__(self,master):
        frame = Frame(master.title("New Title"))
        frame.pack()
        self.bt=Button(frame, text='click', command=self.first)
        self.bt.grid(row=1, column=0)
        self.entry=Entry(frame)
        self.entry.grid(row=1, column=1)
        self.entry2=Entry(frame)
        self.entry2.grid(row=1, column=2)
    #global L    
    def first(self):
        C = float(self.entry.get())
        D = float(self.entry2.get())
        A=twond.second(C, D)  #this will store the returned value

        print(A)     
        
        F = A[0]
        P = A[1]

        Final = F+P 
        print(Final)

root = Tk()
app = App(root)
root.mainloop()

This is the main function
And the second function:

def second(C,D):
    F = C*1.8+32
    P = (F*D)/100
    #print(F)
    #print(P)
    return F, P

Now it can receive the returned variable like in an array but thats alright as I can then reinitialise the variable.
So fro example in the 2 entry boxes I put 30 C and percentage 5
the output:

print(A)
(86.0, 5.16000001)

where

F =A[0] = 86.0
P =A[1] = 5.16000001

THis is what I wanted for now.

Thank you very much man. You are a legend.

Regards,

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.