Ipython Qtconsole

This post record how I setup ipython qtconsole and what problem I encountered.

qtconsole need PyQt4 or PySide installed, here I choose PyQt4.

to install PyQt4, need to setup SIP first, these two need install from source code.

ps. it is recommend to setup python in virtual env with pyenv first.

dependency

Install some dev packages for building source code.

1
sudo apt-get install python-dev python-qt4 python-qt4-dev python-sip python-sip-dev build-essential gfortran libqt4-dev qt4-qmake libpq-dev libsqlite3-dev qt4-dev-tools qt4-doc unixodbc-dev pyqt4-dev-tools

SIP

download source code

1
2
3
python config.py
make
make install

PyQt4

this is the tricky part. Since current version of PyQt4 is 4.10, which broken with ipython. I found someone with similiar problem spyderlib issues, it says ipython is working on it, so I clone the dev version of ipython from github, but it still not working. I endup choose previous version of PyQt4 4.9.4 and it works!!

source code

1
2
3
python configure.py
make
make install

if you have Qt4 and Qt5 both installed, you maybe have problem when running configure.py, because the enviroment is set for Qt5 not Qt4, we need to tell python to use Qt4 explicitly.

1
export QMAKESPEC=/usr/share/qt4/mkspecs/default

and run configure.py with

1
python configure.py -q qmake-qt4

reference

installing-pyqt4-and-sip-in-a-virtual-environment-ubuntu-1204

Multi-dimentional List in Python

Multi-dimentional list syntax in python is not as simple as I thought like

1
MyList = 3 * [ 3 * [ 3 * [0]]]

and then, try to modify a value in it, MyList[0][0][0] = 1, you will see there will be 9 items with value 1, this is not we expecte a normal multi-dimentional list should do.

the problem is python instead of create a new instance of list, it copy the Reference of it. I misused it, and bugged me for a while, after digging on the net, came up with 3 different ways.

comprehension

1
2
3
4
MyList = [[[0 for _ in range(3)] for _ in range(3)] for _ in range(3)]

#operate
MyList[0][0][0] = 1

simulate with dict

with collection.defaultdict help

1
2
3
4
5
6
7
from collections improt defaultdict

MyList = defaultdict(int)

#operate
MyList[0,0,0] = 1
MyList[0,1,2] = 'Good'

this give us a very similar syntax provided by NumPy

use NumPy array

1
2
3
4
5
import numpy as np
MyList = np.zeros((3,3,3))

#operate
MyList[0,0,0] = 1

this way unlike the other two above, only numbers is allowed.

Scripting Alternative to Bash

I really don’t like to write bash script. I prefer use python as my shell language, but I have to admit that in some cases, bash script can be simpler than python.

I found the discussion Are there any languages that compile to Bash?

someone mention Plumbum for python and ShellJS for nodejs both reimplement some unix tools. I tried both, here’s what I learned.

  • Plumbum: overriding many python operator | < > …etc. give these operator new meaning such that > or < for redirect.

  • ShellJS: javascript syntax not as simple as python, but there are coffee script/livescript which provide much elegant syntax, make this library worth using.

there is a third option: ipython, after I read the book

Python for Unix and Linux System Administration

ipython is really amazing, I use it as my default pytohn REPL, this book give me lot’s of way to write a bash like script in python way, oh… not exactly pure python, ipython invent some of it’s own syntax.

here are some example

  • !ls: execute ls
  • !ls | grep config: ls with filter
  • %rehash: hash command in PATH. make unix command can be use inside ipython REPL.
1
2
3
(ipython) user = 'root'
(ipython) process = 'bash'
(ipython) listofitem = !ps aux | grep $user | grep $process

script can be store in *.ipy for future use.

Sudo Hangs

Problem description.

one day during work, I encountered this problem, every time I sudo a command, it took awhile to prompt from password.

how to fix it

I recalled that one of my colleague share how he use strace to debug a application. I decided to give it a shot.

1
$ strace -Tvxfo trace.log sudo ls

the log file is very large, these lines tells what cause the problem

1
2
3
4
5
6
0.000093 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 6 <0.000014>
0.000042 connect(6, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 <0.000
0.000051 poll([{fd=6, events=POLLOUT}], 1, 0) = 1 ([{fd=6, revents=POLLOUT}]) <0.000009>
0.000043 sendto(6, "\x02\xd8\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x08\x4a\x43\x75\x62\x75\x6e\x74\x75\x00
0.000066 poll([{fd=6, events=POLLIN}], 1, 5000) = 0 (Timeout) <5.005021>
5.005098 poll([{fd=6, events=POLLOUT}], 1, 0) = 1 ([{fd=6, revents=POLLOUT}]) <0.000008>

I changed the hostname in /etc/hostname day before. Line 4 say that it want to send somthing to JCubuntu (which is my new hostname), but it couldn’t, so time out occurred.

the solution is adding a new line to the /etc/hosts

1
127.0.0.1  newhostname

the problem will disappear