Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

Thursday, June 14, 2007

Didn't I Say I Wouldn't Compare Languages?

I posted a version of this to JJ Behrens' Blog post about Ruby, and decided it was probably worth also posting here.

I use and like both Ruby and Python, here's why...

Things I like about Ruby with respect to Python



  1. I think Ruby is the only language that gets accessors right. The thing you want to do 95% of the time -- simple access -- is trivial, and the thing you want to do 5% -- something fancy in your accessor -- of the time is a pretty easy override. Plus, it's nicely encapsulated, and you never have to wonder if that thing in another class is accessed directly or via a method.

  2. Blocks. I find that my kind of functional style flows pretty easily in Ruby. It's also not hard to pass named functions. When I first started with Ruby, it used to bother me that you couldn't tell from a method signature if it took a block, but I've since managed to deal.

  3. Being able to add method to existing classes. Although I know this really bugs some people, sometimes adding a method to String cleans up the code significantly.

  4. Expression-based syntax. The implicit return in Python always causes me at least one error per sessions. Plus I like writing a ternary operator as an actual if statement.



Things I like about Python with respect to Ruby



  1. Consistency. Python enforces it. As a result, my Python code is more likely to be readable by me six months later. Ruby tends to be more concise, but some parts of Ruby are still a little too Perlish...

  2. Real keyword arguments (coming to Ruby soon). The Ruby syntax magic of gathering up map pairs into a hash is sort of annoying.

  3. I find Python's multiple inheritance mechanism to be easier to understand then the Ruby package/module setup. It always seems like I'm messing up the difference between 'require' and 'include'...

  4. On balance, I prefer Python immutable strings to Ruby's mutable string/symbol split.

Wednesday, December 13, 2006

Playing in the Sandbox

This message showed up in the Manning Sandbox forum for wxPython In Action.  After saying some nice things about the book, the poster has some suggestions:

I would love to see an advanced volume covering topics such as XRC, using XML to define a screen layout; creating custom widgets...  internationalization, and a full chapter or more expanding on chapter 5 "Creating your blueprint." I find that... program organization is most important yet little seems to be written about it, for any programming language.... A book that illustrates solutions to design problems using patterns, Python, and wxPython will help many people...
Thanks for the kind words.  I'm thrilled that you found the book helpful.

There are about three or four things that I regret not being able to include in the book.  XRC is definitely on that list -- I think that XML or other GUI description languages are going to be increasingly important.  (Also on the list: multimedia and how to distribute your finished program).

These all got pushed out of the book over space considerations.  We were something like 75 pages over budget as it was.  Owing to some communication issues, nobody realized that we were that far over our page count until the pages were already written, and while it wasn't a problem to get them approved, it did mean that we didn't push forward into other topics.

There are no current plans for a second book, although it's not out of the question that we'd fill a gap or two with an article on line somewhere.  (To be clear, there are no current plans for that, either).  Frankly, sales are not high enough for a publisher to seek us out for a second book at this point, especially since an advanced book would, almost by definition, sell fewer copies than the original.  That's not a knock on the sales, which seem to be roughly in line with publisher expectations, just a comment on the size of the potential market.

As for a patterns/program organization book for Python, I'd love to write one.  For one thing, it'd give me a chance to rant at length about the finer points of architecture and class structure.  I've been known to have an opinion or two on the topic.  The main problem would be selling it.  My sense is that it's rather hard to sell a general-topic programming book compared to one that's tied to a specific tool or product.  This would especially be true for a relatively small market like Python. 

Still, that's what blogs are for, so hopefully I'll be able to get some interesting thoughts on those lines here.

Saturday, December 02, 2006

Don't Ask Questions, It Only Encourages Him

Let me promote this from the comment section -- it's not hard to find, it's the only comment on the previous post.



What is your favorite Python IDE? Your editor choices are interesting and valid but I wondered if you have a preffered IDE for Python and wxPython work?

I may have covered this somewhere, either on this site, or in the Python 411 podcast interview. If so, I'm sorry.



When I'm on a Windows machine, my Python editor of choice is JEdit, and has been for quite a while. I should say that I only rarely use the Python debugger and Jython interpreter add-ons that are available for it. I do have a couple of custom scripts that execute the script I'm working on and so on, but it's not a very elaborate set-up. What I like about JEdit is that it has a clean interface, had familiar Windows keyboard shortcuts and menus, and had a lot of plugin and macro power. The main downside is that it's kind of a memory hog for a text editor.



When I jumped Mac-side for my personal stuff, I tried just about every free programmer's editor I could find (JEdit, like a lot of Java/Swing programs, behaves a bit oddly on a Mac). Finally, I somewhat reluctantly decided to pay for TextMate. Although Python-mode on TextMate hasn't quite gotten the love and attention that Ruby has, there's still a lot of power there. It's really easy to script and customize, and it's about the only editor I've seen that has dynamic mode. So that if you are writing, say, a Django template, TextMate knows the the HTML portion gets colored and edited under HTML scope, and inside the Django tags, you use Django/Python mode.



My main issue with the various IDE's is that I haven't seen a Python one where the gain in the IDE functionality makes up for the editor itself not being as powerful as my normal editor. Some of this is my personal workflow -- using Python and test-first programming, it's very rare for me to feel that I need a step-through debugger. I'm also not very fond of code-generating GUI builders, for reasons that are probably worth another post.



That said, one thing I do like when I'm in and IDE for whatever reason is the ability to specify a project and do useful things across project scope. (Both JEdit and TextMate have this ability, but not fully formed.) I've done some Ruby work using Eclipse with Ruby plugins, and it's nice to, say, have one-button access to running all your unit tests.



That's what works for me, but I'm always looking for new tools and finding out how other people work.

Tuesday, September 12, 2006

Re-refactoring

Here's a little riff inspired by one of the examples in Martin Fowler's book Refactoring, which is another great programming book that deserves an appreciation post one of these days. This was actually also spawned by code that I've read, and later realized that Fowler did a similar example. Thing is, I don't think Fowler went far enough in this case.

Here's the example. (page 243 for those of you playing the home game). But, since it's Python Week here, I'll translate to Python.

if isSpecialDeal():
total = price * 0.95
send()
else:
total = price * 0.98
send()
Fowler correctly notices the duplicate call to send(), and refactors to:
if isSpecialDeal():
total = price * 0.95
else:
total = price * 0.98
send()
This is fine as far as it goes, but as I see it, there's a second duplication in this snippet -- the formula for calculating the total. I'd rather see something like this (using the new Python 2.5 ternary syntax:
multiplier = (0.95 if isSpecialDeal() else 0.98)
total = price * multipiler
send()
There are a couple of advantages to this last snippet. We've separated the calculation of the total from the act of gathering the data for that calculation. This makes the actual formula for the total clearer, and allows you to easily spawn the multiplier getter off to it's own method if it gets more complicated. Plus we've removed more duplication, and I think made the code structure match the logical structure of the calculation a little bit better.

This is a simple example, and you could quibble with it. The general idea of separating conditional logic from calculations is a solid way to clean up code and make it easier to maintain in the long run.

Before I leave... I'm not sold on the syntax for the Python ternary yet. I'm told that the syntax was chosen over the perhaps more consistent if cond then x else y end because it was felt that in most use cases you'd have a clear preferred choice and a clear alternate choice, and putting the preferred choice before the conditional emphasized that. I don't know if that matches how I'd use a ternary. Although I guess it's reminiscent of listcomp syntax. I need to use it in real programs to know for sure.

Monday, September 11, 2006

Some 411 of my own

Saturday, Robin and I had the pleasure of being interviewed by Ron Stephens for the excellent Python 411 podcast. I think this was the first time I've ever been interviewed for anything, and while it's always fun to talk about Python, the book, and me (not necessarily in that order), it does take some getting used to.

Anyway, I do mention this here blog during the interview, and while I don't want to talk about the actual interview in detail until I hear the edited version, it did occur to me that I might want to have some actual Python content on board in case anybody comes by to check the place out.

Python content all week, then, starting with today's Things I Love About Python:

  1. Whitespace. I know that I said just a few short days ago that I wasn't going to redefend Python's whitespace blocks. That was then, this is now. Now, I'm just going to gush over them. I love using whitespace to mark blocks. It enforces what I'd be doing anyway. It encourages consistent style, with the result that other people's Python code is actually intelligible. It encourages short methods and shallow nesting, both good habits, and it lets you get about 10-25% more code on a page. Nobody is ever going to have an Obfuscated Python contest (okay, I looked it up... somebody has, but they realize it's a joke.

  2. List Comprehensions. One of my favorite syntax features in any language. So concise and yet so clear... Try to describe the following any more clearly in any language, programming or not.

    [x.name for x in students if x.grade > 90]

    Okay, they do sometimes blow up if you make them too complicated.

  3. First Class Functions. It's easier to pass around named function objects in Python than in just about any language not named Lisp. This is a very good thing. It enables all kinds of elegant abstractions (especially since classes and instances can all be made callable). Over time, using Python has made all my coding move to a more functional style that's easier to test, verify, and maintain.
Of course, not everything in Python needs to be elegant and abstracted. Last night I had a problem. I wanted to download all episodes of a popular podcast that does not have an easily accessible archive page. Rather that walk through months of postings, I decided to write a script that would take advantage of the pages naming conventions, loop to find the shows for given days, find the downloadable URL and download, then add to iTunes. Final code, just under 60 lines. Elapsed time, under 45 minutes start to first download, including downloading, installing, and using a new library (Beautiful Soup, which is a nice HTML parser). The point is not that I'm particularly good at this (the script is a little sloppy and doesn't handle error conditions well), but that Python is particularly good at this. Plus, it was fun -- no fighting with compilers and interpreters, able to find support for the libraries when I needed it.

Thursday, August 31, 2006

Languages I Use

Continuing in the getting to know you kind of vein, I thought I'd ground some of what I say by talking about the three programming languages that have made up the bulk of my professional and hobby work for the past five years or so -- Java, Python, and Ruby.

Java: I've been programming Java since either just before or just after the 1.0 release... can't quite remember at this point. I think I've covered most of the major Java libraries (although I've done very little EJB work). Basically, Java is the station wagon of programming languages. It's not elegant or efficient, but it gets you where your going and you won't offend anybody along the way.

Far and away the best feature of working in Java is the tool support, especially the IDE support. If you're doing something in Java, odds are somebody has done it before and there's an open source .jar file somewhere that will help. Plus, IntellJ IDEA makes working in Java almost as productive on a time-basis as working in a scripting language.

Java is, of course, famously verbose, and there's the constant sense of telling the compiler things that the compiler should already know. (The 1.5 language features improve this somewhat, at the cost of moving some of the verbosity elsewhere). Java's original design goal was basically to get C programmers to do object-oriented stuff without scaring them away, and at that it's a success, but that does lead to oddities like having both basic types and object wrappers for them, and keeping the ridiculous C-style switch statement.

There's also the "Java style" of OO design, enshrined early on by Sun, and followed by many third-party libraries. To oversimplify, there's a lot of design made complicated by the desire to make less common tasks as privileged in the API as more common ones. For example, the need to spell out what are basically boilerplate properties in a web.xml file or a Struts config file. Swing has several features like this, including the event system and say, supporting multiple listeners for a button click.

Python: With Python I suppose you have to start with the whitespace thing, although I know that anybody who actually works in Python is sick of hearing about it. I wrote what I hope was a spirited defense of it in the Jython book, and I'm not going to repeat myself. What I like most about working in Python is the conceptual consistency -- objects are like classes are like modules are like dictionaries. I find that to be a very powerful equation, and it makes Python code more predictable to me. I also think the syntax is very clear and readable. (I particularly like the list comprehension syntax.)

On the down side, although there probably is more Python libraries than Ruby ones floating around (although I'm not as sure of that as I was even a year ago), there's no central repository so they are harder to find. It is true, though, that Python style quirks are more likely to bleed into my programming in other languages than vice-versa -- I write a lot of Java code that really looks like it wants to be written in Python.

Ruby: I actually got into Python, Ruby, and XP at about the same time. I started on Ruby because a number of the early XP gurus were excited about it. And while I know I'm supposed to pick a side or something, I actually like Python and Ruby both quite a bit. There are some particular bits of Ruby syntax that I think are particularly well done, for example the way that accessors are handled. I even like that you can leave parentheses off method calls if the line is unambiguous, although a little of that can go a long way. Blocks make the language very flexible, and very easy to build non-redundant code in.

There are a couple of pieces of Ruby syntax that make me nervous, like the syntactic sugar for hashes as the last argument of a method or the way you don't have to specify that a block is needed in the signature of a method. To be fair, I haven't experienced practical problems with these features yet. Ruby has a lot of syntax sweetener compared to Python, which is sometimes good (elegant Ruby code is very elegant) and sometimes bad (I've had some trouble following Ruby examples if they are very magical). Because Ruby has been the focus of a lot of XP/Agile writers, the testing tools and general XPish support is very good. For a long time, I thought that general library support lagged Python, but that's becoming less true daily. And of course there is also Rails, about which more at another time.