You have a number of programs which need to be run in a sequence. You need an easier programming environment than a shell to control the flow. Python is widely used for utilities programming, graphical front-ends for Linux command line scripts by organisations like Fedora and Ubuntu. Python has an excellent set of built-in modules for interfacing with the OS and the system. So, start the python interpreter and get a list of modules available:
Spend a few minutes looking at the long list of modules you can use. You should notice that there are two modules with names which remind us of the work we need to do - 'os' and 'sys'. You will want to know what each of these modules does. So, try:
The os module provides os dependent functions for managing files, directories and execution of programs. The first method you can try is 'system'.
>>> import os
>>> error = os.system('OpenOffice')
sh: openoffice: command not found
>>> print error
You realise that the command for starting open office is ooffice (works on Fedora and Ubuntu) or soffice depending upon distribution/installation. So, try again but make sure that you close ooffice if you are using it:
>>> error = os.system('ooffice')
>>> print error
Open office starts but the control does not go back to the Python program. You will notice that the print statement is executed only after you have closed open office. You need to keep the open office started and running in the background. An easy option is that we can use the option '&' to run the program in the background. So, try:
>>> error = os.system('ooffice &')
>>> print error
This time open office starts up and the print statement is executed. You can work in both applications. There remains a slight hitch. You may wish to stop the program. You need to spawn another program and have control over it. You can have a look at the spawnlp method and that seems appropriate. It takes a 'no wait' option and returns the process id. So, try:
Just to make sure that you have the process id, try:
>>> pid=os.spawnlp(os.P_NOWAIT, 'ooffice')
>>> print pid
Open office should close.
Now you can explore the 'sys' module. Two items will be useful from this module. The exit method and the list, argv, which contains the command line parameters passed to the python program. Write the following code in test_params.py:
for param in sys.argv:
print 'Parameter = ', param
Now, from the command line, run
$ python test_params.py loans_v2.py
Parameter = test_params.py
Parameter = loans_v2.py
Notice that the first parameter is the name of the python script and the other parameters follow. From the command line, try:
You will find that the editor starts and opens the test_params.py file. So, you can try the same thing from Python:
$ gedit test_params.py
>>> p= os.spawnlp(os.P_NOWAIT,'gedit', 'test_params.py')
>>> print p
The editor starts but does not open the file. As we had noticed above, Linux expects the first parameter to be the identifier of the application. So, you can pass one additional parameter as follows:
>>> p= os.spawnlp(os.P_NOWAIT,'gedit','gedit', 'test_params.py')
>>> print p
The editor has opened the file as expected.
You now have the basic tools at your disposal to start integrating the various tasks from last month's programs. You can start creating a file, workflow.py:
Now, try running this program from the command line:
$ python workflow.py
File "db2oo.py", line 18, in <module>
calc = oo_calc()
File ".... open_office.py", line 14, in oo_calc
open_office.NoConnectException: Connector : couldn't connect to socket (Success)
You get an error. A little experimentation will lead you to the conclusion that the open office program has started but is not yet ready for accepting connections. So, you will need to wait before starting the rest of the script. You should revise your workflow.py as follows:
# Start Open Office in background mode
print 'Open Office started. Wait a few seconds to connect'
print "Load Data from db"
# stop background copies of soffice & soffice.bin
# Manually edit the spreadsheet
print "Store data back in db"
# Clean up
You need to run the open office in background twice. So, convert it into a function. A second point to note is that the command ooffice starts 2 programs – soffice and soffice.bin. The pid is of the first. Unfortunately, the second one is not killed if you have run open office in the background mode and you kill the first one. A simple solution is to use the pkill command as above. By the way, you can leave out the '-invisible' option while developing and testing.
A well-written program should not depend on hard-coded file names. So, you should accept command line variables. The files needed are the friends and items databases and the temporary spreadsheets workbook. Typically, Linux utilities use the pattern '-o value'. You may decide to use '-i' for items, '-f' for friends and '-w' for workbook. So, create a file test_params.py:
print 'The number of arguments',len(sys.argv)
print 'The script name',sys.argv
while index < len(sys.argv):
if sys.argv[index] == '-i':
items_db = sys.argv[index + 1]
print 'Items ', items_db
elif sys.argv[index] == '-f':
friends_db = sys.argv[index + 1]
print 'Friends ', friends_db
elif sys.argv[index] == '-w':
workbook = sys.argv[index + 1]
print 'Workbook ', workbook
print "Syntax Error ", sys.argv[index]
index += 2
You should now execute this script, e.g.
$python test_params.py -i items.db
$python test_params.py -i items.db -w workbook.ods
$python test_params.py -f friends.db -w workbook.ods -i items.db
This script should now be integrated with the workflow.py. Since it will require changes in the code from the last month's article and is not difficult, you can do this as an exercise.
A second exercise worth doing is that you need not restrict yourself to just command line parameters. If the parameters have not been given, you could bring up a tkinter form as discussed in an earlier article. You can type the following in tk_params.py and expand it :
root = Tkinter.Tk()
items_db = tkFileDialog.askopenfilename(
title='Please select Items DB')
workbook = tkFileDialog.asksaveasfilename(
title='Please select Worksheet Name')
return items_db, workbook
In the case of items_db, the file must exist; so, askopenfilename is the useful method. In the case of workbook, if the file exists a warning that an existing file will be overwritten is useful; hence, asksaveasfilename is the appropriate method.
As you have tried, it is easy to add existing widgets and quickly capture desired parameters conveniently. The hardest part of using tk widgets is finding the documentation for using them!
The best place to learn more about various Python modules is by using the python docs – http://docs.python.org/. Usage of widgets is best explored by using Google.
You may well think that the world is moving to Web2.0 so what's the point of continuing with pre-web programming. So, next time you will explore how to web-enable your application for keeping track of your loaned items.
Python For Friends >