I have written a neat little Spherical Harmonics explorer. Right now, the projection function has some weird bug still, but the basis functions, and arbitrary combinations of them can be viewed nicely. The tool is written in Python, using PyQt4 and PyOpenGL. Python is excellent for prototyping such a tool. It might not be as fast as C++, but the rendering speed using PyOpenGL is more than enough and very smooth. I might put the small 3D viewer widget online later, because it might be useful for many people. Here’s some eyecandy:
Category: Python
Selecting between overloaded signals in PyQt
The signal mechanism in Qt allows for overloading. E.g. the QSpinBox comes with two signals called valueChanged(int) and valueChanged(QString). However, since Python is dynamically typed, such overloading gives rise to problems. Here is how you can select which signal you want to connect to your slot:
from PyQt4 import QtCore, QtGui, uic
class MyMainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ui = uic.loadUi("MyMainWindow.ui", self)
# Slot connections
self.ui.spinBox.valueChanged.connect(self.spinBoxChanged)
self.ui.spinBox.setValue(4)
@QtCore.pyqtSlot(int)
def spinBoxChanged(self, i):
# do something...
pass
Notice the (int) in the decorator of the slot. This has to match the signature of the signal. I haven’t dug into more complex signals, passing around arbitrary objects, but I think that is not a problem: Qt datatypes have a Python wrapper, and functions in Python cannot be overloaded anyway, so there won’t be clashes with pure Python signals and slots.
I love Python
It’s so easy to quickly code something and calculate something. The following snippet actually computes the number of possible cards in the game Tsuro. The game ships with 64 cards, but my colleague and I suspected that those were not all possible combinations (eliminating all rotational symmetries). So we did some quick calculations, and came up with 105 possible cards. So I wrote this short Python code to enumerate all possible cards then:
def makeCards(cards, card, connectionSet):
if connectionSet == set([]):
for i in range(1,4):
c = shiftCard(card, i)
try:
cards.index(c)
return cards
except ValueError:
pass
return cards + [card]
start = connectionSet.pop()
for i in connectionSet:
newConnection = sorted([start, i])
cards = makeCards(cards, sorted(card + [newConnection]), connectionSet - set([i]))
return cards
def shiftCard(card, i):
newCard = []
for c in card:
conn = sorted([(c[0] + 2 * i) % 8, (c[1] + 2 * i) % 8])
newCard = sorted(newCard + [conn])
return newCard
mycards = makeCards([], [], set([0,1,2,3,4,5,6,7]))
print mycards
print len(mycards)
Python: swapping variables
I forgot where I read this, but this is a neat way of swapping variables in python:
u = 1
v = 2
print "%i %i" % (u, v)
u, v = v, u
print "%i %i" % (u, v)
How to duplicate Matlab functionality
Since I am a total Matlab-n00b, I rather write a convoluted Python script instead of using the appropriate Matlab function. And here it is. A small script to compute the standard deviation of two vectors. I guess this would have been one Matlab command.
import sys
import scipy.io
import math
def computeStdDev(file, vec1, vec2):
data = scipy.io.loadmat(file, struct_as_record=True)
vector1 = data[vec1]
vector2 = data[vec2]
if len(vector1) != len(vector2):
print "Error: Vectors do not have matching lengths."
return
diff = vector1
N = len(diff)
for i in range(N):
diff[i] = vector1[i] - vector2[i]
mu = 0
for val in diff:
mu = mu + val
mu = mu / float(N)
sigma = 0
for i in range(N):
sigma = sigma + (diff[i] - mu)**2
sigma = math.sqrt(sigma / float(N))
print "mu: %f" % mu
print "sigma: %f" % sigma
if len(sys.argv) != 4:
print "Usage: %s file vector1 vector2" % sys.argv[0]
sys.exit(0)
computeStdDev(sys.argv[1], sys.argv[2], sys.argv[3])
Matlab and Python
How to read Matlab files with Python and SciPy can be read here. Short:
import scipy.io
data = scipy.io.loadmat('test.mat')
This will create a dictionary called data containing all the variables of the Matlab file.
Elegantly making a dictionary of lists
In Python I sometimes want to make a dictionary of lists. So usually I would write something like:
mydic = {}
for something in somethingelse:
mydic[somekey].append(something)
This however will not work, if somekey did not exist so far, because it will raise an exception. But there is help! You can use a collection:
import collections
mydic = collections.defaultdic(list)
for something in somethingelse:
mydic[somekey].append(something)
PyQt dynamic uic example
Here is a minimal example for PyQt4, to set up a main window and connect a simple action to some slot. The documentation on doing this is sparse to say the least. So I hope this is helpful for anyone trying something similar. I assume that you have created a ui_MainWindow.ui file with Qt Designer, which contains a form derived from QMainWindow.
import sys
from PyQt4 import QtCore, QtGui, uic
class MyMainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ui = uic.loadUi("ui_MainWindow.ui", self)
self.connect(self.ui.actionOpen, QtCore.SIGNAL('triggered()'), self, QtCore.SLOT('open()'))
@QtCore.pyqtSlot()
def open(self):
fileDialog = QtGui.QFileDialog(self, "Open file")
fileDialog.show()
app = QtGui.QApplication(sys.argv)
mainWindow = MyMainWindow()
mainWindow.show()
sys.exit(app.exec_())