Showing posts with label functional-programming. Show all posts
Showing posts with label functional-programming. Show all posts

Tuesday, January 29, 2019

Daily Coding Problem #69: A functional programming solution


- By Vasudev Ram - Online Python training / SQL training / Linux training




Stock reduction image attribution

Hi, readers,

I subscribed to the mailing list of the Daily Coding Problem site site a while ago. It's a useful site. Their modus operandi is to send you one programming problem per day, described in English. You try to solve them, in any programming language of your choice. (They say that some of the questions were asked by companies like Google, Facebook, Amazon, Microsoft, Netflix, etc.) Something like Rosetta Code.
The idea is that you can use this to practice and improve your programming and algorithm development skills.

I haven't been attempting to solve every problem I get in email from them, as of now. I just try one now and then. Hope to attempt more later.

Daily Coding Problem #69 is one that I tried, and solved, using a functional programming approach.

This is the problem statement (taken from the email I got from them):

Daily Coding Problem: Problem #69
To: [email protected]
Good morning! Here's your coding interview problem for today.

This problem was asked by Facebook.

Given a list of integers, return the largest product that can be made by multiplying any three integers.

For example, if the list is [-10, -10, 5, 2], we should return 500, since that's -10 * -10 * 5.

You can assume the list has at least three integers.

And here is my functional-style solution below (actually, two variants on a solution). For this post, I've used a slightly different format than what I usually use - instead of alternating code and (text) explanations, I've put all the explanations in the code, as comments - sort of like literate programming.
# daily_coding_problem_069.py
# Problem source: https://dailycodingproblem.com
# Solution created by Vasudev Ram
# Website: https://vasudevram.github.io
# Copyright 2019 Vasudev Ram
# Blog: https://jugad2.blogspot.com
# Python posts: https://jugad2.blogspot.com/search/label/python
# Product store: https://gumroad.com/vasudevram
# Twitter: https://mobile.twitter.com/vasudevram
# LinkedIn: https://linkedin.com/in.vasudevram

"""
Daily Coding Problem: Problem #69

This problem was asked by Facebook.

Given a list of integers, return the largest product that can be made 
by multiplying any three integers.

For example, if the list is [-10, -10, 5, 2], we should return 500, 
since that's -10 * -10 * 5.

You can assume the list has at least three integers.
"""

from __future__ import print_function

try:
    reduce
except NameError as ne:
    from functools import reduce

from itertools import combinations

# Create a list with a few numbers.
lis = range(1, 6)
print()
print("lis:", lis)

# First, print the combinations iterator object.
print("combinations(lis, 3):", combinations(lis, 3))
# Next, print the combinations themselves.
print("list(combinations(lis, 3)):\n" + \
    "\n".join(str(item) for item in list(combinations(lis, 3))))
print()

# Then define a function that takes an iterable and returns 
# the product of all the numbers in it.
def product(iterable):
    p = 1
    for i in iterable:
        p *= i
    return p

# Test the product function a few times:
print("product(range(10)):", product(range(10)))
print("product(range(1, 11)):", product(range(1, 11)))
print("product(range(1, 6, 2)):", product(range(1, 6, 2)))
print("product(range(1, 10, 2)):", product(range(1, 10, 2)))
print()

# Now use the product function with the combinations function 
# to solve Daily Coding Problem #69:
print("max(map(product, combinations(lis, 3)):", \
    max(map(product, combinations(lis, 3))))

# Now let's solve the same problem with reduce and operator.mul 
# instead of the product function above:

# Here is the docstring for reduce:
print("reduce.__doc__:", reduce.__doc__)
print

from operator import mul

# Here is the docstring for mul:
print("operator.mul.__doc__:", mul.__doc__)
print()

# Show how reduce works with mul with a few examples:
print("reduce(mul, range(1, 5)):", reduce(mul, range(1, 5)))
print("reduce(mul, range(3, 7)):", reduce(mul, range(3, 7)))
print()

# Use reduce-with-mul instead of product.
print("max(map(lambda s: reduce(mul, s), combinations(lis, 3))):", \
    max(map(lambda s: reduce(mul, s), combinations(lis, 3))))

# Here's the call using product again for comparison:
print("max(map(product, combinations(lis, 3))):", \
    max(map(product, combinations(lis, 3))))
print()

# A few more calls to the reduce-with-mul version:
lis4 = range(1, 5)
print("lis4:", lis4)
print("max(map(lambda s: reduce(mul, s), combinations(lis4, 3))):", \
    max(map(lambda s: reduce(mul, s), combinations(lis4, 3))))
print()

lis6 = range(1, 7)
print("lis6:", lis6)
print("max(map(lambda s: reduce(mul, s), combinations(lis6, 3))):", \
    max(map(lambda s: reduce(mul, s), combinations(lis6, 3))))
print()

lis7 = range(1, 8)
print("lis7:", lis7)
print("max(map(lambda s: reduce(mul, s), combinations(lis7, 3))):", \
    max(map(lambda s: reduce(mul, s), combinations(lis7, 3))))
print()

# And finally, here is the solution run again with the example 
# input given in the Facebook problem mentioned above:

lis_fb = [-10, -10, 5, 2]
print("lis_fb:", lis_fb)
print("max(map(lambda s: reduce(mul, s), combinations(lis_fb, 3))):", \
    max(map(lambda s: reduce(mul, s), combinations(lis_fb, 3))))
print()

# The result matches the given answer, 500.

# Now let's modify the Faceboook input and run the code again:
lis_fb2 = [-10, 8, -10, 9, 5, 7, 2]
# (Added values 8, 9 and 7 to the list.)
print("lis_fb2:", lis_fb2)
print("max(map(lambda s: reduce(mul, s), combinations(lis_fb2, 3))):", \
    max(map(lambda s: reduce(mul, s), combinations(lis_fb2, 3))))
print()

# The result is right again, since -10 * -10 * 9 = 900 is 
# the largest product.

Here is the output of a run of the program using Python 3:
lis: range(1, 6)
combinations(lis, 3): <itertools.combinations object at 0x0000000001DA9598>
list(combinations(lis, 3)):
(1, 2, 3)
(1, 2, 4)
(1, 2, 5)
(1, 3, 4)
(1, 3, 5)
(1, 4, 5)
(2, 3, 4)
(2, 3, 5)
(2, 4, 5)
(3, 4, 5)

product(range(10)): 0
product(range(1, 11)): 3628800
product(range(1, 6, 2)): 15
product(range(1, 10, 2)): 945

max(map(product, combinations(lis, 3)): 60
reduce.__doc__: reduce(function, sequence[, initial]) -> value

Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
operator.mul.__doc__: Same as a * b.

reduce(mul, range(1, 5)): 24
reduce(mul, range(3, 7)): 360

max(map(lambda s: reduce(mul, s), combinations(lis, 3))): 60
max(map(product, combinations(lis, 3))): 60

lis4: range(1, 5)
max(map(lambda s: reduce(mul, s), combinations(lis4, 3))): 24

lis6: range(1, 7)
max(map(lambda s: reduce(mul, s), combinations(lis6, 3))): 120

lis7: range(1, 8)
max(map(lambda s: reduce(mul, s), combinations(lis7, 3))): 210

lis_fb: [-10, -10, 5, 2]
max(map(lambda s: reduce(mul, s), combinations(lis_fb, 3))): 500

lis_fb2: [-10, 8, -10, 9, 5, 7, 2]
max(map(lambda s: reduce(mul, s), combinations(lis_fb2, 3))): 900

I also tested it with Python 2 and it gave basically the same output, 
maybe with the exception of some minor message differences between 2 and 3.
So I'm not showing the 2 output here.

The image at the top of the post is of stock with bay leaf and thyme being reduced in a pan.
Here is the Wikipedia article about reduction in cooking.

The functional programming meaning of reduce sort of matches the cooking meaning, right? Heh.

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.

Check out WP Engine, powerful WordPress hosting.

Sell More Digital Products With SendOwl.

Get a fast web site with A2 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:


Tuesday, January 22, 2019

Factorial one-liner using reduce and mul for Python 2 and 3


- By Vasudev Ram - Online Python training / SQL training / Linux training

$ foo bar | baz

Hi, readers,

A couple of days ago, I wrote this post for computing factorials using the reduce and operator.mul functions:

Factorial function using Python's reduce function

A bit later I realized that it can be made into a Python one-liner. Here is the one-liner - it works in both Python 2 and Python 3:
$ py -2 -c "from __future__ import print_function; from functools 
import reduce; from operator import mul; print(list(reduce(mul, 
range(1, fact_num + 1)) for fact_num in range(1, 11)))"
[1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]

$ py -3 -c "from __future__ import print_function; from functools 
import reduce; from operator import mul; print(list(reduce(mul, 
range(1, fact_num + 1)) for fact_num in range(1, 11)))"
[1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]

(I've split the commands above across multiple lines to avoid truncation while viewing, but if trying them out, enter each of the above commands on a single line.)

A small but interesting point is that one of the imports is not needed in Python 2, and the other is not needed in Python 3:

- importing print_function is not needed in Py 3, because in 3, print is a function, not a statement - but it is not an error to import it, for compatibility with Py 2 code - where it actually needs to be imported for compatibility with Py 3 code (for using print as a function), ha ha.

- importing reduce is not needed in Py 2, because in 2, reduce is both a built-in and also available in the functools module - and hence it is not an error to import it.

Because of the above two points, the same one-liner works in both Py 2 and Py 3.

Can you think of a similar Python one-liner that gives the same output as the above (and for both Py 2 and 3), but can work without one of the imports above (but by removing the same import for both Py 2 and 3)? If so, type it in a comment on the post.

py is The Python launcher for Windows.

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.

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

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:




Monday, January 21, 2019

Factorial function using Python's reduce function


- By Vasudev Ram - Online Python training / SQL training / Linux training



[This is a beginner-level Python post. I label such posts as "python-beginners" in the Blogger labels at the bottom of the post. You can get a sub-feed of all such posts for any label using the label (case-sensitive) in a URL of the form:

https://jugad2.blogspot.com/search/label/label_name where label_name is to be replaced by an actual label,

such as in:

jugad2.blogspot.com/search/label/python-beginners

and

jugad2.blogspot.com/search/label/python
]

Hi, readers,

The factorial function (Wikipedia article) is often implemented in programming languages as either an iterative or a recursive function. Both are fairly simple to implement.

For the iterative version, to find the value of n factorial (written n! in mathematics), you set a variable called, say, product, equal to 1, then multiply it in a loop by each value of a variable i that ranges from 1 to n.

For the recursive version, you define the base case as 0! = 1, and then for all higher values of n factorial, you compute them recursively as the product of n with (n - 1) factorial.

[ Wikipedia article about Iteration. ]

[ Wikipedia article about Recursion in computer_science. ]

Here is another way of doing it, which is also iterative, but uses no explicit loop; instead it uses Python's built-in reduce() function, which is part of the functional programming paradigm or style:
In [179]: for fact_num in range(1, 11):
     ...:     print reduce(mul, range(1, fact_num + 1))
     ...:
1
2
6
24
120
720
5040
40320
362880
3628800
The above snippet (run in IPython - command-line version), loops over the values 1 to 10, and computes the factorial of each of those values, using reduce with operator.mul (which is a functional version of the multiplication operator). In more detail: the function call range(1, 11) returns a list with the values 1 to 10, and the for statement iterates over those values, passing each to the expression involving reduce and mul, which together compute each value's factorial, using the iterable returned by the second range call, which produces all the numbers that have to be multiplied together to get the factorial of fact_num.

The Python docstring for reduce:
reduce.__doc__: reduce(function, sequence[, initial]) -> value

Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
Did you know that there are many different kinds of factorials? To learn more, check out this post:

Permutation facts

- 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.

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.

Sell More Digital Products With SendOwl.

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 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:


Friday, June 1, 2018

Porting a prime checker from Q to Python (with improvements)

By Vasudev Ram


Q => Py

Hi readers,

I was checking out the Q programming language.

It's an interesting language, a descendant of APL, that supports array and functional programming styles. Some information about Q from its Wikipedia page:

Paradigm: Array, functional
Designed by: Arthur Whitney
Developer: Kx Systems
First appeared: 2003
Typing discipline: Dynamic, strong
Influenced by: A+, APL, Scheme, K

Q is a proprietary array processing language developed by Arthur Whitney and commercialized by Kx Systems. The language serves as the query language for kdb+, a disk based and in-memory, column-based database. kdb+ is based upon K, a terse variant of APL. Q is a thin wrapper around K, providing a more readable, English-like interface.

I had tried out Q a bit recently, using one of the tutorials.

Then, while reading the Q Wikipedia page again, I saw this paragraph:

[
When x is an integer greater than 2, the following function will return 1 if it is a prime, otherwise 0:

{min x mod 2_til x}
The function is evaluated from right to left:

"til x" enumerate the positive integers less than x.
"2_" drops the first two elements of the enumeration (0 and 1).
"x mod" performs modulo division between the original integer and each value in the truncated list.
"min" find the minimum value of the list of modulo result.
]

It's basically an algorithm in Q to find whether a given number x (> 2) is prime or not [1]. The algorithm returns 1 if x is a prime, else 0. Notice how concise it is. That conciseness is a property of the APL family of languages, such as APL, J and Q. In fact Q is slightly less concise than some of the others, I've read, because it puts a thin English-like wrapper on the hard-core APL symbolic syntax. But all of them are still very concise.

So I thought of implementing that algorithm in Python, just for fun. I first wrote a naive version, more or less a port of the Q version. Then I rewrote that first version in a more functional way. Then I realized that there are other opportunities for improving the code [2], and implemented a few of them.

So I combined the few different versions of the is_prime_* functions (where * = 1, 2, 3, etc.) that I had written, in a single program, with a driver function to exercise all of them. The code is in file is_prime.py, shown further below. There are comments in the program that explain the logic and improvements or differences of the various is_prime function versions.

[1] Prime_number

[2] There are obviously many other ways of checking if numbers are prime, and many of them are faster than these approaches; see [3]. These are not among the most efficient ways, or even close; I was just experimenting with different ways of rewriting and refactoring the code, after the initial port from Q to Python. Even the original Q version in the Wikipedia page was not meant to be a fast version, since it does not use any of the improvements I mention below, let alone using any special Q-specific algorithm or language feature, or advanced general prime-finding algorithms.

[3] Primality test

There might still be some scope for further changes or improvements, some of which I may do in a future post. A few such improvements are:

1. Don't divide x by all values up to x - 1. Instead, only check up to the square root of x. This is a standard improvement often taught to programming beginners; in fact, it is mentioned in the Wikipedia articles about primes.

2. Terminate early when the first remainder equal to 0 is found. This avoids unnecessarily computing all the other remainders. I did that in is_prime_3().

3. Don't check for divisibility by any even number > 2 (call it b), because if any such b divides x evenly, then so will 2, and we would have checked earlier if 2 divides x evenly.

4. Create a function for the output statements, most of which are common across the different is_prime versions, and call that function instead from those places.

5. Use a generator to lazily yield divisors, and when any divisor gives a zero remainder, exit early, since it means the number is not prime. Done in is_prime_4().

Other ways of doing it may include use of some other functional programming features of Python such as filter(), itertools.takewhile/dropwhile, etc. (The itertools module has many functions and is very interesting, but that is a subject for a different post.)

I also observed some interesting behavior when running the program with large ranges of inputs for prime number checking. Will analyze that a bit and write about my opinions on that in a future post.

Here is the code for is_prime.py:
# File: isprime.py
# A port of a primality checking algorithm from the Q language to Python, 
# plus a few improvements / variations, using Python features.
# Ref: https://en.wikipedia.org/wiki/Q_(programming_language_from_Kx_Systems)
# Search for the word "prime" in that page to see the Q code.

# Author: Vasudev Ram
# Copyright 2018 Vasudev Ram
# Web site: https://vasudevram.github.io
# Blog: https://jugad2.blogspot.com
# Product store: https://gumroad.com/vasudevram

from __future__ import print_function
from debug1 import debug1

import sys

# Naive, mostly procedural port from the Q version.
def is_prime_1(x):
    # Guard against invalid argument.
    assert x > 2, "in is_prime_1: x > 2 failed"
    # The range of integers from 0 to x - 1
    til_x = range(x)
    # The range without the first 2 items, 0 and 1.
    divs = til_x[2:]
    # The remainders after dividing x by each integer in divs.
    mods = map(lambda d: x % d, divs)
    # x is prime if the minimum-valued remainder equals 1.
    return min(mods) == 1

# Shorter, more functional version, with nested calls 
# to min, map and range.
def is_prime_2(x):
    assert x > 2, "in is_prime_2: x > 2 failed"
    # Eliminate slicing used in is_prime_1, just do range(2, x).
    return min(map(lambda d: x % d, range(2, x))) == 1

# Early-terminating version, when 1st remainder equal to 0 found, 
# using a list for the range of divisors.
def is_prime_3(x):
    assert x > 2, "in is_prime_3: x > 2 failed"
    divs = range(2, x)
    # Check if x is divisible by any integer in divs; if so, 
    # x is not prime, so terminate early.
    debug1("in is_prime_3, x", x)
    for div in divs:
        debug1("  in loop, div", div)
        if x % div == 0:
            return False
    # If we reach here, x was not divisible by any integer in 
    # 2 to x - 1, so x is prime.
    return True

# Generator function to yield the divisors one at a time, to 
# avoid creating the whole list of divisors up front.
def gen_range(start, x):
    assert start > 0, "in gen_range, start > 0 failed"
    assert x > start, "in gen_range, x > start failed"
    i = start
    while i < x:
        yield i
        i += 1

# Early-terminating version, when 1st remainder equal to 0 found, 
# using a generator for the range of divisors.
def is_prime_4(x):
    assert x > 2, "in is_prime_4, x > 2 failed"
    divs = gen_range(2, x)
    debug1("in is_prime_4, x", x)
    for div in divs:
        debug1("  in loop, div", div)
        if x % div == 0:
            return False
    return True

def check_primes(low, high):
    assert low <= high, "in check_primes, low <= high failed"

    """
    print("\nWith a for loop:")
    for x in range(low, high + 1):
        print(x, "is" if is_prime_1(x) else "is not", "prime,", end=" ")
    print()
    """

    print("\nWith nested function calls:")
    output = [ str(x) + (" prime" if is_prime_2(x) else " not prime") \
        for x in range(low, high + 1) ]
    print(", ".join(output))

    print("\nWith a list of divisors and early termination:")
    output = [ str(x) + (" prime" if is_prime_3(x) else " not prime") \
        for x in range(low, high + 1) ]
    print(", ".join(output))

    print("\nWith a generator of divisors and early termination:")
    output = [ str(x) + (" prime" if is_prime_4(x) else " not prime") \
        for x in range(low, high + 1) ]
    print(", ".join(output))

def main():
    try:
        low = int(sys.argv[1])
        high = int(sys.argv[2])
        if low <= 2:
            print("Error: Low value must be > 2.")
            sys.exit(1)
        if high < low:
            print("Error: High value must be >= low value.")
            sys.exit(1)
        print("Checking primality of integers between {} and {}".format(low, high))
        check_primes(low, high)
        sys.exit(0)
    except ValueError as ve:
        print("Caught ValueError: {}".format(str(ve)))
    except IndexError as ie:
        print("Caught IndexError: {}".format(str(ie)))
    sys.exit(1)

if __name__ == '__main__':
    main()
And here are some runs of the output, below, both for normal and error cases. Note that I used my debug1() debugging utility function in a few places, to show what divisors are being used, in a few places. This helps show that the early termination logic works. To turn off debugging output, simply use the -O option, like this example:

python -O is_prime.py other_args

This improved version of the debug1 function (get it here), unlike the earlier version that was shown in this blog post:

A simple Python debugging function

, does not require the user to set any environment variables like VR_DEBUG, since it uses Python's built-in __debug__ variable instead. So to enable debugging, nothing extra needs to be done, since that variable is set to True by default. To disable debugging, all we have to do is pass the -O option on the python command line.

Here is the prime program's output:

Try this one later (if you're trying out the program), since it takes 
longer to run. You may observe some interesting behavior:

$ python -O is_prime.py 3 10000 | less

where less is the Unix 'less' command, a text pager. Any command-line text pager 
that can read standard input (from a pipe) will work.

Try some of these below (both normal and error cases) before the one above:

Some error-handling cases:

$ python -O is_prime.py 0 0
Error: Low value must be > 2.

$ python -O is_prime.py 2 0
Error: Low value must be > 2.

$ python -O is_prime.py 3 0
Error: High value must be >= low value.

$ python -O is_prime.py 4 2
Error: High value must be >= low value.

Some normal cases:

$ python -O is_prime.py 3 3
Checking primality of integers between 3 and 3

With nested function calls:
3 prime

With a list of divisors and early termination:
3 prime

With a generator of divisors and early termination:
3 prime

To show that the early termination logic works, run the program without 
the -O option. 
Here is one such run. Due to more debugging output, I've only checked 
two numbers, 4 and 5. But you can try with any number of values if you 
page the output, or redirect it to a file.

$ python is_prime.py 4 5
Checking primality of integers between 4 and 5

With nested function calls:
4 not prime, 5 prime

With a list of divisors and early termination:
in is_prime_3, x: 4
  in loop, div: 2
in is_prime_3, x: 5
  in loop, div: 2
  in loop, div: 3
  in loop, div: 4
4 not prime, 5 prime

With a generator of divisors and early termination:
in is_prime_4, x: 4
  in loop, div: 2
in is_prime_4, x: 5
  in loop, div: 2
  in loop, div: 3
  in loop, div: 4
4 not prime, 5 prime

You can see from the above run that for 4, the checking stops early, 
at the first divisor (2), in fact, because it evenly divides 4.
But for 5, all divisors from 2 to 4 are checked, because 5 has 
no prime factors (except itself and 1).

And here is a run checking for primes between 3 and 30:

$ python -O is_prime.py 3 30
Checking primality of integers between 3 and 30

With nested function calls:
3 prime, 4 not prime, 5 prime, 6 not prime, 7 prime, 8 not prime, 9 not prime, 
10 not prime, 11 prime, 12 not prime, 13 prime, 14 not prime, 15 not prime, 
16 not prime, 17 prime, 18 not prime, 19 prime, 20 not prime, 21 not prime, 
22 not prime, 23 prime, 24 not prime, 25 not prime, 26 not prime, 27 not prime, 
28 not prime, 29 prime, 30 not prime

With a list of divisors and early termination:
3 prime, 4 not prime, 5 prime, 6 not prime, 7 prime, 8 not prime, 9 not prime, 
10 not prime, 11 prime, 12 not prime, 13 prime, 14 not prime, 15 not prime, 
16 not prime, 17 prime, 18 not prime, 19 prime, 20 not prime, 21 not prime, 
22 not prime, 23 prime, 24 not prime, 25 not prime, 26 not prime, 27 not prime, 
28 not prime, 29 prime, 30 not prime

With a generator of divisors and early termination:
3 prime, 4 not prime, 5 prime, 6 not prime, 7 prime, 8 not prime, 9 not prime, 
10 not prime, 11 prime, 12 not prime, 13 prime, 14 not prime, 15 not prime, 
16 not prime, 17 prime, 18 not prime, 19 prime, 20 not prime, 21 not prime, 
22 not prime, 23 prime, 24 not prime, 25 not prime, 26 not prime, 27 not prime, 
28 not prime, 29 prime, 30 not prime

You can see that all three functions (is_prime_2 to 4) give the same results. 
(I commented out the call to the naive function version, is_prime_1, after 
a few runs (not shown), so none of these outputs shows its results, but they 
are the same as the others, except for minor formatting differences, due to 
the slightly different output statements used.

I also timed the program for finding primes up to 1000 and 10,000 
(using my own simple command timing program written in Python - not shown).

Command: python -O is_prime.py 3 1000
Time taken: 2.79 seconds
Return code: 0

Command: python -O is_prime.py 3 10000
Time taken: 66.28 seconds
Return code: 0

Related links:

Q (programming_language from Kx_Systems

Kx Systems

Kdb+

Column-oriented DBMS

In-memory database

If you want to try out Q, Kx Systems a free version available for download for non-commercial use, here: Q downloads

Enjoy.

- Vasudev Ram - Online Python training and consulting

Get fast web hosting with A2Hosting.com

Get updates (via Gumroad) on my forthcoming apps and content.

Jump to posts: Python * DLang * xtopdf

Subscribe to my blog by email

My ActiveState Code recipes

Follow me on: LinkedIn * Twitter

Are you a blogger with some traffic? Get Convertkit:

Email marketing for professional bloggers



Thursday, April 27, 2017

Using nested conditional expressions to classify characters

By Vasudev Ram


While writing some Python code, I happened to use a conditional expression, a Python language feature.

Conditional expressions are expressions (not statements) that have if/else clauses inside them, and they evaluate to either one of two values (in the basic case), depending on the value of a boolean condition. For example:
for n in range(4):
    print n, 'is odd' if n % 2 == 1 else 'is even'
0 is even
1 is odd
2 is even
3 is odd
Here, the conditional expression is this part of the print statement above:
'is odd' if n % 2 == 1 else 'is even'
This expression evaluates to 'is odd' if the condition after the if is True, and evaluates to 'is even' otherwise. So it evaluates to a string in either case, and that string gets printed (after the value of n).

Excerpt from the section about conditional expressions in the Python Language Reference:

[
conditional_expression ::= or_test ["if" or_test "else" expression]
expression ::= conditional_expression | lambda_expr

Conditional expressions (sometimes called a “ternary operator”) have the lowest priority of all Python operations.

The expression x if C else y first evaluates the condition, C (not x); if C is true, x is evaluated and its value is returned; otherwise, y is evaluated and its value is returned.
]

You can see that the definition of conditional_expression is recursive, since it is partly defined in terms of itself (via the definition of expression).

This implies that you can have recursive or nested conditional expressions.

Also, since the syntax of the Python return statement is:
return [ expression_list ]
(where expression_list means one or more expressions, separated by commas, it follows that we can use a nested conditional expression in a return statement (because a nested conditional expresssion is an expression).

Here is a small program to demonstrate that:
'''
File: return_with_nested_cond_exprs.py 
Purpose: Demonstrate nested conditional expressions used in a return statement, 
to classify letters in a string as lowercase, uppercase or neither.
Also demonstrates doing the same task without a function and a return, 
using a lambda and map instead.
Author: Vasudev Ram
Copyright 2017 Vasudev Ram
Web site: https://vasudevram.github.io
Blog: https://jugad2.blogspot.com
'''

from __future__ import print_function
from string import lowercase, uppercase

# Use return with nested conditional expressions inside a function, 
# to classify characters in a string as lowercase, uppercase or neither:
def classify_char(ch):
    return ch + ': ' + ('lowercase' if ch in lowercase else \
    'uppercase' if ch in uppercase else 'neither')

print("Classify using a function:")
for ch in 'AaBbCc12+-':
    print(classify_char(ch))

print()

# Do it using map and lambda instead of def and for:
print("Classify using map and lambda:")

print('\n'.join(map(lambda ch: ch + ': ' + ('lowercase' if ch in lowercase else 
'uppercase' if ch in uppercase else 'neither'), 'AaBbCc12+-')))
Running it with:
$ python return_with_nested_cond_exprs.py
gives this output:
Classify using a function:
A: uppercase
a: lowercase
B: uppercase
b: lowercase
C: uppercase
c: lowercase
1: neither
2: neither
+: neither
-: neither

Classify using map and lambda:
A: uppercase
a: lowercase
B: uppercase
b: lowercase
C: uppercase
c: lowercase
1: neither
2: neither
+: neither
-: neither
As you can see from the code and the output, I also used that same nested conditional expression in a lambda function, along with map, to do the same task in a more functional style
.

- Vasudev Ram - Online Python training and consulting

Get updates (via Gumroad) on my forthcoming apps and content.

Jump to posts: Python * DLang * xtopdf

Subscribe to my blog by email

My ActiveState Code recipes

Follow me on: LinkedIn * Twitter

Are you a blogger with some traffic? Get Convertkit:

Email marketing for professional bloggers



Saturday, October 22, 2016

perm_facts version with list comps and functional programming

By Vasudev Ram



Cartoon attribution

A little after writing the program (perm_facts.py) in my recent post:

Permutation facts

(which showed that the number of permutations of n things was the same as n factorial), I saw that I could replace the program's for loops with list comprehensions. So I did that, in the functions num_perms_upto and factorials_upto.

Then I also changed the recursive factorial function to the iterative version shown in the code below. (Although people sometimes use recursive algorithms instead of iterative ones, because they can be simpler to implement, often by using elegant divide and conquer methods), in this case, the recursive version is not really simpler than the iterative one.)

However, I then realized that I could replace the iterative version by a one-line functional version using reduce and operator.mul. So here is the program, perm_fact2.py, with all the changes mentioned above (the iterative version is left in, as comments, but the for loops from the original perm_fact.py are gone, replaced by shorter list comprehensions).

A small benefit of the changes is that the number of lines comes down by a few (if you don't count the commented lines for the iterative version, which I left in there, since it was not in the original), but that was not the goal of the exercise - I was just exploring different ways of doing it.

And whether the code is clearer or not after the changes, may be a matter of personal opinion. For those used to the procedural / imperative style, the changes may make it a bit harder to read, but I think the functional part (reduce with operator.mul, here) and list comprehensions seem to have a certain elegance, and they take slightly less LOC.

Excessive use of reduce, map, etc., just for the sake of it, isn't good, though. And up to 3 or so nested list comprehensions is easy to understand, IME. The thing to remember is that the nested for's (in a nested list comp) run in the same order (leftmost or outermost first) as in a nested for loop. (This is mentioned in the Python docs, and I think they did it that way to be intuitive.)

I ran the program the same way as the previous one, and it gave the same output (verified by DOS's "fc /l outfile1 outfile2", so I will not show the output again here.
#--------------------------------------------------------------
# perm_fact2.py
# Modified version of perm_fact.py, with:
# - two for loops replaced by list comprehensions;
# - recursive factorial() replaced by iterative function;
# - iterative factorial() in turn replaced by 
#   functional version, using reduce().
# Author: Vasudev Ram
# Copyright 2016 Vasudev Ram
# Web site: https://vasudevram.github.io
# Blog: http://jugad2.blotspot.com
# Product store: https://gumroad.com/vasudevram
#--------------------------------------------------------------

import sys
from itertools import permutations
from operator import mul

def num_perms_upto(n):
    return [ len(list(permutations(range(i)))) for i in range(1, n + 1) ]

def factorial(n):
    if n < 0:
        print "Argument n should be >= 0"
        sys.exit(0)
    #-------------------------------------------------------
    #Iterative computation of factorial.
    #f = 1
    #for i in range(1, n + 1):
    #    f *= i
    #return f
    #-------------------------------------------------------
    # Functional computation of factorial, using reduce().
    return reduce(mul, range(1, n + 1), 1)

def factorials_upto(n):
    return [ factorial(i) for i in range(1, n + 1) ]

print "Number of permutations of 1 .. n, where n in 1 .. 10:"
print num_perms_upto(10)
print "Factorial of n, where n in 1 .. 10:"
print factorials_upto(10)
I also timed the runs of both perm_fact.py and perm_fact2.py (and perm_fact2.py separately for both the iterative and functional versions of factorial), a few times each, but did not notice any significant difference. Sometimes one was a bit faster, sometimes the other was, sometimes nearly the same.

(One reason why I thought of timing it in the first place, was because I had read somewhere recently that using map on a sequence can be faster than processing its items in a for loop; haven't tested that, so don't know whether is right or not, but it could be - IIRC, the reason given was that the iteration then happens inside the C implementation of map, and if true, that probably holds for reduce too.)

Also, due to the small amount of code in each, and only a few iterations happening in the code, versus the size of the Python interpreter, it is likely that a good (relative) chunk of the total run time was taken by the loading and initialization of the interpreter, and maybe by parsing the .py files. Other random OS processes running on my machine could also account for the variations. Anyway, the goal here was not really to see if the changes made it faster.

- Vasudev Ram - Online Python training and consulting

FlyWheel - Managed WordPress Hosting

Get updates on my software products / ebooks / courses.

Jump to posts: Python   DLang   xtopdf

Subscribe to my blog by email

My ActiveState recipes



Wednesday, September 14, 2016

Func-y D + Python pipeline to generate PDF

By Vasudev Ram



Hi, readers,

Here is a pipeline that generates some output from a D (language) program and passes it to a Python program that converts that output to PDF. The D program makes use of a bit of (simple) template programming / generics and a bit of functional programming (using the std.functional module from Phobos, D's standard library).


D => Python


I'm showing this as yet another example of the uses of xtopdf, my Python toolkit for PDF creation, as well as for the D part, which is fun (pun intended :), and because those D features are powerful.

The D program is derived, with some modifications, from a program in this post by Gary Willoughby,

More hidden treasure in the D standard library .

That program demonstrates, among other things, the pipe feature of D from the std.functional module.

First, the D program, student_grades.d:
/*
student_grades.d
Author: Vasudev Ram
Web site: https://vasudevram.github.io
Blog: http://jugad2.blogspot.com
Product store: https://gumroad.com/vasudevram
Adapts code from:
http://nomad.so/2015/08/more-hidden-treasure-in-the-d-standard-library/
*/

import std.stdio;
import std.algorithm;
import std.array;
import std.conv;
import std.functional;

// Set up the functional pipeline by composing some functions.
alias sumString = pipe!(split, map!(to!(int)), sum);

void main(string[] args)
{
    // Data to be transformed:
    // Each string has the student name followed by 
    // their grade in 5 subjects.
    auto student_grades_list = 
    [
        "A 1 2 3 4 5",
        "B 2 3 4 5 6",
        "C 3 4 5 6 7",
        "D 4 5 6 7 8",
        "E 5 6 7 8 9",
    ];

    // Transform the data for each student.
    foreach(student_grades; student_grades_list) {
        auto student = student_grades[0]; // name
        auto total = sumString(student_grades[2..$]); // grade total
        writeln("Grade total for student ", student, ": ", total);
    }
}
The initial data (which the D program transforms) is hard-coded, but that can easily be changed to read it from a text file, for instance. The program uses pipe() to compose [1] the functions split, map (to int), and sum (some of which are generic / template functions).

So, when it is run, each string (student_grades) of the input array student_grades_list is split (into an array of smaller strings, by space as the delimiter); then each string in the array (except for the first, which is the name), is mapped (converted) to integer; then all the integers are summed up to get the student's grade total; finally these names and totals are written to standard output. That becomes the input to the next stage of the pipeline, the Python program, which does the conversion to PDF.

Build the D program with:
dmd -o- student_grades.d
which gives us the executable, student_grades(.exe).

The Python part of the pipeline is StdinToPDF.py, one of the apps in the xtopdf toolkit, which is designed to be used in pipelines such as the above - basically, any Unix, Windows or Mac OS X pipeline, that generates text as its final output, can be further terminated by StdinToPDF, resulting in conversion of that text to PDF. It is a small Python app written using the core class of the xtopdf library, PDFWriter. Here is the original post about StdinToPDF:

[xtopdf] PDFWriter can create PDF from standard input

Here is the pipeline:
$ student_grades | python StdinToPDF.py sg.pdf

Below is a cropped screenshot of the generated output, sg.pdf, as seen in Foxit PDF Reader.

[1] Speaking of functional composition, you may like to check out this earlier post by me:

fmap(), "inverse" of Python map() function

It's about a different way of composing functions (for certain cases). It also has an interesting comment exchange between me and a reader, who showed both how to do it in Scala, and another way to do it in Python. Also, there is another way to compose functions in D, using a function called compose; it works like pipe, but the composed functions are written in the reverse order. It's in the same D module as pipe, std.functional.

Finally (before I pipe down - for today :), check out this HN comment by me (on another topic), in which I mention and link to multiple other ways of doing pipe-like stuff in Python:

Comment on Streem – a new programming language from Matz

- Enjoy.

- 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



Thursday, July 2, 2015

Free Erlang masterclasses from Erlang co-inventor and University of Kent

By Vasudev Ram

Saw this via Twitter:

The University of Kent is organizing free masterclasses on Erlang, by 3 people: Joe Armstrong, co-inventor of Erlang, Simon Thompson, functional programming teacher and researcher at the University of Kent, and Francesco Cesarini, CTO and founder of Erlang Solutions Ltd.

Details here:

Erlang master classes

- Vasudev Ram - Online Python training and programming

Dancing Bison Enterprises

Signup to hear about new products or services that I create.

Posts about Python  Posts about xtopdf

Contact Page

Sunday, October 21, 2012

OCaml used at Jane Street, Citrix and Facebook


By Vasudev Ram

This post, Announcing the OCaml Labs project, says that the OCaml language is used at Jane Street, Citrix and Facebook, among other places.

Reddit thread about the OCaml Labs announcement.




- Vasudev Ram - Dancing Bison Enterprises


Friday, October 5, 2012

fmap(), "inverse" of Python map() function


By Vasudev Ram

fmap() is a function I created, which is a kind of inverse of the built-in Python map() function. It has probably been discovered/created by many others before (though they may have called it by different names), but I thought of it just now, based on some code I wrote recently (*), so blogging about it.

The comments in the source code below describe what fmap does. It is straightforward.

(*) That "recent code" refers to this snippet:
result = item
for processor in self._processors:
    result = processor(result)

from my blog post about the release of PipeController v0.1; that snippet basically does the same thing as fmap(), but the snippet is specific to PipeController, whereas fmap() was extracted from that, and generalized to be reusable in other programs.

fmap.py source code:

(You can also get the fmap.py code from a pastebin here, since Blogger sometimes doesn't render inline code too well (tabs show up as one space, for example.)

# fmap.py

# Author: Vasudev Ram - http://www.dancingbison.com

# fmap() is a Python function which is a kind of inverse of the 
# built-in Python map() function.
# The map() function is documented in the Python interpreter as
# follows:

"""
>>> print map.__doc__
map(function, sequence[, sequence, ...]) -> list

Return a list of the results of applying the function to the items of
the argument sequence(s).  If more than one sequence is given, the
function is called with an argument list consisting of the corresponding
item of each sequence, substituting None for missing values when not all
sequences have the same length.  If the function is None, return a list of
the items of the sequence (or a list of tuples if more than one sequence).
"""

# The fmap() function does the inverse, in a sense.
# It returns the result of applying a list of functions to a 
# given argument.
# TODO: Later extend the function to also work on a sequence of 
# arguments like map() does.

import string

def fmap(function_list, argument):
 result = argument
 for function in function_list:
  #print "calling " + function.__name__ + "(" + repr(result) + ")"
  result = function(result)
 return result

def times_two(arg):
 return arg * 2

def square(arg):
 return arg * arg

def upcase(s):
 return string.upper(s)

def delspace(s):
 return string.replace(s, ' ', '')

def main():

 print

 function_list = [ times_two, square ]
 for argument in range(5):
  fmap_result = fmap(function_list, argument)
  print "argument:", argument, ": fmap result:", fmap_result

 print

 function_list = [ upcase, delspace ]
 for argument in [ "the quick brown fox", "the lazy dog" ]:
  fmap_result = fmap(function_list, argument)
  print "argument:", argument, ": fmap result:", fmap_result

if __name__ == "__main__":
 main()

# EOF: fmap.py

Output of running a test program for fmap():
$> python fmap.py

argument: 0 : fmap result: 0
argument: 1 : fmap result: 4
argument: 2 : fmap result: 16
argument: 3 : fmap result: 36
argument: 4 : fmap result: 64

argument: the quick brown fox : fmap result: THEQUICKBROWNFOX
argument: the lazy dog : fmap result: THELAZYDOG

UPDATE:

Here are a couple of other interesting posts about functional programming in Python, which I found by doing a Google search for relevant terms:

Dhananjay Nene's two posts on the subject:

Functional Programming With Python - Part 1

Functional Programming With Python – Part 2 - Useful Python Constructs

A StackOverflow thread: Why program functionally in Python?


- Vasudev Ram - Dancing Bison Enterprises

Wednesday, August 22, 2012

Try OCaml in the browser - with a guided tutorial


OCaml is a programming language developed at INRIA, a French national research institute for computer science and allied areas.

Here is the Wikipedia page about OCaml.

Try OCaml is a site that lets you try out OCaml in the browser, using a step-by-step guided tutorial. The Try OCaml site is by OCamlPro.com, a company that supports OCaml and has ties to the OCaml group at INRIA.

Their site has a page with a section titled Why OCaml, which gives some reasons for using OCaml.

OCaml is used by a UK-based company called Coherent Graphics. I had come across them a while ago when checking out various PDF processing libraries. Their CamlPDF is a free PDF processing library written in OCaml. But it also is the basis for PDF library support in multiple other languages. From their site:

[ This is CamlPDF, an OCaml library for reading, writing and manipulating Adobe portable document files.

CamlPDF consists of a set of low level modules for representing, reading and writing the basic structure of PDF, together with an initial attempt at a higher level API.

CamlPDF is released under a BSD licence with special exceptions. See the LICENCE file in the source for details.

CamlPDF forms the basis of our PDF Command-line Toolkit and .NET PDF Toolkit, our PDF Editor for Mac OS X and the PDF import for a major commercial vector graphics package. ]

Inspired by nature.
- dancingbison.com | @vasudevram | jugad2.blogspot.com