Global and non-local variables.
If we define a variable ( define in Python means the first time when we use the variable by assigning it some value ) outside a function then it is a global variable and we can access it from a function also.
Ex:
var1 = "Testing"
def foo():
print("var1 inside :", var1)
foo()
print("var1 outside:", var1)
Output:
[amittal@hills Global]$ python3 g1.py
var1 inside : Testing
var1 outside: Testing
We can see that the function "foo" can print the variable "var1". However if we try to change the value inside the function then we run into a problem.
Ex:
var1 = "Testing"
def foo():
var1 = var1 + "Some"
print("var1 inside :", var1)
foo()
print("var1 outside:", var1)
Output:
Traceback (most recent call last):
File "g2.py", line 13, in <module>
foo()
File "g2.py", line 10, in foo
var1 = var1 + "Some"
UnboundLocalError: local variable 'var1' referenced before assignment
Now Python thinks that you are trying to change the value of "var1" and treats it like a local variable and states that you haven't assigned anything to the local variable "var1" . We can use the variable but not change the value.
Ex:
var1 = "Testing"
def foo():
var2 = var1 + "Some"
print("var2 inside :", var2)
print("var1 inside :", var1)
foo()
print("var1 outside:", var1)
Output:
[amittal@hills Global]$ python3 g3.py
var2 inside : TestingSome
var1 inside : Testing
var1 outside: Testing
In the above the global variable value is used for "var1" . However we can assign and change the value of "var1" directly inside a function.
Ex:
var1 = "Testing"
def foo():
var1 = " the function."
print("var1 inside :", var1)
foo()
print("var1 outside:", var1)
Output:
[amittal@hills Global]$ python3 g1a.py
var1 inside : the function.
var1 outside: Testing
We changed the value of "var1" and now Python treats it like a local variable We can see fro the output that the global variable value did not get changed.
Ex:
var1 = "Testing"
def foo():
var2 = "var2 Inside the function."
var1 = "var1 Inside the function."
print("var2 inside :", var2)
print("var1 inside :", var1)
foo()
print("var1 outside:", var1)
print("var2 outside:", var2)
Output:
[amittal@hills Global]$ python3 g4.py
var2 inside : var2 Inside the function.
var1 inside : var1 Inside the function.
var1 outside: Testing
Traceback (most recent call last):
File "g4.py", line 19, in <module>
print("var2 outside:", var2)
NameError: name 'var2' is not defined
Now we assigned something to "var1" inside the function. Python thinks of "var1" as a local variable. We can see that after the execution of "foo()" the value of the global variable "var1" did not change.
We saw how the statement
var1 = var1 + "Some"
caused confusion in the previous example. Since we are assigning something to "var1" Python thinks of it as a local variable but then the right hand side is using "var1" and that means that it hasn't been assigned a value yet. To tell Python explicitly that we mean "var1" to be global we can use the "global" keyword and avoid the confusion.
Ex:
var1 = "Testing"
def foo():
global var1
var1 = "var1 Inside the function."
print("var1 inside :", var1)
foo()
print("var1 outside:", var1)
Output:
[amittal@hills Global]$ python3 g5.py
var1 inside : var1 Inside the function.
var1 outside: var1 Inside the function.
Now the global "var1" has been changed.
Similarly:
Ex:
var1 = "Testing"
def foo():
global var1
var1 = var1 + " Some"
print("var1 inside :", var1)
foo()
print("var1 outside:", var1)
Output:
[amittal@hills Global]$ python3 g6.py
var1 inside : Testing Some
var1 outside: Testing Some
Non-Local Variables
There are certain scenarios when a variable can't be thought of as global or local.
Ex:
def outer():
x1 = "local"
def inner():
#nonlocal x
x1 = "nonlocal"
print("inner:", x1)
inner()
print("outer:", x1)
outer()
Output:
[amittal@hills Global]$ python3 nl1.py
inner: nonlocal
outer: local
In the above example we have a function "outer" that has another function defined in it. The outer function has a variable "x1" but how does the inner function look at this variable ? It is not global . If we assign a value to x1 in the inner function then that does not make a difference to the outer variable. We can use the keyword "nonlocal" to refer to the outer variable.
Ex:
def outer():
x1 = "local"
def inner():
nonlocal x1
x1 = "nonlocal"
print("inner:", x1)
inner()
print("outer:", x1)
outer()
Output:
[amittal@hills Global]$ python3 nl2.py
inner: nonlocal
outer: nonlocal
Functions
We use functions to organize and partition our code.
Ex:
def my_function():
print("Inside the my_function")
#Calling afunction
my_function()
Output:
[amittal@hills Functions]$ python3 func1.py
Inside the my_function
[amittal@hills Functions]$
We use the keyword "def" to define our function. Let us rewrite the code to find out if a number is prime using functions.
Ex:
import math
def isNoPrime( number1 ) :
isPrime = True
for x1 in range( 2, int(math.sqrt(no1)+1) ) :
if no1 % x1 == 0 :
isPrime = False
break
return isPrime
no1 = int( input( "Enter a number.") )
if isNoPrime( no1 ) :
print( "Number is Prime" )
else :
print( "Number is not Prime" )
Output:
[amittal@hills Functions]$ python3 prime1.py
Enter a number.22
Number is not Prime
We can also have arguments in functions take default values. That is if we don't call the function with the value of the argument then the default value is taken on by the argument.
Ex:
def my_function(str1 = "Some default value"):
print( str1 )
#Calling a function
my_function()
my_function( "Some argument" )
Output:
[amittal@hills Functions]$ python3 default1.py
Some default value
Some argument
Ex:
def my_function( str2 , str1 = "Some default value" ):
print(str2, str1 )
#Calling a function
my_function( "Some argument" )
Output:
[amittal@hills Functions]$ python3 default2.py
Some argument Some default value
Error Handling
Procedural languages handled errors by checking the return value of functions. The general scheme was:
int result;
result = function1() ;
//check values of result
result = function2() ;
//check values of result
Object oriented languages adapt a different approach.
try
{
//All the code that may throw an exception
}
catch( Exception )
{
//Write error handling code here.
}
We write all the code that may have an error in the "try" block and then if there is an error the function will throw it and we will "catch" it in the catch block .
Ex:
try:
x2 = int( input( "Enter a number.") )
x1 = 5 / x2
except:
print( "Encountered Exception." )
else:
print( "Did not encounter an error." )
finally:
print( "Inside the finally block." )
Output:
[amittal@hills Exceptions]$ python3 try1.py
Enter a number.0
Encountered Exception.
Inside the finally block.
[amittal@hills Exceptions]$ python3 try1.py
Enter a number.4
Did not encounter an error.
Inside the finally block.
Pass statement
The "pass" is an empty statement that does nothing.
1)
Write code to determine if a number that the user inputs is a prime number or not.
2)
Use a function to determine if the number is prime.
3)
Use exception handling mechanism to handle invalid inputs in the function for the program that was written in exercise 2 .
1)
import math
no1 = int( input( "Enter a number.") )
# %
isPrime = True
for x1 in range( 2, int(math.sqrt(no1)+1) ) :
if no1 % x1 == 0 :
isPrime = False
break
if isPrime :
print( "Number is Prime" )
else :
print( "Number is not Prime" )
#print if no1 is prime o
2)
import math
def isNoPrime( number1 ) :
isPrime = True
for x1 in range( 2, int(math.sqrt(no1)+1) ) :
if no1 % x1 == 0 :
isPrime = False
break
return isPrime
no1 = int( input( "Enter a number.") )
if isNoPrime( no1 ) :
print( "Number is Prime" )
else :
print( "Number is not Prime" )
3)
import math
def isNoPrime( number1 ) :
#print( "Inside isNoPrime." )
if number1 <= 0 :
raise Exception( "Input less than 0." )
#print( "Inside isNoPrime1." )
isPrime = True
for x1 in range( 2, int(math.sqrt(no1)+1) ) :
if ( no1 % x1 == 0 ) :
isPrime = False
break
#print( "Inside isNoPrime2." )
return isPrime
while( True ) :
try:
no1 = int( input( "Enter a number.") )
if isNoPrime( no1 ) :
print( "Number is Prime" )
else :
print( "Number is not Prime" )
break
except:
print( "Entry is not valid." )