Learning more
Learning Python is like learning… well, like learning a language! You must practice reading and writing regularly, and as you do you’ll become more and more comfortable, starting to get a feeling for how things work, and how to effectively express yourself.
Programming is a career in and of itself, so as physicists we have twice as much work to do! It takes people many years to get comfortable with any language, so try not to get too frustrated if things seem complicated at the beginning. It gets better!
When you do get stuck, ask friends and colleagues for help. One of the great things about Python is that many people around the world use it, and it’s very popular in high energy physics, so you likely already know someone who can help solve your problem. Working on code with others is a great way to learn, as you can see how other people do things, and find out tricks you didn’t know about.
Beyond other people, Google is a powerful ally. Knowing how to express your problem is important in getting the best answers quickly. Generally, including a few words as possible is a good idea, like “python dictionary delete key”, or “python read file lines”.
Stack Overflow is an excellent resource, with community-provided answers for many programming-related questions. Most problems you encounter will already be answered there, and often the answers are quite didactic, providing context and further reading, beyond just posting the code that answers the question (these answers aren’t always the ones marked as the ‘best answer’, and don’t always have the most votes).
Exploring Python
The Python standard library is a treasure-trove of useful objects and methods. We’ve gone through a tiny subset of them here, some others that might be useful to you are:
os
: Operating system functions to manipulate and query your machine and the file system, likeos.mkdir
to make directories andos.rename
.tempfile
: create files and directories in a temporary location, like/tmp
, e.g.tempfile.mkdtemp
.glob
: File name matching, to be able to do things likels folder/*.txt
in Python withglob.glob('folder/*.txt')
.subprocess
: Call shell commands withsubprocess.call(['ls', '-l', '-a'])
.time
: Get the current time withtime.localtime().tm_hour
.collections
: Usecollections.namedtuple
to create your own property-only objects.
Use>>> import collections >>> Coordinate = collections.namedtuple('Coordinate', ['x', 'y']) >>> coord = Coordinate(4.5, 2.0) >>> coord.y 2.0 >>> x, y = coord >>> x 4.5
collections.OrderedDict
for ordered dictionaries.>>> d = {'foo': 'bar', 123: 321, 'hero': 'thor'} >>> for key, value in d.items(): ... print key, value ... 123 321 foo bar hero thor >>> d = collections.OrderedDict([('foo', 'bar'), (123, 321)]) >>> d.update([('hero', 'thor')]) >>> for key, value in d.items(): ... print key, value ... foo bar 123 321 hero thor
collections.defaultdict
is useful for creating dictionaries that will create automatically create values when a previously undefined key is accessed.>>> d = collections.defaultdict(int) >>> d['foo'] += 1 >>> print d, d['foo'], d['bar'] defaultdict(<type 'int'>, {'foo': 1}) 1 0
Conventional coding
‘Pythonic code’ is code that follows the conventions of the wider Python community. Lots of people write Python, and by following certain stylistic conventions it makes it easier for everyone to read each other’s code (as they say: ‘you spend 90% of your time reading code, and 10% writing it’).
Pythonic style emphasises clean, readable code, with consistent formatting and
useful comments. The most important thing is to be consistent. You can consult
PEP8, the official Python style recommendations, if you're unsure or
want to settle a dispute like lower_case_functions
versus
upperCaseFunctions
. Which of these two methods is easier to read?
import time
def myFunc(x,y,verbose = True, fast='yes'):
"""Do the thing."""
z=( x *y ) /2
if verbose == False:
print x,y, z
if not fast:
time.sleep( 1 )
return z* z
def my_func(x, y, verbose=True, fast=True):
"""Return ((x*y)/2)**2.
Keyword arguments:
x, y -- Values used in the computation
verbose -- Print computation information
fast -- If True, sleep for 1 second before returning
"""
z = (x*y)/2
if verbose:
print x, y, z
# Should probably remove this functionality
if not fast:
time.sleep(1)
return z*z
The Zen of Python summarises the ‘philosophy’ that the language tries to follow. See what you think!
>>> import this
“There should be one-- and preferably only one --obvious way to do it”
If there isn't, you might be trying to come at a problem the wrong way.