SaltyCrane Blog — Notes on JavaScript and web development

PyQt 4.3 Simple QAbstractListModel/ QlistView example

import sys
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 

#################################################################### 
def main(): 
    app = QApplication(sys.argv) 
    w = MyWindow() 
    w.show() 
    sys.exit(app.exec_()) 

#################################################################### 
class MyWindow(QWidget): 
    def __init__(self, *args): 
        QWidget.__init__(self, *args) 

        # create table
        list_data = [1,2,3,4]
        lm = MyListModel(list_data, self)
        lv = QListView()
        lv.setModel(lm)

        # layout
        layout = QVBoxLayout()
        layout.addWidget(lv) 
        self.setLayout(layout)

#################################################################### 
class MyListModel(QAbstractListModel): 
    def __init__(self, datain, parent=None, *args): 
        """ datain: a list where each item is a row
        """
        QAbstractListModel.__init__(self, parent, *args) 
        self.listdata = datain
 
    def rowCount(self, parent=QModelIndex()): 
        return len(self.listdata) 
 
    def data(self, index, role): 
        if index.isValid() and role == Qt.DisplayRole:
            return QVariant(self.listdata[index.row()])
        else: 
            return QVariant()

####################################################################
if __name__ == "__main__": 
    main()

How to pass command line arguments to your Python program

Here is an example for quick reference. argv holds the program name at index 0. That's why we start at 1.

#!/usr/bin/python

import sys

def main():
    # print command line arguments
    for arg in sys.argv[1:]:
        print arg

if __name__ == "__main__":
    main()

Try it out:
$ python cmdline_args.py arg1 arg2 arg3
arg1
arg2
arg3

See also:
sys module documentation
getopt module documentation
Guido van Rossum's post

Tabular data structure conversion in Python

Here is a Python library to convert between various tabular data structures including list of lists, list of dicts, dict of lists, and dict of dicts. My original attempts at these conversions required that the data be rectangular (e.g. each column has the same number of elements). However, further research led me to this ASPN Recipe which uses map to transpose a list of lists even if it is not rectangular. With help from the mailing list, I rewrote the recipe without using lambda. (I did this because Guido suggested not to use map with lambda for the sake of clarity.)

I used list comprehensions wherever possible and a functional/ declarative approach in general. It is likely there is a better way to do many of these conversions. (After all, I just learned how to use zip().) In particular, the functions with the comment "Better way?" use a number of the other conversion functions in series to achieve the desired result. All of these could be optimized. Feedback on better methods is welcome.

Example data structures

Here are examples of the 8 different tabular data structures. Note that if a transpose is performed (i.e. rows switched with columns or vice versa), the output is padded with None. Otherwise, it is left as is.

# lorl- list of lists where each inner list is a row
lorl = [
    ['a1', 'b1', 'c1'],    # row 1
    ['a2', 'b2', 'c2'],    # row 2
    ['a3', 'b3', 'c3'],    # row 3
    ['a4', 'b4',     ],    # row 4
    ]

# locl- list of lists where each inner list is a column
locl = [
    ['a1', 'a2', 'a3', 'a4'],    # col a
    ['b1', 'b2', 'b3', 'b4'],    # col b
    ['c1', 'c2', 'c3',     ],    # col c
    ]

# lord- list of dicts where each dict is a row
lord = [
    {'a':'a1', 'b':'b1', 'c':'c1'},   # row 1
    {'a':'a2', 'b':'b2', 'c':'c2'},   # row 2
    {'a':'a3', 'b':'b3', 'c':'c3'},   # row 3
    {'a':'a4', 'b':'b4',         },   # row 4
    ]

# locd- list of dicts where each dict is a column
locd = [
    {1:'a1', 2:'a2', 3:'a3', 4:'a4'},         # col a
    {1:'b1', 2:'b2', 3:'b3', 4:'b4'},         # col b
    {1:'c1', 2:'c2', 3:'c3',       },         # col c
    ]

# dorl- dict of lists where each list is a row
dorl = {
    1: ['a1', 'b1', 'c1'],            # row 1
    2: ['a2', 'b2', 'c2'],            # row 2
    3: ['a3', 'b3', 'c3'],            # row 3
    4: ['a4', 'b4',     ],            # row 4
    }
# docl- dict of lists where each list is a column
docl = {
    'a': ['a1', 'a2', 'a3', 'a4'],          # column a
    'b': ['b1', 'b2', 'b3', 'b4'],          # column b
    'c': ['c1', 'c2', 'c3',     ],          # column c
    }

# dord- dict of dicts where each inner dict is a row
dord = {
    1: {'a':'a1', 'b':'b1', 'c':'c1'},  # row 1
    2: {'a':'a2', 'b':'b2', 'c':'c2'},  # row 2
    3: {'a':'a3', 'b':'b3', 'c':'c3'},  # row 3
    4: {'a':'a4', 'b':'b4',         },  # row 4
    }

# docd- dict of dicts where each inner dict is a column
docd = {
    'a': {1:'a1', 2:'a2', 3:'a3', 4:'a4'},    # column a
    'b': {1:'b1', 2:'b2', 3:'b3', 4:'b4'},    # column b
    'c': {1:'c1', 2:'c2', 3:'c3',       },    # column c
    }

# list of row keys and column keys
rowkeys = [1, 2, 3, 4]
colkeys = ['a', 'b', 'c']

Code

Below is the library of functions.

"""tabular.py
Functions to convert tabular data structures
The following data structures are supported:
lorl- list of lists where each inner list is a row
locl- list of lists where each inner list is a column
lord- list of dicts where each dict is a row
locd- list of dicts where each dict is a column
dorl- dict of lists where each list is a row
docl- dict of lists where each list is a column
dord- dict of dicts where each inner dict is a row
docd- dict of dicts where each inner dict is a column
"""
#-------------------------------------------------------
# from lorl to ...
#-------------------------------------------------------
def lorl2locl(lorl):
    return [list(col) for col in map(None, *lorl)]

def lorl2lord(lorl, colkeys):
    return [dict(zip(colkeys, row)) for row in lorl]

def lorl2locd(lorl, rowkeys):
    # better way?
    return locl2locd(lorl2locl(lorl), rowkeys)

def lorl2dorl(lorl, rowkeys):
    return dict(zip(rowkeys, [row for row in lorl]))

def lorl2docl(lorl, colkeys):
    # better way?
    return locl2docl(lorl2locl(lorl), colkeys)

def lorl2dord(lorl, rowkeys, colkeys):
    return dict(zip(rowkeys, [dict(zip(colkeys, row))
                              for row in lorl]))

def lorl2docd(lorl, rowkeys, colkeys):
    # better way?
    return dict(zip(colkeys, [dict(zip(rowkeys, col))
                              for col in lorl2locl(lorl)]))

#-------------------------------------------------------
# from locl to ...
#-------------------------------------------------------
def locl2lorl(locl):
    return [list(row) for row in map(None, *locl)]

def locl2lord(locl, colkeys):
    # better way?
    return lorl2lord(locl2lorl(locl), colkeys)

def locl2locd(locl, rowkeys):
    return [dict(zip(rowkeys, col)) for col in locl]

def locl2dorl(locl, rowkeys):
    # better way?
    return dict(zip(rowkeys, [row for row in locl2lorl(locl)]))

def locl2docl(locl, colkeys):
    return dict(zip(colkeys, locl))

def locl2dord(locl, rowkeys, colkeys):
    # better way?
    return dict(zip(rowkeys, [dict(zip(colkeys, row))
                              for row in locl2lorl(locl)]))

def locl2docd(locl, rowkeys, colkeys):
    return dict(zip(colkeys, [dict(zip(rowkeys, col))
                              for col in locl]))

#-------------------------------------------------------
# from lord to ...
#-------------------------------------------------------
def lord2lorl(lord, colkeys):
    return [[row[key] for key in colkeys if key in row]
            for row in lord]

def lord2locl(lord, colkeys):
    # better way?
    return lorl2locl(lord2lorl(lord, colkeys))

def lord2locd(lord, rowkeys, colkeys):
    return [dict([(rkey, row[ckey])
                  for rkey, row in zip(rowkeys, lord) if ckey in row])
            for ckey in colkeys]

def lord2dorl(lord, rowkeys, colkeys):
    return dict(zip(rowkeys, [[row[ckey]
                               for ckey in colkeys if ckey in row]
                              for row in lord]))

def lord2docl(lord, colkeys):
    return dict(zip(colkeys, [[row[ckey]
                               for row in lord if ckey in row]
                              for ckey in colkeys]))

def lord2dord(lord, rowkeys):
    return dict(zip(rowkeys, lord))

def lord2docd(lord, rowkeys, colkeys):
    return dict(zip(colkeys,
                    [dict(zip(rowkeys,
                              [row[ckey]
                               for row in lord if ckey in row]))
                     for ckey in colkeys]))

#-------------------------------------------------------
# from locd to ...
#-------------------------------------------------------
def locd2lorl(locd, rowkeys):
    # better way?
    return locl2lorl(locd2locl(locd, rowkeys))

def locd2locl(locd, rowkeys):
    return [[col[key] for key in rowkeys if key in col]
            for col in locd]

def locd2lord(locd, rowkeys, colkeys):
    return [dict([(ckey, col[rkey])
                  for ckey, col in zip(colkeys, locd) if rkey in col])
            for rkey in rowkeys]

def locd2dorl(locd, rowkeys):
    return dict(zip(rowkeys, [[col[rkey]
                               for col in locd if rkey in col]
                              for rkey in rowkeys]))

def locd2docl(locd, rowkeys, colkeys):
    return dict(zip(colkeys, [[col[rkey]
                               for rkey in rowkeys if rkey in col]
                              for col in locd]))

def locd2dord(locd, rowkeys, colkeys):
    return dict(zip(rowkeys,
                    [dict(zip(colkeys,
                              [col[rkey]
                               for col in locd if rkey in col]))
                     for rkey in rowkeys]))

def locd2docd(locd, colkeys):
    return dict(zip(colkeys, locd))

#-------------------------------------------------------
# from dorl to ...
#-------------------------------------------------------
def dorl2lorl(dorl, rowkeys):
    return [dorl[key] for key in rowkeys]

def dorl2locl(dorl, rowkeys):
    # better way?
    return lorl2locl(dorl2lorl(dorl, rowkeys))

def dorl2lord(dorl, rowkeys, colkeys):
    return [dict(zip(colkeys, dorl[rkey]))
            for rkey in rowkeys]

def dorl2locd(dorl, rowkeys):
    # better way?
    return locl2locd(lorl2locl(dorl2lorl(dorl, rowkeys)), rowkeys)

def dorl2docl(dorl, rowkeys, colkeys):
    # better way?
    return locl2docl(lorl2locl(dorl2lorl(dorl, rowkeys)), colkeys)

def dorl2dord(dorl, rowkeys, colkeys):
    # better way?
    return lorl2dord(dorl2lorl(dorl, rowkeys), rowkeys, colkeys)

def dorl2docd(dorl, rowkeys, colkeys):
    # better way?
    return locl2docd(lorl2locl(dorl2lorl(dorl, rowkeys)),
                     rowkeys, colkeys)

#-------------------------------------------------------
# from docl to ...
#-------------------------------------------------------
def docl2lorl(docl, colkeys):
    # better way?
    return locl2lorl(docl2locl(docl, colkeys))

def docl2locl(docl, colkeys):
    return [docl[key] for key in colkeys]

def docl2lord(docl, rowkeys, colkeys):
    # better way?
    return lorl2lord(locl2lorl(docl2locl(docl, colkeys)), colkeys)

def docl2locd(docl, rowkeys, colkeys):
    #
    return [dict(zip(rowkeys, docl[ckey]))
            for ckey in colkeys]

def docl2dorl(docl, rowkeys, colkeys):
    # better way?
    return lorl2dorl(locl2lorl(docl2locl(docl, colkeys)), rowkeys)

def docl2dord(docl, rowkeys, colkeys):
    # better way?
    return lorl2dord(locl2lorl(docl2locl(docl, colkeys)),
                     rowkeys, colkeys)

def docl2docd(docl, rowkeys, colkeys):
    # better way?
    return locl2docd(docl2locl(docl, colkeys), rowkeys, colkeys)

#-------------------------------------------------------
# from dord to ...
#-------------------------------------------------------
def dord2lorl(dord, rowkeys, colkeys):
    return [[dord[rkey][ckey]
             for ckey in colkeys if ckey in dord[rkey]]
            for rkey in rowkeys if rkey in dord]

def dord2locl(dord, rowkeys, colkeys):
    # better way?
    return lorl2locl(dord2lorl(dord, rowkeys, colkeys))

def dord2lord(dord, rowkeys):
    return [dord[rkey] for rkey in rowkeys]

def dord2locd(dord, rowkeys, colkeys):
    # better way?
    return lord2locd(dord2lord(dord, rowkeys), rowkeys, colkeys)

def dord2dorl(dord, rowkeys, colkeys):
    # don't need zip
    return dict([(rkey, [dord[rkey][ckey]
                         for ckey in colkeys if ckey in dord[rkey]])
                 for rkey in rowkeys])

def dord2docl(dord, rowkeys, colkeys):
    # better way?
    return locl2docl(lorl2locl(dord2lorl(dord, rowkeys, colkeys)),
                     colkeys)

def dord2docd(dord, rowkeys, colkeys):
    # better way?
    return locl2docd(lorl2locl(dord2lorl(dord, rowkeys, colkeys)),
                     rowkeys, colkeys)

#-------------------------------------------------------
# from docd to ...
#-------------------------------------------------------
def docd2lorl(docd, rowkeys, colkeys):
    # better way?
    return locl2lorl(docd2locl(docd, rowkeys, colkeys))

def docd2locl(docd, rowkeys, colkeys):
    return [[docd[ckey][rkey]
             for rkey in rowkeys if rkey in docd[ckey]]
            for ckey in colkeys if ckey in docd]

def docd2lord(docd, rowkeys, colkeys):
    # better way?
    return locd2lord(docd2locd(docd, colkeys), rowkeys, colkeys)

def docd2locd(docd, colkeys):
    return [docd[ckey] for ckey in colkeys]

def docd2dorl(docd, rowkeys, colkeys):
    # better way?
    return lorl2dorl(locl2lorl(docd2locl(docd, rowkeys, colkeys)),
                     rowkeys)

def docd2docl(docd, rowkeys, colkeys):
    # don't need zip
    return dict([(ckey, [docd[ckey][rkey]
                         for rkey in rowkeys if rkey in docd[ckey]])
                 for ckey in colkeys])

def docd2dord(docd, rowkeys, colkeys):
    # better way?
    return lorl2dord(locl2lorl(docd2locl(docd, rowkeys, colkeys)),
                     rowkeys, colkeys)

Iterating through two lists in parallel using zip()

From the Python docs, zip returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. This is useful for iterating over two lists in parallel. For example, if I have two lists, I can get the first element of both lists, then the second element of both lists, then the third, etc.

Python 2.5.1 (r251:54863, May 18 2007, 16:56:43)
[GCC 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [1,2,3]
>>> b = ['a','b','c']
>>> for i,j in zip(a,b):
...     print i, j
...
1 a
2 b
3 c
>>> 

If the lists are different lengths, zip truncates to the length of the shortest list. Using map with None is similar to zip except the results are padded with None.

>>> a = [1,2,3]
>>> b = ['a','b','c','d']
>>> zip(a,b)
[(1, 'a'), (2, 'b'), (3, 'c')]
>>> map(None,a,b)
[(1, 'a'), (2, 'b'), (3, 'c'), (None, 'd')]
>>> 

If I have a list of keys and a list of values, I can create a dictionary by passing the output of zip to dict.

>>> mykeys = ['a', 'b', 'c']
>>> myvalues = [1, 2, 3]
>>> dict(zip(mykeys, myvalues))
{'a': 1, 'c': 3, 'b': 2}
>>> 

See also this thread on the Python mailing list: Iterating through two lists

How to use grep and find to search specific files

I often use grep to search through the text of my files for search terms such as a variable or function name. For example, since xrange is being removed from Python 3000, I'd like to search for all the occurrences of xrange. Here is how to search all my Python files in the current directory:

$ grep --color "xrange" *.py

Which outputs something like:

dol2lol.py:    for i in xrange(len(dol[keylist[0]])):
dol2lol.py:            for i in xrange(len(dol[keylist[0]]))]
lol2lod.py:#     for i in xrange(len(locols[0])):
lol2lod.py:#         for j in xrange(len(keylist)):
lol2lod.py:    return [dict([(keylist[j], locols[j][i]) for j in xrange(len(keylist))])
lol2lod.py:            for i in xrange(len(locols[0]))]
table_modelview.py:        for row in xrange(nrows):

The above command only works for the current directory. If I want to recurse into subdirectories, I can use:

$ grep -r --color "xrange" .

However, this command often produces too many results because I cannot specify which files to search. To gain better control over which files are searched, I can use grep in combination with the find command. Here is an example which recurses into subdirectories and searches all my Python files for xrange. (I know it's hard to imagine when xrange would be inside anything other than a Python file, but hey, it's just an example.

$ find . -name '*.py' -exec grep --color 'xrange' {} +

Usually, using find with -exec is very slow and xargs is used to gain performance. However, thanks to the tip from Some notes about find, I used the + expression at the end of the commandline which avoids the fork/exec overhead, without using xargs.

As a final example, here is how I search for the text #define in all files in my current directory, excluding my backup files (*~, *.orig, *.bak). In this example, I don't want to recurse into directories, so I set -maxdepth to 1. Note, Some notes about find has some other options about limiting the depth portably, but this option worked for me. Note, this is similar to the command I use as my Emacs grep.

find . -maxdepth 1 ! -regex '.*~$' ! -regex '.*\.orig$' \
    ! -regex '.*\.bak$' -exec grep --color "#define" {} +

Using grep to exclude a pattern

If you want to find all the lines that DO NOT match a particular pattern, use the -v (or --invert-match) option to invert the match and select non-matching lines.

How to convert a dictionary of lists to a list of lists in Python

UPDATE: See my new post, Tabular data structure conversion in Python for an updated method which handles non-rectangular data.

The functions below convert a rectangular dictionary of lists to a list of lists. Each list in the dictionary must be the same length. Additionally, a list of keys is required as an input argument to specify the desired ordering of the columns in the returned list of lists. If this were not specified, the order of the columns would be unknown since items in a dictionary are unordered.

The converted list of lists can contain either a list of rows or a list of columns. The first two functions create a lists of rows; the last two create a list of columns. (I consider each list in the dict of lists as a column, and all items for a given index a row.)

I also compare the imperative/procedural approach to the declarative/functional approach. I like the declarative/functional approach because it is so concise, and, I believe, a little faster as well.

#!/usr/bin/python

# IMPERATIVE/PROCEDURAL APPROACH
def byrow_imper(dol, keylist):
    """Converts a dictionary of lists to a list of lists using the
    values of the dictionaries. Each list must be the same length.
       dol: dictionary of lists
       keylist: list of keys, ordered as desired
       Returns: a list of lists where the inner lists are rows. 
         i.e. returns a list of rows. """
    lol = []
    for i in xrange(len(dol[keylist[0]])):
        row = []
        for key in keylist:
            row.append(dol[key][i])
        lol.append(row)
    return lol

# DECLARATIVE/FUNCTIONAL APPROACH
def byrow_decl(dol, keylist):
    """Converts a dictionary of lists to a list of lists using the
    values of the dictionaries. Each list must be the same length.
       dol: dictionary of lists
       keylist: list of keys, ordered as desired
       Returns: a list of lists where the inner lists are rows. 
         i.e. returns a list of rows. """
    return [[dol[key][i] for key in keylist] 
            for i in xrange(len(dol[keylist[0]]))]

# IMPERATIVE/PROCEDURAL APPROACH
def bycol_imper(dol, keylist):
    """Converts a dictionary of lists to a list of lists using the
    values of the dictionaries. Each list must be the same length.
       dol: dictionary of lists
       keylist: list of keys, ordered as desired
       Returns: a list of lists where the inner lists are columns. 
         i.e. returns a list of columns. """
    lol = []
    for key in keylist:
        col = []
        for item in dol[key]:
            col.append(item)
        lol.append(col)
    return lol

# DECLARATIVE/FUNCTIONAL APPROACH
def bycol_decl(dol, keylist):
    """Converts a dictionary of lists to a list of lists using the
    values of the dictionaries. Each list must be the same length.
       dol: dictionary of lists
       keylist: list of keys, ordered as desired
       Returns: a list of lists where the inner lists are columns. 
         i.e. returns a list of columns. """
    return [[item for item in dol[key]] for key in keylist]

# TEST
if __name__ == "__main__": 
    dol = {
        'a': ['a1', 'a2', 'a3'],   # column a
        'b': ['b1', 'b2', 'b3'],   # column b
        'c': ['c1', 'c2', 'c3'],   # column c
        }
    keylist = ['a', 'b', 'c']
    print byrow_imper(dol, keylist)
    print byrow_decl(dol, keylist)
    print bycol_imper(dol, keylist)
    print bycol_decl(dol, keylist)

Results:
[['a1', 'b1', 'c1'], ['a2', 'b2', 'c2'], ['a3', 'b3', 'c3']]
[['a1', 'b1', 'c1'], ['a2', 'b2', 'c2'], ['a3', 'b3', 'c3']]
[['a1', 'a2', 'a3'], ['b1', 'b2', 'b3'], ['c1', 'c2', 'c3']]
[['a1', 'a2', 'a3'], ['b1', 'b2', 'b3'], ['c1', 'c2', 'c3']]

How to convert a list of dictionaries to a list of lists in Python

UPDATE: See my new post, Tabular data structure conversion in Python for an updated method which handles non-rectangular data.

The functions below convert a rectangular list of dictionaries to a list of lists. Each dictionary in the list must have the same keys. Additionally, a list of keys is required as an input argument to specify the desired ordering of the columns in the returned list of lists. If this were not specified, the order of the columns would be unknown since items in a dictionary are unordered.

The converted list of lists can contain either a list of rows or a list of columns. The first two functions create a lists of rows; the last two create a list of columns. (I consider each dict in the list of dicts as a row, and all values for a given key as a column.)

I also compare the imperative/procedural approach to the declarative/functional approach. I like the declarative/functional approach because it is so concise, and, I believe, a little faster as well.

#!/usr/bin/python

def byrow_imper(lod, keylist):
    """Converts a list of dictionaries to a list of lists using the
    values of the dictionaries. Assumes that each dictionary has the
    same keys. 
       lod: list of dictionaries
       keylist: list of keys, ordered as desired
       Returns: a list of lists where the inner lists are rows. 
         i.e. returns a list of rows. """
    # imperative/procedural approach
    lol = []
    for row in lod:
        row2 = []
        for key in keylist:
            row2.append(row[key])
        lol.append(row2)
    return lol

def byrow_decl(lod, keylist):
    """Converts a list of dictionaries to a list of lists using the
    values of the dictionaries. Assumes that each dictionary has the
    same keys. 
       lod: list of dictionaries
       keylist: list of keys, ordered as desired
       Returns: a list of lists where the inner lists are rows. 
         i.e. returns a list of rows. """
    # declarative/functional approach
    return [[row[key] for key in keylist] for row in lod]

def bycol_imper(lod, keylist):
    """Converts a list of dictionaries to a list of lists using the
    values of the dictionaries. Assumes that each dictionary has the
    same keys. 
       lod: list of dictionaries
       keylist: list of keys, ordered as desired
       Returns: a list of lists where the inner lists are columns. 
         i.e. returns a list of columns. """
    # imperative/procedural approach
    lol = []
    for key in keylist:
        col = []
        for row in lod:
            col.append(row[key])
        lol.append(col)
    return lol

def bycol_decl(lod, keylist):
    """Converts a list of dictionaries to a list of lists using the
    values of the dictionaries. Assumes that each dictionary has the
    same keys. 
       lod: list of dictionaries
       keylist: list of keys, ordered as desired
       Returns: a list of lists where the inner lists are columns. 
         i.e. returns a list of columns. """
    # declarative/functional approach
    return  [[row[key] for row in lod] for key in keylist]

if __name__ == "__main__": 
    lod = [
        {'a':1, 'b':2, 'c':3},
        {'a':4, 'b':5, 'c':6},
        {'a':7, 'b':8, 'c':9},
        ]
    keylist = ['a', 'b', 'c']
    print byrow_imper(lod, keylist)
    print byrow_decl(lod, keylist)
    print bycol_imper(lod, keylist)
    print bycol_decl(lod, keylist)

Results:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

How to get syntax highlighting in Blogger with Pygments

  • $ sudo easy_install Pygments
  • $ pygmentize -f html myscript.py
  • copy html code to blog post
  • $ pygmentize -S default -f html
  • copy css to Blogger template

The Pygments website is located at: http://pygments.org

Update 5/21/2008: Andrew K. emailed me about a javascript syntax highlighter called highlight.js at http://softwaremaniacs.org/soft/highlight/en/. I have not tried it, but it looks pretty cool.

PyQt 4.3 QTableView / QAbstractTableModel sorting example

It took me a while to figure out why QTableView's setSortingEnabled method wasn't working. It turns out the sort method in QAbstractItemModel is not implemented. So I had to implement it myself. Hence, my previous post, How to sort a table by columns in Python. I'm not sure if this is the best way to implement the sort method, but I couldn't find anything else out there, and this seems to work for me.

import re
import operator
import os
import sys 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 
 
def main(): 
    app = QApplication(sys.argv) 
    w = MyWindow() 
    w.show() 
    sys.exit(app.exec_()) 
 
class MyWindow(QWidget): 
    def __init__(self, *args): 
        QWidget.__init__(self, *args) 

        # create table
        self.get_table_data()
        table = self.createTable() 
         
        # layout
        layout = QVBoxLayout()
        layout.addWidget(table) 
        self.setLayout(layout) 

    def get_table_data(self):
        stdouterr = os.popen4("dir c:\\")[1].read()
        lines = stdouterr.splitlines()
        lines = lines[5:]
        lines = lines[:-2]
        self.tabledata = [re.split(r"\s+", line, 4)
                     for line in lines]

    def createTable(self):
        # create the view
        tv = QTableView()

        # set the table model
        header = ['date', 'time', '', 'size', 'filename']
        tm = MyTableModel(self.tabledata, header, self) 
        tv.setModel(tm)

        # set the minimum size
        tv.setMinimumSize(400, 300)

        # hide grid
        tv.setShowGrid(False)

        # set the font
        font = QFont("Courier New", 8)
        tv.setFont(font)

        # hide vertical header
        vh = tv.verticalHeader()
        vh.setVisible(False)

        # set horizontal header properties
        hh = tv.horizontalHeader()
        hh.setStretchLastSection(True)

        # set column width to fit contents
        tv.resizeColumnsToContents()

        # set row height
        nrows = len(self.tabledata)
        for row in xrange(nrows):
            tv.setRowHeight(row, 18)

        # enable sorting
        tv.setSortingEnabled(True)

        return tv
 
class MyTableModel(QAbstractTableModel): 
    def __init__(self, datain, headerdata, parent=None, *args): 
        """ datain: a list of lists
            headerdata: a list of strings
        """
        QAbstractTableModel.__init__(self, parent, *args) 
        self.arraydata = datain
        self.headerdata = headerdata
 
    def rowCount(self, parent): 
        return len(self.arraydata) 
 
    def columnCount(self, parent): 
        return len(self.arraydata[0]) 
 
    def data(self, index, role): 
        if not index.isValid(): 
            return QVariant() 
        elif role != Qt.DisplayRole: 
            return QVariant() 
        return QVariant(self.arraydata[index.row()][index.column()]) 

    def headerData(self, col, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return QVariant(self.headerdata[col])
        return QVariant()

    def sort(self, Ncol, order):
        """Sort table by given column number.
        """
        self.emit(SIGNAL("layoutAboutToBeChanged()"))
        self.arraydata = sorted(self.arraydata, key=operator.itemgetter(Ncol))        
        if order == Qt.DescendingOrder:
            self.arraydata.reverse()
        self.emit(SIGNAL("layoutChanged()"))

if __name__ == "__main__": 
    main()

How to sort a table by columns in Python

I have a 2-dimensional table of data implemented as a list of lists in Python. I would like to sort the data by an arbitrary column. This is a common task with tabular data. For example, Windows Explorer allows me to sort the list of files by Name, Size, Type, or Date Modified. I tried the code from this article, however, if there are duplicate entries in the column being sorted, the duplicates are removed. This is not what I wanted, so I did some further searching, and found a nice solution from the HowTo/Sorting article on the PythonInfo Wiki. This method also uses the built-in sorted() function, as well as the key paramenter, and operator.itemgetter(). (See section 2.1 and 6.7 of the Python Library Reference for more information.) The following code sorts the table by the second column (index 1). Note, Python 2.4 or later is required.

import operator

def sort_table(table, col=0):
    return sorted(table, key=operator.itemgetter(col))

if __name__ == '__main__':
    mytable = (
        ('Joe', 'Clark', '1989'),
        ('Charlie', 'Babbitt', '1988'),
        ('Frank', 'Abagnale', '2002'),
        ('Bill', 'Clark', '2009'),
        ('Alan', 'Clark', '1804'),
        )
    for row in sort_table(mytable, 1):
        print row

Results:
('Frank', 'Abagnale', '2002')
('Charlie', 'Babbitt', '1988')
('Joe', 'Clark', '1989')
('Bill', 'Clark', '2009')
('Alan', 'Clark', '1804')

This works well, but I would also like the table to be sorted by column 0 in addition to column 1. In this example, column 1 holds the Last Name and column 0 holds the First Name. I would like the table to be sorted first by Last Name, and then by First Name. Here is the code to sort the table by multiple columns. The cols argument is a tuple specifying the columns to sort by. The first column to sort by is listed first, the second second, and so on.
import operator

def sort_table(table, cols):
    """ sort a table by multiple columns
        table: a list of lists (or tuple of tuples) where each inner list 
               represents a row
        cols:  a list (or tuple) specifying the column numbers to sort by
               e.g. (1,0) would sort by column 1, then by column 0
    """
    for col in reversed(cols):
        table = sorted(table, key=operator.itemgetter(col))
    return table

if __name__ == '__main__':
    mytable = (
        ('Joe', 'Clark', '1989'),
        ('Charlie', 'Babbitt', '1988'),
        ('Frank', 'Abagnale', '2002'),
        ('Bill', 'Clark', '2009'),
        ('Alan', 'Clark', '1804'),
        )
    for row in sort_table(mytable, (1,0)):
        print row

Results:
('Frank', 'Abagnale', '2002')
('Charlie', 'Babbitt', '1988')
('Alan', 'Clark', '1804')
('Bill', 'Clark', '2009')
('Joe', 'Clark', '1989')