Showing posts with label dynamic-languages. Show all posts
Showing posts with label dynamic-languages. Show all posts

Sunday, December 23, 2018

Dynamic function creation at run time with Python's eval built-in

By Vasudev Ram



Hi, readers,

A few days ago, I had published this post:

Dynamic function creation at run time with Python's exec built-in

In today's post I'll show another way of dynamically creating functions at run time - this time using Python's eval built-in instead of exec.

I'll show the code (dyn_func_with_eval.py), followed by its output.
# dyn_func_with_eval.py 
# Purpose: To dynamically create (and run) a function at run time, 
# using Python's eval built-in.
# Author: Vasudev Ram
# Copyright 2018 Vasudev Ram
# Web site: https://vasudevram.github.io
# Product store: https://gumroad.com/vasudevram
# Twitter: https://twitter.com/vasudevram

from __future__ import print_function

expr = raw_input("Enter a function of x: ")
print("expr: ", expr)
g = eval("lambda x: " + expr)
print("g:", g)
print("g.func_code.co_argcount:", g.func_code.co_argcount)
print("g.func_code.co_varnames:", g.func_code.co_varnames)
print("g(0):", g(0))

old_gi = 0
for i in range(5):
    gi = g(i)
    diff = gi - old_gi
    print("i = {}, g({}) = {}, diff = {}".format(i, i, gi, diff))
    old_gi = gi
As you can see, after prefixing the expression (that was input by the user) with "lambda x: ", to make it a complete lambda function definition, the program uses eval() (instead of exec() like last time), to dynamically evaluate the entered expression (which should represent a function of x).

The end result is that the lambda function object is created and then bound to the name g. Then g is used in the remaining code.

The values of g and g(0) are printed.

Then, in a loop, g is evaluated for i ranging from 0 to 4. For each such value, i, g(i) and the difference between the old g(i) and the current one is printed. (No meaningful value can be given for the previous value of g(i) before g(0), so I used 0 arbitrarily; ignore that first difference).

Now, the output:
$ python dyn_func_with_eval.py
Enter a function of x: x * x + 2 * x + 1
expr:  x * x + 2 * x + 1
g: <function <lambda> at 0x022D0A70>
g.func_code.co_argcount: 1
g.func_code.co_varnames: ('x',)
g(0): 1
i = 0, g(0) = 1, diff = 1
i = 1, g(1) = 4, diff = 3
i = 2, g(2) = 9, diff = 5
i = 3, g(3) = 16, diff = 7
i = 4, g(4) = 25, diff = 9

Note that I used Python introspection to print the argument count and the local variable names of the generated function.

So, it worked. We could enter a function of x via the keyboard, use eval() to dynamically create a Python function that uses it, and evaluate that function for some range of values. Are there any uses of this technique, other than to show that it is possible, and interesting? Sure, I can think of at least one: a graphing calculator. We could have a GUI window with a pane that can draw graphics, such as curves in the 2D plane (using one of the Python GUI toolkits like wxPython or PyQt that support this), and then repeatedly prompt the user for a function of x, eval() it as above, then plot the values of x and y (= g(x)) for a range, in a loop, to draw a curve that represents the function entered.

Note: Use of exec and eval can be a security risk, so only use them in a trusted environment. The optional arguments globals and locals, which I did not use in these two posts, may be of use to control the environment in which they run, but user input is also important.

In fact, the graphing calculator could probably be done as a web app too, using some Python web framework, such as Flask, Bottle, Django or other (a lightweight one may be better here, or even plain CGI), and a web form with an HTML5 canvas and some JavaScript on the front-end. The user could enter the formula (some function of x) in a text box, submit it, the back-end Python app could eval() it to create the function, evaluate that function for a range of points like I did above, and send the list of (x, y) pairs to the browser, where the JavaScript could draw a curve representing those points, on the canvas.

Did you notice any pattern to the values of g(i)? The values are 1, 4, 9, 16, 25 - which are the squares of the integers 1 to 5. But the formula I entered for g was not x * x, rather, it was x * x + 2 * x + 1. Then why are squares shown in the output? Reply in the
comments if you get it, otherwise I will answer next time.

The image at the top of the post is from the Wikipedia page about lambda (the Greek letter) and is of the Greek alphabet on a black figure vessel. Check out the many meanings and uses of the symbol/letter lambda in various fields (see that Wikipedia page).

- Enjoy.


- Vasudev Ram - online Python training and consulting


I conduct online courses on Python programming, Unix / Linux commands and shell scripting and SQL programming and database design, with course material and personal coaching sessions.

The course details and testimonials are here.

Contact me for details of course content, terms and schedule.

Getting a new web site or blog, and want to help preserve the environment at the same time? Check out GreenGeeks.com web hosting.

Sell your digital products via DPD: Digital Publishing for Ebooks and Downloads.

Learning Linux? Hit the ground running with my vi quickstart tutorial. I wrote it at the request of two Windows system administrator friends who were given additional charge of some Unix systems. They later told me that it helped them to quickly start using vi to edit text files on Unix. Of course, vi/vim is one of the most ubiquitous text editors around, and works on most other common operating systems and on some uncommon ones too, so the knowledge of how to use it will carry over to those systems too.

Check out WP Engine, powerful WordPress hosting.

Creating online products for sale? Check out ConvertKit, email marketing for online creators.

Teachable: feature-packed course creation platform, with unlimited video, courses and students.

Posts about: Python * DLang * xtopdf

My ActiveState Code recipes

Follow me on:



Sunday, December 16, 2018

Dynamic function creation at run time with Python's exec built-in

By Vasudev Ram

Hi, readers,
I was browsing Paul Graham's essay about his book "On Lisp". It's about advanced uses of Lisp and some of the features that make it unique.

In it, he talks about many Lisp features, like the ability to treat code as data, the fact that functions are first-class objects, so, just like other objects such as scalar variables, lists, maps, etc., they too can be passed as arguments to functions, returned from functions, stored in variables, etc., and the fact that Lisp programs can write Lisp programs. (There's a lot more to the book, of course.) This made me think of experimenting a bit with Python's dynamic features, whether similar to Lisp or not. One man's Lisp is another man's Python ...

I did know from a while ago that Python has many dynamic features, and have blogged about some of them in the past. (Search my blog for topics like Python tricks, the trace module and chained decorators, Python introspection, the inspect module, finding the caller of a Python function, Python generators are pluggable, function-based callbacks, class-based callbacks, and other fun stuff. Try using 'site:jugad2.blogspot.com' and suchlike search engine techniques.) This is one more such exploration.

I got the idea of writing a program that can dynamically create a function at run time, based on some user input, and then run that function. The program uses the exec built-in of Python.

Here is the program, dyn_func_with_exec.py:
# dyn_func_with_exec.py 
# Purpose: To dynamically create (and run) a function at run time. 
# Author: Vasudev Ram
# Copyright 2018 Vasudev Ram
# Web site: https://vasudevram.github.io
# Product store: https://gumroad.com/vasudevram

from __future__ import print_function
import sys

major = sys.version_info.major
if major == 2:
    input_func = raw_input
elif major == 3:
    input_func = input
else:
    print("Unsupported version, go back to the future.")
    sys.exit(0)

func_name = input_func("Enter name of function to create dynamically: ")
func_def = """
def {}(args):
    print("In function", func_name, ": args:", args)
""".format(func_name)

exec(func_def)
print(func_name, ":", eval(func_name))

args1 = (1, "a"); args2 = (2, "b")

# Two ways of calling the dynamically created function:
print("\nCalling {} via eval():".format(func_name))
eval(func_name + "(args1)")
print("\nCalling {} via globals() dict:".format(func_name))
globals()[func_name](args2)
Here is the output of 3 runs:
(py is the Python launcher for Windows.)
$ py -2 dyn_func_with_exec.py
Enter name of function to create dynamically: mu
mu : <function mu at 0x0000000002340518>

Calling mu via eval():
In function mu : args: (1, 'a')

Calling mu via globals() dict:
In function mu : args: (2, 'b')

$ py -3 dyn_func_with_exec.py
Enter name of function to create dynamically: _
_ : <function _ at 0x000000000039C1E0>

Calling _ via eval():
In function _ : args: (1, 'a')

Calling _ via globals() dict:
In function _ : args: (2, 'b')

$ py dyn_func_with_exec.py
Enter name of function to create dynamically: |
Traceback (most recent call last):
  File "dyn_func_with_exec.py", line 28, in <module>
    exec(func_def)
  File "<string> line 2
    def |(args):
        ^
SyntaxError: invalid syntax
So it works in both Python 2 and 3. The last run (with an invalid function name) shows how the user input gets interpolated into the function definition string func_def.

The if statement used shows another dynamic aspect of Python: the ability to call different functions (via the same name, input_func), based on some condition which is only known at run time (the Python version, in this case).

Why mu for the input? Well, if foo, why not mu? :)
See my HN comment here

Another way to dynamically decide which function to run:

Driving Python function execution from a text file

Enjoy.


- Vasudev Ram - Online Python training and consulting

I conduct online courses on Python programming, Unix / Linux commands and shell scripting and SQL programming and database design, with course material and personal coaching sessions.

The course details and testimonials are here.

Contact me for details of course content, terms and schedule.

Try FreshBooks: Create and send professional looking invoices in less than 30 seconds.

Getting a new web site or blog, and want to help preserve the environment at the same time? Check out GreenGeeks.com web hosting.

Sell your digital products via DPD: Digital Publishing for Ebooks and Downloads.

Learning Linux? Hit the ground running with my vi quickstart tutorial. I wrote it at the request of two Windows system administrator friends who were given additional charge of some Unix systems. They later told me that it helped them to quickly start using vi to edit text files on Unix. Of course, vi/vim is one of the most ubiquitous text editors around, and works on most other common operating systems and on some uncommon ones too, so the knowledge of how to use it will carry over to those systems too.

Teachable: feature-packed course creation platform, with unlimited video, courses and students.

Check out WP Engine, powerful WordPress hosting.

Creating online products for sale? Check out ConvertKit, email marketing for online creators.

Get a fast web site with A2 Hosting.

Posts about: Python * DLang * xtopdf

My ActiveState Code recipes

Follow me on:


Tuesday, November 1, 2016

Creating an REPL is easy in Python


By Vasudev Ram


Read Eval Print Loop

It's easy to create a simple Python REPL (a Read-Eval-Print Loop) in Python - with code.interact(), that is, with the interact function from the code module in Python's standard library.

I wrote and interacted with a small Python program to illustrate it.

It sets a couple of variables, then calls code.interact(), at which point I interact with the program via the REPL session that interact() creates.

I can see and set the variables set earlier by the program, because I pass the locals() dict to interact().

I can define a function in the session, which can access the variables set before the session.

And any changes the session makes to the variables, via my assignments, persist in the program after the interactive session ends (upon typing Ctrl-Z) and the program continues.

All this is shown in the code and output below:
from __future__ import print_function
#--------------------------------------------------------------
# Reference:
# https://docs.python.org/2.7/library/code.html
# https://docs.python.org/3.6/library/code.html
# code_interact.py
# Copyright 2016 Vasudev Ram
# Web site: https://vasudevram.github.io
# Blog: http://jugad2.blogspot.com
# Product store: https://gumroad.com/vasudevram
#--------------------------------------------------------------

import code

a = 1
b = "hello"
print("Before code.interact, a = {}, b = {}".format(a, b))

banner="code.interact session, type Ctrl-Z to exit."
code.interact( banner=banner, local=locals())

print("After code.interact, a = {}, b = {}".format(a, b))
The output of the program:
$ python code_interact.py
Before code.interact, a = 1, b = hello
code.interact session, type Ctrl-Z to exit.
>>> greeting = "hello "
>>> times = 2
>>> a
1
>>> b
'hello'
>>> def repeat_string(s, n):
...     return s * n
...
>>> repeat_string(greeting, times)
'hello hello '
>>> repeat_string(greeting, a)
'hello '
>>> repeat_string(b, times)
'hellohello'
>>> a += 2
>>> a
3
>>> repeat_string(greeting, a)
'hello hello hello '
>>> repeat_string(b, a)
'hellohellohello'
>>>
After code.interact, a = 3, b = hello
$
While on the topic of REPLs, check out these earlier posts:

repl.it, online REPL for many languages, and empythoned.

Codingbat, Progress Graphs and Michael Jordan

codepad.org, executable multi-language pastebin, in Python

- Vasudev Ram - Online Python training and consulting

Get updates on my software products / ebooks / courses.

Jump to posts: Python   DLang   xtopdf

Subscribe to my blog by email

My ActiveState recipes

FlyWheel - Managed WordPress Hosting





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, func_from_file.py:
# Driving Python function execution from a text file.
# Author: Vasudev Ram: 
# https://vasudevram.github.io, 
# http://jugad2.blogspot.com
# 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:
        print
        line = line[:-1] 
        if line.lower() not in fns:
            print "Skipping invalid function name:", line
            continue
        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
fourth
cube
fourth_power
Running the program with:
python func_from_file.py
gives this output:
$ python func_from_file.py

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

Friday, April 25, 2014

Python variables can have types as values

By Vasudev Ram



I came across this article by Peter Norvig:

Design Patterns in Dynamic Languages

(Peter Norvig is Director of Search at Google and a highly accomplished computer scientist.)

Haven't read the article fully yet, but scanned it a bit, and one line in particular interested me:

"A variable can have a type as a value"

That line is on the page with the heading: "First-Class Dynamic Types"

So I thought of checking this in Python - that section of the article seems to be about Lisp and Dylan (the programming language)).

Here's some code I used to check whether Python variables can have types as values - I typed it in the Python interpreter, so both the input and the output appear below:
>>> a = int
>>> type(a)
<type 'type'>
>>> print a('3') + 4
7
>>> b = str
>>> print b(12) * 5
1212121212
>>> class Foo:
...     def bar(self):
...         print "in Foo.bar()"
...
>>> f = Foo
>>> f().bar()
in Foo.bar()
>>>
And here's a couple more lines which give a clue why the above works:
>>> id(int)
505548800
>>> id(a)
505548800
>>> id(str)
505571224
>>> id(b)
505571224
Note that the names int and str have valid id()s, and that id(a) == id(int), and id(b) == id(str).

So it seems that variables in Python can have values that are types. Of course, the id() stuff I did above indicates that it will work for all Python types if it works for one, since "a = int" binds the name a to the same object that the (built-in) name int is bound to. That's my guess, anyway. Interested to see if anyone has any different ideas or a better explanation.

And speaking of Peter Norvig, here's another article by him about Albert Einstein:

'05 Annual Performance Review: Albert Einstein

- Vasudev Ram - Dancing Bison Enterprises

Contact Page