Command-line Arguments

On your computer, create a file called test2.py that contains these two lines:

import sys
print('Program arguments:', sys.argv)

Now, use your version of Python to run this program. Here’s how it might look in a Linux or Mac OS X terminal window using a standard shell program:

$ python test2.py
Program arguments: ['test2.py']
$ python test2.py tra la la
Program arguments: ['test2.py', 'tra', 'la', 'la']

 

Modules

A module is just a file of Python code.

We refer to code of other modules by using the import statement. This makes the code and variables in the imported module available to your program.

Import a module

We also used imports in two different ways:

• The main program called import report and then ran report.get_description().
• The get_description() function in report.py called from random import choice and then ran choice(possibilities).

The module-qualified name (random.choice) is safer but requires a little more typing.

Let’s say the weather of Melbourne is random play : <, so the weather reporter just pick up a weather randomly, hahaha.

Here’s the main program (call it weatherman.py):

import report
description = report.get_description()
print("Today's weather:", description)

And here is the module (report.py):

def get_description(): # see the docstring below?
"""Return random weather, just like the pros"""

from random import choice
possibilities = ['rain', 'snow', 'sleet', 'fog', 'sun', 'who knows]    
return choice(possibilities)
or we can import choice in the other way:
>>> import random
>>> def get_description():
... possibilities = ['rain', 'snow', 'sleet', 'fog', 'sun', 'who knows']
... return random.choice(possibilities)
The built-in function:
random.choice(seq)

Return a random element from the non-empty sequence seq. If seq is empty, raises IndexError.

Import a Module with Another Name

 

In our main weatherman.py program, we called import report. But what if you have another module with the same name or want to use a name that is more mnemonic or shorter? In such a situation, you can import using an alias. Let’s use the alias wr:

import report as wr
Import Only What You Want from a Module

With Python, you can import one or more parts of a module. Each part can keep its original name or you can give it an alias. First, let’s import get_description() from the report module with its original name:

from report import get_description
description = get_description()
print("Today's weather:", description)
Search module path

 

Where does Python look for files to import? It uses a list of directory names and ZIP archive files stored in the standard sys module as the variable path. You can access and modify this list. Here’s the value of sys.path for Python 3.3 on my Mac:

>>> import sys
>>> for place in sys.path:
... print(place)

Python looks in the current directory first when you try to import something: “import report”  looks for report.py in current directory first.
The first match will be used.

 

Exploring built-in modules

You can find the standard library here: http://docs.python.org/2/library/

Two very important functions come in handy when exploring modules in Python – the dir and help functions.

We can look for which functions are implemented in each module by using the dir function.

Writing modules

 

Writing Python modules is very simple. To create a module of your own, simply create a new .py file with the module name, and then import it using the Python file name (without the .py extension) using the import command.

Packages

To allow Python applications to scale even more, you can organize modules into file hierarchies called packages.

Packages are namespaces which contain multiple packages and modules themselves.

Writing packages

To make a package, you can group multiple modules into one directory, and you’ll need one more thing in the sources directory: a file named __init__.py. This can be empty, but Python needs it to treat the directory containing __init__.py as a package.

Each package in Python is a directory which MUST contain a special file called __init__.py. This file can be empty, and it indicates that the directory it contains is a Python package, so it can be imported the same way a module can be imported.

If we create a directory called foo, which marks the package name, we can then create a module inside that package called bar. We also must not forget to add the __init__.py file inside the foo directory.

To use the module bar:

from foo import bar

 

Handle missing keys with setdefault() and defaultdict()

 

Trying to access a dictionary with a nonexistent key raises an exception. Usually, a Python dictionary throws a KeyError if you try to get an item with a key that is not currently in the dictionary. Using the dictionary get() function to return a default value avoids an exception.

Setdefault()

 

The setdefault() function is like get(), but also assigns an item to the dictionary if the key is missing:

>>> periodic_table = {'Hydrogen': 1, 'Helium': 2}
>>> print(periodic_table)
 {'Helium': 2, 'Hydrogen': 1}

If the key was not already in the dictionary, the new value is used:

>> carbon = periodic_table.setdefault('Carbon', 12)
>>> carbon
 12
>>> periodic_table
 {'Helium': 2, 'Carbon': 12, 'Hydrogen': 1}

If we try to assign a different default value to an existing key, the original value is returned and nothing is changed:

>> helium = periodic_table.setdefault('Helium', 947)
>>> helium
2
>>> periodic_table
 {'Helium': 2, 'Carbon': 12, 'Hydrogen': 1}

 

Defaultdict

 

Defaultdict() is similar, but specifies the default value for any new key up front, when the dictionary is created. Its argument is a function. The argument to defaultdict() is a function that returns the value to be assigned to a missing key.

>>> from collections import defaultdict
>>> periodic_table = defaultdict(int)
 Now, any missing value will be an integer (int), with the value 0:
>>> periodic_table['Hydrogen'] = 1
>>> periodic_table['Lead']
 0
>>> periodic_table
 defaultdict(<class 'int'>, {'Lead': 0, 'Hydrogen': 1})

>>> periodic_table['Leadsec']
 0
>>> periodic_table
 defaultdict(<type 'int'>, {'Leadsec': 0, 'Hydrogen': 1, 'Lead': 0})

we can define our own function as the argument:

>>> def no_idea():
 return 'Huh?'

>>> bestiary=defaultdict(no_idea)
>>> bestiary['A']='Abominable Snowman'
>>> bestiary['B']='Besilisk'
>>> bestiary['A']
 'Abominable Snowman'
>>> bestiary['B']
 'Besilisk'
>>> bestiary['C']
 'Huh?'
>>> bestiary
 defaultdict(<function no_idea at 0x00000000029F7208>, {'A': 'Abominable Snowman', 'C': 'Huh?', 'B': 'Besilisk'})

You can use lambda to define your default-making function right inside the call:

>>> bestiary = defaultdict(lambda: 'Huh?')
>>> bestiary['E']
 'Huh?

 

Using int is one way to make your own counter:

>>>from collections import defaultdict
 >>> food_counter = defaultdict(int)
 >>> for food in ['spam', 'spam', 'eggs', 'spam']:
 ... food_counter[food] += 1
 ...

>>> dict_counter.items()
 [('eggs', 1), ('spam', 3)]
 >>> for food, count in food_counter.items():
 ... print(food, count)
 ...
 eggs 1
 spam 3

The method items() returns a list of dict’s (key, value) tuple pairs.

Counter()

The counter counts the list item.

>>> from collections import Counter
 >>> breakfast = ['spam', 'spam', 'eggs', 'spam']
 >>> breakfast_counter = Counter(breakfast)
 >>> breakfast_counter
 Counter({'spam': 3, 'eggs': 1})

The most_common() function returns all elements in descending order, or just the top count elements if given a count:

>> breakfast_counter.most_common()
 [('spam', 3), ('eggs', 1)]
>>> breakfast_counter.most_common(1)
 [('spam', 3)]

You can combine counters. First, let’s see again what’s in breakfast_counter:

>>> breakfast_counter
>>> Counter({'spam': 3, 'eggs': 1})

This time, we’ll make a new list called lunch, and a counter called lunch_counter:

 >>> lunch = ['eggs', 'eggs', 'bacon']
 >>> lunch_counter = Counter(lunch)
 >>> lunch_counter
 Counter({'eggs': 2, 'bacon': 1})

The first way we combine the two counters is by addition, using +:

>>> breakfast_counter + lunch_counter
 Counter({'spam': 3, 'eggs': 3, 'bacon': 1})

you can get all items by using the union operator |:

>> breakfast_counter | lunch_counter
 Counter({'spam': 3, 'eggs': 2, 'bacon': 1})

The item ‘eggs’ was again common to both. Unlike addition, union didn’t add their counts, but picked the one with the larger count.

You subtract one counter from another by using -. What’s for breakfast but not for lunch?

>> breakfast_counter - lunch_counter
 Counter({'spam': 3})

you can get common items by using the intersection operator &:

>>> breakfast_counter & lunch_counter
 Counter({'eggs': 1})
Order the dictionary (orderedDict())

Many of the code examples in the early chapters of this book demonstrate that the order of keys in a dictionary is not  predictable: you might add keys a, b, and c in that order, but keys() might return c, a, b. Here’s a repurposed example:

>> quotes = {
 ...     'Moe': 'A wise guy, huh?',
 ...     'Larry': 'Ow!',
 ...     'Curly': 'Nyuk nyuk!',
 ...     }
 >>> for stooge in quotes:
 ...    print(stooge)
 ...
 Larry
 Curly
 Moe

An OrderedDict() remembers the order of key addition and returns  them in the same order from an iterator. Try creating an OrderedDict from a sequence of (key, value) tuples:

>>> from collections import OrderedDict
 >>> quotes = OrderedDict([
 ...     ('Moe', 'A wise guy, huh?'),
 ...     ('Larry', 'Ow!'),
 ...     ('Curly', 'Nyuk nyuk!'),
 ...     ])
 >>>
 >>> for stooge in quotes:
 ...     print(stooge)
 ...
 Moe
 Larry
 Curly

 

Print Nicely with pprint()

All of our examples have used print() (or just the variable name, in the interactive interpreter) to print things. Sometimes, the results are hard to read. We need a pretty
printer such as pprint():

>>>from pprint import pprint
>>> quotes = OrderedDict([

...     ('Moe', 'A wise guy, huh?'),
 ...     ('Larry', 'Ow!'),
 ...     ('Curly', 'Nyuk nyuk!'),
 ...     ])
 >>>

>>> print(quotes)               // Plain old print() just dumps things out

OrderedDict([('Moe', 'A wise guy, huh?'), ('Larry', 'Ow!'), ('Curly', 'Nyuk nyuk!')])

>>> pprint(quotes)               //However, pprint() tries to align elements for better readability
 {'Moe': 'A wise guy, huh?',
 'Larry': 'Ow!',
 'Curly': 'Nyuk nyuk!'}

 

 

 

More Python code

There’s an entire world of open-source, third-party Python software. Good  resources include:

• PyPi (also known as the Cheese Shop, after an old Monty Python skit)
• github
• readthedocs