So far, we have covered the main programming structures used in Python. We will now put that together in a script which can be run on demand.
Spyder is an application where you can edit and run your Python scripts. As part of Anaconda, there are a large number of scientific packages which come pre-installed, to make it easier for scientists getting started in programming.
We will run through a brief overview of the panels:
python
in a terminal window)In Spyder, a new file is created when you first open the application. This is called temp.py.
print("Hello World")
OK
runfile('D:/Projects/Python-tutorial/examples/hello.py', wdir='D:/Projects/Python-tutorial/examples')
Hello World
Recall that it is useful to group code into methods so replace the code with:
def hello():
"""Print "Hello World" and return None"""
print("Hello World")
# main program starts here
hello()
hello()
, what will happen if we just type hello()
in the console?We will now use a library as we did in previous lessons. Take note of the order.
import
statement goes at the toptry this example:
import math
def hello():
"""Print "Hello World" and return None"""
print("Hello World")
def get_pi():
"""Get value of pi"""
return math.pi
# main program starts here
hello()
print('pi is', get_pi())
After running this script, you can type
help(math)
in the IPython console - just as we did in Jupyter but it has to be loaded withimport math
first
Before we move on, there is an extra line recommended when running the script from outside this environment:
if __name__ == '__main__':
Insert this line above hello()
then indent the following code:
# main program starts here
if __name__ == '__main__':
hello()
print('pi is', get_pi())
This allows us to run from a terminal window:
python hello.py
So how would we make this script more dynamic?
We will change the hello()
method to take a variable name
.
def hello(name):
"""Print "Hello " and a name and return None"""
print("Hello", name)
...
hello("Josephine")
After running the script, in the IPython console, type
hello("Napoleon")
or any other name
Change the call function to loop over a few names (your first spamming script!).
But these are still variables defined in the script, how do we pass variables in from the command line?
There is a library called sys
which allows your script to read from the system in which it is running. Variables passed in are called arguments
and are strings which are stored in a list called sys.argv
In a new script called sysargs.py, type:
import sys
# main program starts here
if __name__ == '__main__':
program = sys.argv[0]
print("Program running is:", program)
Only one argument is present and that is the name of the program which is running - this will always be the case. We will now include two extra arguments so add some extra lines to the code:
import sys
# main program starts here
if __name__ == '__main__':
program = sys.argv[0]
print("Program running is:", program)
#Now check for extra arguments
if (len(sys.argv) == 3):
argument1 = sys.argv[1]
argument2 = sys.argv[2]
print("Arguments:", argument1, argument2)
python sysargs.py hello world
Return to your hello.py
script and allow the name to be entered as an argument
import sys
import re
def hello(name):
"""Print "Hello " and a name and return None"""
print("Hello", name)
def valid(name):
'''Only words with characters, underscores or hyphens are valid'''
# Provide a validity check to ensure bad stuff is not passed in
# Introducing a new library called `re`
match = re.match(r'^[A-Za-z0-9_\-]+$', name)
if (match):
isvalid = True
else:
isvalid = False
return isvalid
# main program starts here
if __name__ == '__main__':
randomname = None #ensure that this variable is clean to start
if (len(sys.argv) > 1): #test whether any arguments have been passed in
randomname = sys.argv[1]
# Check that name is a valid string
if (randomname is not None and valid(randomname)):
hello(randomname)
else:
print("No name passed in")
WARNING!! Allowing information to be passed into your script this way can be DANGEROUS. The
argv
array should never be read directly without checking the validity of the contents first.
To help you with checking that nothing malicious is passed into your script, use a library called argparse
.
The argparse
module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse
will figure out how to parse those out of sys.argv
. The argparse
module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.
We will update the previous script:
import argparse
import re
def hello(name):
"""Print "Hello " and a name and return None"""
print("Hello", name)
def valid(name):
'''Only words with characters, underscores or hyphens are valid'''
# Provide a validity check to ensure bad stuff is not passed in
# Introducing a new library called `re`
match = re.match(r'^[A-Za-z0-9_\-]+$', name)
if (match):
isvalid = True
else:
isvalid = False
return isvalid
# main program starts here
if __name__ == '__main__':
#Setup the argument parser class
parser = argparse.ArgumentParser(prog='Hello program',
description='''\
Reads a name and says hello
''')
#We use the optional switch -- otherwise it is mandatory
parser.add_argument('--randomname', action='store', help='A name', default="Josephine")
#Run the argument parser
args = parser.parse_args()
#Extract our value or default
randomname = args.randomname
# Check that name is a valid string
if (randomname is not None and valid(randomname)):
hello(randomname)
else:
print("No name passed in")
--randomname Napoleon
, ‘OK’We will now move onto the next lesson Handling errors