Posted March 19th, 2009 |
Published in Python
The link below is to a section of a Python coding tutorial. It elegantly sums up dynamic typing in a few hundred words and 20 or so nice pictures.
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables
Posted February 19th, 2009 |
Published in Python
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren’t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one– and preferably only one –obvious way to do it.
Although that way may not be obvious at first unless you’re Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it’s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea — let’s do more of those!
Posted November 5th, 2008 |
Published in Python
I looked through the Python String Methods page expecting to see a Reverse() function but there isn’t one. Googling further I found plenty of people suggesting using this:
s = s[::-1]
But what the hell is that? Not the most intuitive syntax I’ve ever seen. This is using the Python Slice syntax.
Python can take a slice from a list or a string. The syntax is similar to array accessor in other languages like C, C++ and Pascal – in those languages you could do:
char c = s[3];
And in Python it’s the same – but this has been taken further and that array accessor is now much more powerful. For example:
s = “hello world”
print s[6:11]
>>world
l = [0,1,2,3,4,5,6,7,8,9]
print l[2]
>>2
So it can work like a SubString() function in the first example, like a standard array accessor in the second.
The extended slices add a third parameter, which is the step argument – which basically means it’s the number of elements to jump before retrieving the next element. For example
l = [0,1,2,3,4,5,6,7,8,9]
print l[0:9:2]
>>[0, 2, 4, 6, 8]
l = [0,1,2,3,4,5,6,7,8,9]
print l[::2]
>>[0, 2, 4, 6, 8]
Notice the two different slice syntaxes above giving the same output – [0:9:2] and [::2]. If you leave the first parameter blank it defaults to 0 and if you leave the second blank it defaults to the length of the variable being sliced.
And finally by putting -1 in the step you get the reverse string behaviour
s = “hello world”
print s[::-1]
dlrow olleh
Posted July 30th, 2008 |
Published in Python
Since Python treats a newline as a statement terminator, and since statements are often more then is comfortable to put in one line, many people do:
if foo.bar()['first'][0] == baz.quux(1, 2)[5:9] and \
calculate_number(10, 20) != forbulate(500, 360):
pass
You should realize that this is dangerous: a stray space after the \ would make this line wrong, and stray spaces are notoriously hard to see in editors. In this case, at least it would be a syntax error, but if the code was:
value = foo.bar()['first'][0]*baz.quux(1, 2)[5:9] \
+ calculate_number(10, 20)*forbulate(500, 360)
then it would just be subtly wrong.
It is usually much better to use the implicit continuation inside parenthesis:
This version is bulletproof:
value = (foo.bar()['first'][0]*baz.quux(1, 2)[5:9]
+ calculate_number(10, 20)*forbulate(500, 360))
Posted March 27th, 2008 |
Published in Python
On the Modules page of the Python docs, there is this code example:
def fib(n): # write Fibonacci series up to n
a, b = 0, 1
while b < n:
print b,
a, b = b, a+b
Being new to Python, this code snippet confused me for three reasons:
- What’s the comma at the end of the print statement for?
- Is the “a, b = b, a+b” line a continuation of the print line?
- And finally, is the “a, b = b, a+b” line basically three assignments separated by commas?
I knew that when given an input parameter of 1000 the Fibonacci functions outputs:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
Which basically meant that my assumptions above were all wrong.
Commas at the end of Print statements
In Python, the default behavior of Print is to add a newline character at the end of the printed text – the only time the newline is not added is if a print string ends with a comma. For example:
print "line one"
print "line two"
print "line three",
print "line four"
Outputs:
line one
line two
line three line four
One subtle thing to notice with that output is the space between “line three” and “line four”. Ending a Print with a comma adds a space.
Commas in assignments
My first reaction was to read this line “a, b = b, a+b” as meaning perform three separate assignments. Clearly this couldn’t be because the “a” variable was not being assigned in any way and the known function output wouldn’t match that behaviour. What it is actually doing is assigning the values from list “b, a+b” to list “a, b”.
Posted March 24th, 2008 |
Published in Python
I’ve been using iText – the Java PDF library – a lot recently and seeing as I’ve been getting into Python I wanted something similar to iText for that. I managed to dig these up:
ReportLab - A PDF creation tool in the iText mould but the ReportLab site hasn’t been updated since 2005 so looks like this is a dead project.
PyPDF - A simple library that lets you change PDF metadata (author, title, etc) and to crop, join or split PDF files. PyPDF doesn’t have the ability to modify a page’s content.
HTML2PDF - A the name suggests, this takes some HTML input and creates a PDF from it. Looks good.
Another option may be to compile iText using the GNU Java compiler and then to create a Python wrapper for it. I’ve never used GCJ so I don’t know if it would even compile iText cleanly.
Posted March 21st, 2008 |
Published in Python
The Python language contains the OO concept of a class. Rather strangely, it only really does half the job in that it doesn’t provide a way to properly encapsulate your class’ members.
Take this Java class, for example:
class Steve
{
private String name;
public String getName()
{
return name;
}
public void setName( final String n )
{
name = n;
}
}
This class is properly encapsulated. The getter and setter control the values that can be placed into, and read from, the name property.
You can’t do that with Python, you can create a similar looking class, like so:
class Steve:
name = "";
def getName(self):
return self.name;
def setName( self, n )
self.name = n;
But there is no way to make the name variable private – it is always public. You can define a variable with a leading double-underscore, like so:
class Steve:
__name = "";
def getName(self):
return self.__name;
def setName( self, n ):
self.__name = n;
This stops consumers from using Steve().name directly but __name is still not private – it is merely decorated differently. But it can still be obtained directly by using Steve()._Steve__name instead.
I’m not sure if the intention is to update this in a future version of Python – Python3000 breaks backwards compatibility so this is something that could go in. I hope it does get fixed.
Posted March 19th, 2008 |
Published in Python
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren’t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one– and preferably only one –obvious way to do it.
Although that way may not be obvious at first unless you’re Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it’s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea — let’s do more of those!