Archive | July 2014

Python for Fortran programmers 8: Looking ahead


This series of posts were not a Python tutorial, just some tips for those Fortran programmers who are learning python. Once you know the basics of Python, you can focus on extensions useful to scientists.

The most essential one is Numpy, which gives python the ability to work efficiently with arrays. If you install Numpy, it is worth also installing Scipy. Scipy includes a wealth of algorithms that you probably need but you don’t want to code. From Fourier transforms and splines to minimizations and numerical integrations. There are excellent tutorials for both Numpy and Scipy and a good place to start is at http://www.scipy.org/.
Remember that although you can translate a Fortran code almost line by line into Python, the resulting code will not be optimal, neither for clarity nor efficiency. Learn to be Pythonic:
http://www.cafepy.com/article/be_pythonic/
http://blog.startifact.com/posts/older/what-is-pythonic.html
Use dictionaries, use sets, use list comprehension, and even consider using classes! Remember that almost everything is iterable in Python.
This is my last post for the series Python for Fortran programmers, but I will continue writing about Python tools that I find useful for my research. I hope they will also help other computational chemists and biophysicists.

Advertisements

Python for Fortran programmers 7: default function arguments


Python arguments can have have a default value, in which case, they become optional. Its similar to Fortran optional arguments, but the implementation and the syntax is pretty different. For immutable objects, everything works as a Fortran programmer would expect. But for mutable objects we tend to be surprised.

Type the following function:

def function(data=[]):
    data.append(1)
    return data

and call the function several times, without arguments (function()). What is going on?

As usual, you can better visualize this process if you execute the code in: http://www.pythontutor.com
But it’s easy to understand, and if you do, you won’t be confused again. The first thing to remember is that lists are mutable. The second one is that the def statement is an executable statement, which is executed when the function is defined in that line. As an example, will Hello from f1! be printed if you execute only these lines of code?

def f1():
    print("Hello from f1!")
    return 1

def f2(x=f1()):
    pass

See? You are defining functions but you are actually producing output!
So once the function is called and the object data is created, the same object is called all the time, pointing to the same data mutable object.

If you have understood everything, you should be able to predict the output of these lines:

def function(data=[]):
    data.append(1)
    return data

print(function())
print(function())
print(function())

f1 = function

def function(data=[]):
    data.append(1)
    print("Hello!")
    return data

print(function())
print(function())
print(function())
print("f1 is function:", f1 is function)

You can expand this fascinating subject here: http://effbot.org/zone/default-values.htm from where I stole the example and some ideas, or here:
http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument