Sunday, June 12, 2016

Driving Python function execution from a text file

By Vasudev Ram

Beagle Voyage image attribution

Dynamic and adaptive systems are interesting, since they are more flexible with respect to their environment. Python itself is a dynamic language. Here is a technique which can make Python programs even more dynamic or adaptive.

This post shows a simple technique for driving or dynamically configuring, via an external text file, which specific functions (out of some possible ones), get executed in a program. As such, you can consider it as a sort of configuration technique [1] for externally configuring the behavior of programs, at run time, without needing to change their source code each time.

[1] There are, of course, many other configuration techniques, some of which are more powerful. But this one is very easy, since it only needs a dict and a text file.

Here is the code for the program,
# Driving Python function execution from a text file.
# Author: Vasudev Ram: 
# Copyright 2016 Vasudev Ram

def square(n): return n * n
def cube(n): return n * square(n)
def fourth(n):  return square(square(n))

# 1) Define the fns dict literally ...
#fns = {'square': square, 'cube': cube, 'fourth': fourth}
# 2a) ... or programmatically with a dict comprehension ...
fns = { fn.func_name : fn for fn in (square, cube, fourth) }
# OR:
# 2b) 
# fns = { fn.__name__ : fn for fn in (square, cube, fourth) }
# The latter approach (2a or 2b) scales better with more functions, 
# and reduces the chance of typos in the function names.

with open('functions.txt') as fil:
    for line in fil:
        line = line[:-1] 
        if line.lower() not in fns:
            print "Skipping invalid function name:", line
        for item in range(1, 5):
            print 'item: ' + str(item) + ' : ' + line + \
            '(' + str(item) + ') : ' + str(fns[line](item)).rjust(3)
And here is an example text file used to drive the program, functions.txt:
$ type functions.txt
Running the program with:
gives this output:
$ python

item: 1 : fourth(1) :   1
item: 2 : fourth(2) :  16
item: 3 : fourth(3) :  81
item: 4 : fourth(4) : 256

item: 1 : cube(1) :   1
item: 2 : cube(2) :   8
item: 3 : cube(3) :  27
item: 4 : cube(4) :  64

Skipping invalid function name: fourth_power
The map image at the top of the post, is of the Voyage of the Beagle, the ship in which Charles Darwin made his expedition. His book, On the Origin of Species, "is considered to be the foundation of evolutionary biology", and "Darwin's concept of evolutionary adaptation through natural selection became central to modern evolutionary theory, and it has now become the unifying concept of the life sciences.".

Note to my readers: In my next post, I'll continue on the topic of randomness, which I started on in this post:

The many uses of randomness.

- Vasudev Ram - Online Python training and consulting

Signup to hear about my new courses and products.

My Python posts     Subscribe to my blog by email

My ActiveState recipes

No comments: