OrderedDict in Python

Lists and dictionaries are the fundamental data structures in Python. One of the problems I regularly face with dictionary is that I cannot iterate the keys in a certain order. In many problems, I have the keys in a certain order, I am able to insert the keys in that order, but need to be able to later iterate them in that same order.

The solution to these exact problems is the OrderedDict. It is just like the dictionary, but maintains the order of insertion of the keys. Later when you iterate over its keys, the order is the same as you inserted them in. I am guessing it is implemented by maintaining the keys in a list alongside a dictionary.

Usage of the OrderedDict is same as dictionary in all ways. The only difference is in creating it:

import collections

d = collections.OrderedDict()

Tried with: Python 3.4

How to speedtest from the shell

The SpeedTest website uses a Flash program that may not work on many Linux browsers. If you prefer to check the download and upload bandwidth from the shell, that is easy.

Install the speedtest-cli Python module from PyPI:

$ sudo pip install speedtest-cli

Run the test:

$ speedtest-cli

Tried with: speedtest-cli 0.3.4 and Ubuntu 15.10

AttributeError with Python Enum

Problem

I had code that had worked correctly with Python 2.7 and that used the old enum module. Recently it started throwing this error:

$ ./foo.py 
Traceback (most recent call last):
  File "./foo.py", line 146, in <module>
    main()
  File "./foo.py", line 100, in draw_plot
    if PlotType.Line == plot_type:
  File "/usr/local/lib/python2.7/dist-packages/enum/__init__.py", line 373, in __getattr__
    raise AttributeError(name)
AttributeError: Line

Solution

This error is caused when the enum34 module has been installed alongside the old enum module. enum34 is the backport for Python 2.x of the standard enum in Python 3.4. Many packages have started to use it and so it will be installed implicitly while installing another package. enum34 overrides the old enum files and causes this error.

You could remove enum34 and get rid of this error. But since Python 3.x has already adapted a new enum type, it might be wiser to uninstall the old enum and rewrite your code to use enum34. Its syntax is shown in this example.

Tried with: Python 2.7.6 and Ubuntu 14.04

How to visualize Python profile data with SnakeViz

Profile data visualized with SnakeViz
Profile data visualized with SnakeViz

SnakeViz is a beautiful visualization tool for the profile statistics generated by the Python cProfile module. The data is presented in the browser as a colorful sunburst and you explore the data from the inner core outwards. You can also choose how deep you want the sunburst. Below the visualization, SnakeViz also presents the typical function call table with various columns and this table can be sorted based on any of the columns.

Installing SnakeViz is easy:

$ sudo pip install snakeviz

To run it on a stats file:

$ snakeviz foo.pstats

The visualization is opened in your default browser with the URL http://127.0.0.1:8080

Tried with: SnakeViz 0.2.1, Python 2.7.6 and Ubuntu 14.04

How to read INI file in Python using ConfigParser

ConfigParser is a module that can be used to read and write INI files in Python. The module is straightforward to use. Here is a small example:


#!/usr/bin/env python
"""
This module provides methods to read values from a INI file.
"""
import ConfigParser
class Config(object):
DEFAULT_SEC = "DEFAULT"
def __init__(self):
self.cparser = None
def read_config(self, config_path):
self.cparser = ConfigParser.ConfigParser()
self.cparser.read(config_path)
def get_val(self, key):
return self.cparser.get(Config.DEFAULT_SEC, key)
def get_str(self, key):
return str(self.get_val(key))
def get_int(self, key):
return int(self.get_val(key))
def get_float(self, key):
return float(self.get_val(key))
def main():
print __doc__
if "__main__" == __name__:
main()

view raw

config.py

hosted with ❤ by GitHub

Tried with: Python 2.7.6 and Ubuntu 14.04

Google Python Style Guide

I find it easy to grasp the Google Python Style Guide recommendations by creating a simple example, like this:


#!/usr/bin/env python
"""
Illustration of Google Python Style Guide:
https://google-styleguide.googlecode.com/svn/trunk/pyguide.html
This module provides a class to play TicTacToe game.
"""
__author__ = "Gamer Dude"
__email__ = "gamerdude@gmail.com"
__copyright__ = "Copyright 2015, Big Game Corp."
# Standard
import math
import sys
# External
import py_game_opengl
INVALID_MOVE = -1
class TicTacToe(object):
CELL_NUM = 9
def __init__(self):
"""
Game init method.
"""
self.cur_move = None
self.user_count = 0
self.board = [None for _ in range(CELL_NUM)]
self.renderer = py_game_opengl.Simple_Renderer()
self.renderer.init()
def make_move(self, pos, move):
"""
Make a move on the board.
"""
self.board[pos] = move
self.cur_move = move
self.renderer.draw(self.board)
def print_board(self):
"""
Print the cells of board.
"""
for i, move in enumerate(self.board):
print i, ":", move
def main():
print __doc__
if "__main__" == __name__:
main()

How to natural sort in Python

A lot of sources generate filenames or strings numbered naturally: bat_1, ... bat_9, bat_10. The sort in Python is lexicographic and does not result in a natural ordering of such strings.

The natsort Python package can be used to sort such strings naturally.

Installation for Python 3.x:

$ sudo pip3 install natsort

Usage is simple:

import natsort
out_list = natsort.natsorted(fname_list)

Other uses of this package can be found here.

Tried with: natsort 3.5.2, Python 3.4 and Ubuntu 14.04

How to specify OpenCV color type in Python

Problem

OpenCV has bindings for Python. Specifying the color type in calls to imread or imdecode gives this error:

$ cat foo.py
import cv
import cv2
mat = cv2.imread("foo.png", cv.CV_LOAD_IMAGE_ANYCOLOR)

$ python foo.py
AttributeError: 'module' object has no attribute 'CV_LOAD_IMAGE_ANYCOLOR'

Solution

It looks like the CV_LOAD_IMAGE enums which specify the color type of an image have not been exported to Python. Thankfully, the integer value of these enums can be passed directly to the call.

This enum is defined in highgui/highgui_c.h as:

enum
{
/* 8bit, color or not */
    CV_LOAD_IMAGE_UNCHANGED  =-1,
/* 8bit, gray */
    CV_LOAD_IMAGE_GRAYSCALE  =0,
/* ?, color */
    CV_LOAD_IMAGE_COLOR      =1,
/* any depth, ? */
    CV_LOAD_IMAGE_ANYDEPTH   =2,
/* ?, any color */
    CV_LOAD_IMAGE_ANYCOLOR   =4
};

Make the call using the integer value of the enum directly:

# To call with CV_LOAD_IMAGE_ANYCOLOR
mat = cv2.imread("foo.png", 4)

Tried with: OpenCV 2.4.9, Python 2.7.6 and Ubuntu 14.04

How to use OpenCV waitKey in Python

Updated post here: https://codeyarns.github.io/tech/2015-01-20-how-to-use-opencv-waitkey-in-python.html

How to use OpenCV constants in Python

OpenCV has a Python API. The Python function calls are well documented and listed along with the C and C++ calls. However, it is not obvious how to use the various OpenCV constants and enums in Python. These are typically named as CV_SOME_THING. For example: CV_WINDOW_AUTOSIZE.

  • A few of these named constants seem to be available for use in Python by importing the cv package. For example:
import cv
win = cv.NamedWindow("haha", cv.CV_WINDOW_AUTOSIZE)
  • However, I find that many of these named constants are not available in Python. You will need to look up their integer value from OpenCV header files and pass those raw integer values directly to the calls.

Here is a list of integer values for OpenCV constants that I frequently need to use:

CV_LOAD_IMAGE_UNCHANGED = -1
CV_LOAD_IMAGE_GRAYSCALE =  0
CV_LOAD_IMAGE_COLOR     =  1
CV_LOAD_IMAGE_ANYDEPTH  =  2
CV_LOAD_IMAGE_ANYCOLOR  =  4

Tried with: OpenCV 2.4.9, Python 2.7.3 and Ubuntu 14.04