$$ \newcommand{\tp}{\thinspace .} $$

 

 

 

This chapter is taken from the book A Primer on Scientific Programming with Python by H. P. Langtangen, 5th edition, Springer, 2016.

Making code for Python 2 and 3

This book applies Python version 2.7, but there is a newer version of Python called Python 3 (the current version is 3.5). Unfortunately, Python 2 programs do not work with Python 3 and vice versa. Newcomers to Python are normally guided to pick up version 3 rather than version 2, since the former has many improvements and represents the future of the language. However, for scientific computing, version 3 still lacks many useful libraries, and that is the reason why this book applies Python version 2.7.

Basic differences between Python 2 and 3

So, what are the major differences between version 2 and 3? We cover only the three differences that involve statements we have seen so far in the book.

The print statement has changed

Here are some examples on print statements in Python 2:

a = 1
print a
print 'The value of a is', a
print 'The value of a is', a,  # comma prevents newline
b = 2
print 'and b=%g' % b

The print statement is not a statement anymore, but a function in Python 3. The above code needs to be written as

a = 1
print(a)
print('The value of a is', a)
print('The value of a is', a, end=' ')  # end='' prevents newline
b = 2
print('and b=%g' % b)

Integer division is not an issue in Python 3

The expression 1/10 is 0 in Python 2, while in Python 3 it equals 0.1. Nevertheless, there are so many computer languages and tools that interpret as 1/10 integer division, so rather than relying on a language's interpretation of integer divided by integer as float division, the programmer is strongly encouraged to turn one of the operands explicitly to float, as in 1.0/10.

The raw_input function is named input in Python 3

The Python 2 code

a = float(raw_input('Give a: '))

reads

a = float(input('Give a: '))

in Python 3.

Note that in Python 2 there is an input function which equals eval applied to raw_input:

a = input('Give a: ')  # Python 2!
# Equivalent to
a = eval(raw_input('Give a: '))

Turning Python 2 code into Python 3 code

Suppose you have written some Python 2 code according to this book and want it to run under Python 3. We strongly recommend to create a common version of your program such that it works under both Python 2 and 3. This is quite easy if you use the future package (it is easily installed by pip install future).

The future package has a program futurize that can rewrite a .py file such that it works under Python 2 and 3. Let us grab a file c2f_qa.py,

C = raw_input('C=? ')
C = float(C)
F = 9.0/5*C + 32
print F

and convert it by

Terminal> futurize -w c2f_qa.py

Now c2f_qa.py has the content

from __future__ import print_function
from builtins import input
C = input('C=? ')
C = float(C)
F = 9.0/5*C + 32
print(F)

We notice that the raw_input call has been changed to input and that the print statement is a call to the print function. A simple test shows that the new file runs on both versions of Python:

Terminal> python2 c2f_qa.py
C=? 21
69.8
Terminal> python3 py3/c2f_qa.py
C=? 21
69.80000000000001

(This test requires that you have Python 3 installed.)

Note that if we change the division 9.0/5 in the file to 9/5, futurize will not make a float division out of that expression (i.e., the Python 2 meaning of the syntax is not changed). If we want all syntax to be interpreted the Python 3 way, add the --all-imports option:

Terminal> futurize -w --all-imports c2f_qa.py

The result is

from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import input
from builtins import *
C = input('C=? ')
C = float(C)
F = 9/5*C + 32
print(F)

Now, 9/5 represents float division, and the program runs under both versions of Python.

Usually, you do not want futurize to overwrite your original Python 2 program, but it is easy to let it generate the new version in a subfolder instead:

Terminal> futurize -w -n -o py23 c2f_qa.py

The generated new version of c2f_qa.py is now in py23/c2f_qa.py.

Most of the programs in this book apply the command line for input, and the programmer should fix all issues about integer division, so running futurize on the programs you have seen so far will just change the print statement. There are more challenging differences between Python 2 and 3 when one applies more advanced objects and modules.