Sunday, May 23, 2010

Rules of amateur (i.e. for pleasure) photography

  1. Find an interesting subject - and the lens and the camera and the grain and the noise just don't matter, is the photo fun to look at? The only thing that can get annoying is bad focus and camera shake.
  2. All subjects are interesting - when looked at in your unique way. Find what you like and bring that into all the photos. It will take all your life and will change as you change, which is why art is such a good hobby.
  3. You can always crop more - people have fleeting expressions, you need to shoot NOW. Don't worry about exact framing, just make sure you get all you want in the frame, crop out the bad parts later.
  4. Someone somewhere has taken a better photograph of that - just look through flickr. Concentrate on having fun. And make sure you experiment and come up with your own way of looking at things.

Wednesday, May 19, 2010

GLIPY - a promising but defunct enhanced shell for Python

From here, we find the home page form GLiPy. GLiPy is a graphical shell for python. It adds interesting features that allow plotting of numpy matrices in line with the generating code. Unfortunately it seems to be defunct now.
Some related shells for Python:

Saturday, May 15, 2010

Tuesday, May 11, 2010

Sometimes the tax-man giveth: Schedule M

We have a good relationship with the IRS. We overpay them over the year and they give back the interest free loan to us in May (calling it a 'refund'). Usually there is no correspondence, especially since the electronic stuff. The last time I got a letter from the IRS it was to tell me I had screwed up and we were owed a smaller refund. So, natch, when I saw this next letter from the IRS I started to grumble about socialism and how all this medical reform was going to reform our bank accounts, and why should we pay those fat cats in Washington. I opened it up and - they want to give us MORE money. Apparently we are eligible for a 'making work pay' credit that I missed! It almost quadrupled our refund! So folks, for all those skin-flints like me who do their own taxes, don't forget schedule M - if you earn less than $150000 (jointly) - which means most of us dorky lower middle class postdocs - you could get $800 back!

Monday, May 10, 2010

Installing multiprocessing on Python 2.5

multiprocessing comes standard with python 2.6, but you can hand install it for Python 2.5.

svn checkout python-multiprocessing
cd python-multiprocessing
sudo python install   

Saturday, May 8, 2010

Nikon 35mm f/1.8 AF-S

  1. Metal mount
  2. Comes with lens hood and lens case
  3. Very light
  4. Small, but not as small as those pictures of it on the D300 make you think
  5. 52mm thread
  6. Rapid focus
  7. Very sharp

Polling loops vs blocking calls to Queue

This short code demonstrates how blocking calls to a Queue, while consuming less CPU, are limited in their response time by the minimum time slice the OS is willing to allocate (typically 10ms for Mac OS X and Linux). Non-blocking calls to Pipe, using poll() to check if there is data, on the other hand, give us millisecond or less response times, though they consume more CPU. In this respect doing a blocking call to a CPU is no different than adding sleep(.01) statements to a polling loop. In a way, if you execute a sleep(.01) only when you have no events in your poll you will be more efficient than if you had a blocking call pull events off your Queue one by one - because each call to Queue.get() consumes a time-slice, whereas the sleep(.01) only occurs once.

The 10ms OS pre-emption interval and sleep()

Linux and Mac OS X have a 10ms preemption (scheduling) interval. This means that the python time.sleep command (often introduced in a polling loop to prevent the thread hogging the CPU) has a floor at 10ms i.e time.sleep(1), time.sleep(.5) and time.sleep(.01) will all work as expected, giving 1s, 500ms and 10ms delays. But time.sleep(.001) will give us a 10ms delay, not a 1ms delay.

There is a hack for linux systems using nanosleep, but the cleanest thing to do is to use Queues from the multiprocessing module, instead of polling loops. You can also use select, but that gets more messy.

Tuesday, May 4, 2010

Prevent polling loops from hogging CPU

A python polling loop (that continuously runs in order to check for events to happen, often in other threads) can hog the CPU (100% CPU). To prevent this and allow other processes to share the CPU put in a time.sleep(x) command, where x is a small number say 0.1 ms. This is sufficient to prevent the thread/loop from grabbing 100% CPU and setting off all your fans and heating up your cores.

Note that this is a bad way to do things in general, not least because sleep has a 10ms floor.

Monday, May 3, 2010