Showing posts with label Lisp. Show all posts
Showing posts with label Lisp. Show all posts

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:


Thursday, September 8, 2016

"Please don't assume Lisp is only useful for Animation and Graphics, AI, Bioinformatics, B2B and E-Commerce, Data Mining, ...


By Vasudev Ram


"Please don't assume Lisp is only useful for Animation and Graphics,


AI, Bioinformatics, B2B and E-Commerce,


Data Mining, EDA/Semiconductor applications,


Expert Systems, Finance,


Intelligent Agents, Knowledge Management, Mechanical CAD, Modeling and Simulation, Natural Language, Optimization, Research, Risk Analysis, Scheduling, Telecom,


and Web Authoring just because these are the only things they happened to list." --Kent Pitman

One could say somewhat the same about Python ...

Image attributions:

Utah teapot

Shopping cart icon

Semiconductor

Dollar

Telecom

- 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



Wednesday, December 12, 2012

How (not) to defend your dysfunctional programming language

[IWE] Why Lisp macros are cool, a Perl perspective

Interessant  ...

IMO, the post doesn't do a good job of explaining why Lisp macros are useful, at least until the part about setnth or so.

Saturday, September 29, 2012

A Lisp success story - ITA Software/Orbitz

Carl de Marcken: Inside Orbitz

from Paul Graham's site. The essay is old but of interest. Also, ITA Software was acquired a while ago by Google.

- Vasudev Ram
www.dancingbison.com

Thursday, August 9, 2012

clj-pdf, Clojure PDF library and instant-pdf, a RESTful PDF generation service

By Vasudev Ram


[ UPDATE: I emailed the author of clj-pdf and instant-pdf, and he told me two things: 1) the instant-pdf bug mentioned below seems to be due to a Clojure JSON library (see the comments on this post), and does not occur when clj-pdf is used directly, and 2) clj-pdf uses the iText PDF library for generating PDF. ]

Saw this via proggit (programming.reddit.com):

clj-pdf is a Clojure library for PDF generation.

instant-pdf is a RESTful web service for PDF generation, built using clj-pdf. It supports JSON for markup. Interesting approach.
It has a fairly large JSON syntax for many elements of PDF, like metadata, text, paragraphs, chapters, colors, tables, etc.

I tried it out a bit. What I tried mostly worked, except for one issue - pasting a DOS directory listing into the text box (for the content section), resulted in PDF output that contained the string "null" instead of backslashes, e.g. for a path like C:\abc\def\some-file.

clj-pdf uses JFreeChart.

P.S. I liked this blog post: WHY ALL THE PARENS, by yogthos, the author of clj-pdf.

- Vasudev Ram - Dancing Bison Enterprises

Friday, March 16, 2012

Python becoming a platform for Clojure


Interesting development, for the reasons cited in the post.

http://khinsen.wordpress.com/2012/03/15/python-becomes-a-platform/

- Vasudev Ram
www.dancingbison.com