My client is looking to hire a new Python developer, initially for an 8 month contract. It's a home working position, we communicate mostly via Skype / email / gtalk etc. Although we do meet up in meatspace from time to time, so ideally a candidate would be in the London / Oxford area.
So there is some genuinely interesting technology there, and more such projects planned. We need someone who is a good problem solver with a general interest in web technologies. There's also the occasionally need work with data at the bits and bytes level, so a working knowledge of C that would be a plus.
Here's a Python gotcha that I spent some time tracking down. I'm writing it up in the spirit of saving developers a debugging headache in the future.
I had an integer with a single bit set, and I wanted to find the index of that bit. For example, 4 in binary is 00000100. The 1 is at the third position from the right, which should give an index of 2 – since the first position is 0.
You can do this in two ways; either check each bit in turn until you find a 1, or you can use math as a shortcut. I chose the math solution:
>>> import math >>> myint = 4 >>> int(math.log(myint, 2)) 2
Simple right? Finally staying awake in high school maths paid off. So simple that it was the last bit of code I suspected to be broken (spoiler: it was).
This is Python 2.7 which still has two types of integer; type int and arbitrary long integer type long. I was testing with ints because that's what you get when you type 4. However the numbers I was getting out of the Django db where longs. Look what happens with the above code when you use 4L rather than 4:
>>> myint = 4L
>>> int(math.log(myint, 2))
And that was the result of my headache. Longs and ints are generally interchangeable. But not in this case. math.log gives a different result with long and ints. Which we can see here.
>>> math.log(4, 2)
>>> math.log(4L, 2)
That tiniest of rounding errors for the long version would be insignificant for most applications, but not if you are converting to an integer and discarding the fractional part. The fix is simple. Round the return value of math.log to the nearest whole.
>>> int(round(math.log(4L, 2)))
If you are working with Python 3, this problem goes away. Another reason to migrate if you have the option!
Packt Publishing have released Instant Pygame for Python Game Development How-to, a guide to getting started with PyGame, written by Ivan Idris. This title will help you get over the initial hurdles in setting up a PyGame environment and developing your own games.
I was the technical reviewer for this book.
When I'm debugging Python I tend to sprinkle my code liberally with print statements. Trouble is, I forget which files I added those print statements to and have to waste a few minutes tracking them down. Time which could be better spent doing pretty much anything else.
Not sure why I didn't think of this before, but I hacked together something that automatically prints the file and line of the print statement next to the output.
Here's the code:
import inspect import sys import os class DebugPrint(object): def __init__(self, f): self.f = f def write(self, text): frame = inspect.currentframe() filename = frame.f_back.f_code.co_filename.rsplit(os.sep, 1)[-1] lineno = frame.f_back.f_lineno prefix = "[%s:%s] " % (filename, lineno) if text == os.linesep: self.f.write(text) else: self.f.write(prefix + text) if not isinstance(sys.stdout, DebugPrint): sys.stdout = DebugPrint(sys.stdout)
To use it, save it as ‘debugprint.py’ then imported it somewhere. That's all you need to do. Works on Python 2.7 and probably other 2.X Pythons.
Here's what happens if you do it from the console:
>>> import debugprint >>> print "Hello" [<stdin>:1] Hello
For print statements in your app, you will get something like:
“ Has anyone done for the email module, what @kennethreitz has done for http? i.e. make the api only as complex than it needs to be. #Python ”0
“ Maybe I should be a pro photographer. Let's face it, at 40 I'm going to struggle to maintain the fast paced life of a #Python engineer. ”0
Ben Timby has committed code to PyFilesystem that lets you expose any filesystem over FTP. We've had the ability to serve filesystems over SFTP (secure ftp) and XMLRPC for a while, but plain old FTP was a glaring omission–until now.
You can serve the current directory programatically with something like the following:
from fs.expose.ftp import serve_fs from fs.osfs import OSFS serve_fs(OSFS('.'), '127.0.0.1', 21)
The same functionality is also available to the fsserve command. The following is equivalent to the above code, but from the command line:
fsserve -t ftp .
You'll probably need root privileges (i.e. sudo) on Linux for these examples.
With the server running, you can browse the files on your home directory with an ftp client, or by typing “ftp://127.0.0.1” in to your browser. Any of the other supported filesystems can be served in the same way.
FTP has been around since the dawn of the internet, so just about any network enabled device will be able to access files exposed this way. It's a great way of creating a gateway to other filesystems. You could expose files stored on Amazon S3 for example.
You'll need to check out the latest code from SVN to try this out.
Update: Ben has posted more about this.