Follow Slashdot blog updates by subscribing to our blog RSS feed

 



Forgot your password?
typodupeerror
×
Programming IT Technology

Python 2.4 Final Released 359

Eventh writes "The final release of Python 2.4 was just released. Python 2.4 is the result of almost 18 month's worth of work on top of Python 2.3. New features are, but not limited to, function decorators, generator expressions, a number of new module and more. Check out Andrew Kuchling's What's New In Python for a detailed view of some of the new features of Python 2.4. "
This discussion has been archived. No new comments can be posted.

Python 2.4 Final Released

Comments Filter:
  • 18 Months (Score:4, Informative)

    by nijk ( 781345 ) * on Tuesday November 30, 2004 @11:34AM (#10953442)
    It took them a while, but it's worth it. Here's some of the new features:

    * multi-line imports - when using imports in the form from foo import bar, baz, bing, bang, you can surround the imported names with brackets, and they can be split across lines. This is part of PEP 328.
    * Farewell to OverflowWarning - as documented in PEP 237, Python no longer generates OverflowWarnings.
    * function/method decorators - function and method decorators, first described in PEP 318, have been added to the language, using 'pie-decorator' syntax. Decorators are on the line before the 'def', and prefixed with an '@' sign. (PEP 318)
    * Assigning to None - the compiler now treats assigning to None as a SyntaxError.
    * Failed import cleanup - when a module import failed, versions of Python prior to 2.4a2 would leave a broken module in sys.modules - subsequent attempts to import the failing module would silently succeed, but use the broken module object. The import machinery now removes the failing module from sys.modules if the import fails.
    * The -m command line option - python -m modulename will find a module in the standard library, and invoke it. For example, python -m pdb is equivalent to python -m /usr/lib/python2.4/pdb.py
    • genexps (Score:5, Insightful)

      by ultrabot ( 200914 ) on Tuesday November 30, 2004 @11:45AM (#10953569)
      You forgot the most important improvement, the "generator expressions".

      From the AMK's excellent (as always) overview:

      print sum(obj.count for obj in list_all_objects())

      The important part is that no intermediate list is generated, because we are dealing with generators.

      Generators in general kick so much ass it's not even funny.
      • Re:genexps (Score:2, Informative)

        by percivall ( 651934 )

        Yeah, generators do kick ass.

        But it's important to remember that generator expressions are slower than list comprehensions. This is mainly because functions calls are expensive in Python, and when dealing with generators each iteration means one more function call.

      • Re:genexps (Score:3, Interesting)

        by Pxtl ( 151020 )
        Wow, generators, decorators.... how much more linguistic cruft is it gonna take before they just give up and implement Ruby style blocks? It seems like 90% of these are created because lamdba sucks and def isn't anonymous.
        • Re:genexps (Score:4, Informative)

          by ultrabot ( 200914 ) on Tuesday November 30, 2004 @01:42PM (#10954752)
          It seems like 90% of these are created because lamdba sucks and def isn't anonymous.

          Uh, you do realize that generators have nothing to do with anonymous functions, and that it's rather a simplified, understandable approach for providing coroutines? Generators are significantly more powerful than Ruby code blocks.
          • Re:genexps (Score:5, Insightful)

            by CoughDropAddict ( 40792 ) on Tuesday November 30, 2004 @02:23PM (#10955276) Homepage
            At a language level, it's true that generators don't have anything to do with lambda or code blocks. But when you consider what these features are used for, there is some overlap.

            Consider the example you gave:
            print sum(obj.count for obj in list_all_objects())
            In Ruby, you can accomplish the same thing by writing:
            print (objGenerator.map { |obj| obj.count } ).sum
            where "objGenerator" is an object that mixes in the "Enumerable" module. An even better way (that really avoids building an intermediate list, even of integers) is:
            a = 0
            objGenerator.each { |obj| a += obj.count }
            print a
            There is one thing that generators give you that blocks can't, that is very, very cool. With a generator, you can create programs with a pipeline architecture, where different steps of the pipeline all can be written as if they have the main loop.

            Imagine you are writing a compiler. You could write (be easy on my syntax, I haven't written Python in a while)
            def lexer(input):
            state = STATE_BEGIN
            ch = input.read(1)
            if state == STATE_BEGIN:
            if ch == '(':
            yield TOKEN_LEFT_PAREN
            (...)

            def parser(lexer)
            token = lexer.get()
            if token == TOKEN_LEFT_PAREN:
            yield parse_expr(lexer)
            # gobble TOKEN_LEFT_PAREN
            lexer.get()
            (...)
            The beauty is that both your lexer and your parser can be written as if they have the main loop, and all they have to do is yield a token/expression when they find one. In reality, it's pipelined and you get the efficiency of not having to build up the entire list of tokens before you start parsing.
          • Re:genexps (Score:4, Insightful)

            by CoughDropAddict ( 40792 ) on Tuesday November 30, 2004 @02:34PM (#10955439) Homepage
            Oops, I realized that probably the best way to do this in ruby is to use inject:
            print objGenerator.inject(0) { |sum, value| sum + value }
            No intermediate list, and you don't have to rely on having a function like "sum" defined -- it could be any operation.

            You could also add this to the "Enumerable" mixin:
            module Enumerable
            def sum
            return inject(0) { |sum, value| sum + value }
            end
            end
            Now you can call "sum" on any object that implements "Enumerable", and the example becomes:
            print objGenerator.sum
  • by koi88 ( 640490 ) on Tuesday November 30, 2004 @11:34AM (#10953448)

    Finally I can make my functions so much prettier.
  • by Anonymous Coward on Tuesday November 30, 2004 @11:37AM (#10953483)
    If you can keep your "significant whitespace sucks" comments as children of this one, I'm sure everyone will get along just fine...
    • Re:OK Trolls... (Score:2, Insightful)

      by rhaig ( 24891 )
      whitespace, when used correctly, makes code readable. However, having the inability to be flexible with the use of that whitespace bugs me.

      coding standards make good code, not a language. I can write bad python just as easially as I can write good perl.
      • Example: Say you're debugging a script on an 80 character wide TTY display. Do you really want to go through each line, scrolling all the way to the end because your language has significant whitespace?

        Just like a Wookie on Endor, it doesn't make sense.

        • Re:OK Trolls... (Score:5, Informative)

          by pclminion ( 145572 ) on Tuesday November 30, 2004 @12:43PM (#10954174)
          Do you really want to go through each line, scrolling all the way to the end because your language has significant whitespace?

          There is absolutely nothing that says you can't break things across lines. In most cases you don't even need a backslash to escape the linebreak. TRY the damn thing before criticizing it.

        • Example: Say you're debugging a script on an 80 character wide TTY display. Do you really want to go through each line, scrolling all the way to the end because your language has significant whitespace?

          Uh, no, I don't... which is why I'm glad this is perfectly valid python syntax:

          a = [1,2,3,
          4,5,6,
          7,8,9]

          def somefunc(s1,s2,s3):
          print "1 "+s1+"\n"+ \
          "2 "+s2+"\n"+ \
          "3 "+s3+"\n"

          somefunc("as","df",
          "gh")

      • One of the biggest drawback of the whitespace issue is that you don't get a real lambda in Python for basically just that reason. The lambda that is in Python is limited to a single expression (ie. single line) and thus beside trivial stuff completly useless. Naming functions kind of really sucks if all you wanna do is something very little.

        The whitespace issue makes of course other things like copy&paste a whole lot harder too.

        Overall I just wish they would introduce some kind of construct to get awa
  • heh (Score:5, Funny)

    by boschmorden ( 610937 ) on Tuesday November 30, 2004 @11:38AM (#10953492)
    import overlords

    print "I for one welcome our new %s overloads.!" % overloads.get_random()
  • by Anonymous Coward on Tuesday November 30, 2004 @11:41AM (#10953529)
    The python final release of python 2.4 is finally released for python users out there who wish to use the final release of python release final.
  • by deathazre ( 761949 ) <mreedsmith@gmail.com> on Tuesday November 30, 2004 @11:47AM (#10953587)
    2,500KVA @ 0.8 PF? (note: some electrical background required to appreciate the above)
  • by Frater 219 ( 1455 ) on Tuesday November 30, 2004 @11:47AM (#10953589) Journal
    The What's New document gives a somewhat inaccurate description of the importance of the Decimal type. Naturally, switching from binary to decimal changes which fractions can be exactly represented, but it does not change the fact that some cannot.

    The importance of decimal arithmetic is not that it is more accurate than binary, but rather that it conforms more closely to what people expect from using decimal in daily life. These expectations are codified into various social rules such as accounting practices.

    There's been some heated discussion of Python 2.4's Decimal, in this very regard, on the Lambda the Ultimate [lambda-the-ultimate.org] languages blog.

    • That entire "debate" consists of one idiot flipping a shit because of a poorly worded snippet from a pre-release version of the "What's New?" overview. He didn't even bother to reference the appropriate PEPs and documentation before grossly misrepresenting the point of the new Decimal type.

      No, the Decimal type isn't IEEE 754 standard. No, it doesn't solve, or intend to solve, all the world's numerical analysis problems. Yes, it is a good thing in a language intended to minimize the dissonance between user
    • Agreed: decimal representations are pretty useless. You might as well use binary integers and appropriate scaling. And that is what any implementation of decimal arithmetic should be: binary numbers with implicit decimal scale factors.
  • frozenset (Score:5, Interesting)

    by hey ( 83763 ) on Tuesday November 30, 2004 @11:47AM (#10953591) Journal
    Instead of having a special keyword for immutable sets (frozenset) wouldn't it be better to have an "immutable", "final" or "const" keyword?!
    • Instead of having a special keyword for immutable sets (frozenset) wouldn't it be better to have an "immutable", "final" or "const" keyword?!

      Where would you put that keyword?

      s = frozen Set()

      where frozen would do some kind of lookup in a table that has a non-mutable equivalent of every class?

      That wouldn't make much sense. Providing a freeze() function might be more sensible, where it would always call obj.__freeze__ if applicable, telling the object to lose all the mutability...
    • Re:frozenset (Score:3, Informative)

      by Anonymous Coward
      in short, no.

      python doesn't have modifiers for anything else, so it would require syntax changes. Whitespace after a python reserved word seperates it from its expression.

      "frozen x = Set()" complexifies things because since day 1, an assignment returns 'None', and 'frozen None' is nonsense.

      You could of course write it as a property:

      x = Set()
      x.become_frozen()

      But it's better to consider 'frozenset' as a subclass of 'set' (or vice versa), since 'frozenset' very well fits the 'is a' paradigm, because a fr
  • Python annoyances (Score:2, Insightful)

    by Anonymous Coward
    Python is a pretty good language for general use and for teaching. If fact, what got me interested in Python was a story (on Slashdot) about programmers at Sun saying that Python was a better language than Java in their environment.

    Having said the above, there always seem to be 'issues'. Floating point numbers are one such issue. This release fixes that with 'Decimal'. The trouble is, you have to know about 'Decimal' before you can use it. This raises the difficulty of using Python.

    I find that I writ
    • The decimal type offers a fix for a (very slight) inaccuracy that's inherent with floating point values on a machine level. It's not a programming language "issue" at all.

      Having said that, I agree it takes some time to become efficient in Python. I wish/hope (ought to check again) that Python's potentially excellent built-in documentation string system becomes/is more accessible and useful. That'd help a lot with getting to know modules.

      I've used 3 scripting languages over the times; I use bash for anythi
  • by mi ( 197448 ) <slashdot-2017q4@virtual-estates.net> on Tuesday November 30, 2004 @11:53AM (#10953653) Homepage Journal
    I do not see "Extensions API" anywhere on the list of improvements. Last I tried, creating one's own object type or even a simple command was a rather tedious task, unlike in TCL...
  • Dive into Python (Score:4, Interesting)

    by cbelle13013 ( 812401 ) on Tuesday November 30, 2004 @11:54AM (#10953657)
    I had absolutely no interest in Python until I read Slashdots review of Dive Into Python [slashdot.org]. Its right on target and got me excited to run home and see what I could do. Of course that only lasted for about a month, but I'll be sure to head home and take a peak at it again.
  • I was supprised that even though a good number of Slashdotters are programmers themselves, http://www.python.org/ [python.org] was not slashdotted.

    Can one tell me why I should learn python and not any other programming language anyway?

    From the little I have seen, python seems to be a command line language. Is it anywhere similar to Visual Basic, which I have come to see and experience through a GUI?

    • Use a toolkit (Score:3, Informative)

      by gregarican ( 694358 )
      There are GUI toolkits which typically are added on as an extension to something like Python. I am learning Ruby and can choose from Qt, Tk, Wx, Fox, etc. As long as someone has created the extensions you are good to go.
    • There are many gui widget libraries available for python, and several RAD tools to get into 'em quickly. Try Boa constructor http://boa-constructor.sourceforge.net/ [sourceforge.net] or google for pyglade
    • Re:Supprised (Score:5, Insightful)

      by kirkjobsluder ( 520465 ) <kirk@job[ ]der.net ['slu' in gap]> on Tuesday November 30, 2004 @12:21PM (#10953950) Homepage
      Can one tell me why I should learn python and not any other programming language anyway?

      Well, some of the things I like about python:
      1: tightly structured code.
      2: less punctuation.
      3: more readable syntax.
      4: full OOP from the ground up (in contrast to perl where the OOP is bolted on with references).
      5: short production cycle.

      Many of these things can be found in other languages as well. So it largely comes down a matter of preference.

      From the little I have seen, python seems to be a command line language. Is it anywhere similar to Visual Basic, which I have come to see and experience through a GUI?

      Check out tkinter and wxPython.
      • Re:Supprised (Score:3, Informative)

        by eli173 ( 125690 )
        From the little I have seen, python seems to be a command line language. Is it anywhere similar to Visual Basic, which I have come to see and experience through a GUI?


        Check out tkinter and wxPython.
        And if you like KDE, checkout PyQt [riverbankcomputing.co.uk].
    • Re:Supprised (Score:3, Insightful)

      by pHDNgell ( 410691 )
      Can one tell me why I should learn python and not any other programming language anyway? ...uh, because your brain is actually capable of learning more than one way to do things. Some people even know up to *three* programming languages!

      Sarcasm aside, it's not uncommon for me to work in four vastly different programming languages in a single day (usually java, ocaml, python, and C). That's not counting the ``lesser'' languages like sh, javascript, etc...

      If I hear people talking about how a language or d
    • Re:Supprised (Score:5, Informative)

      by Junks Jerzey ( 54586 ) on Tuesday November 30, 2004 @02:35PM (#10955464)
      Can one tell me why I should learn python and not any other programming language anyway?

      I expect this isn't the answer that true Python devotees would express, but here goes anyway: It's a very high-level, very dynamic, language that's reliably cross-platform.

      "Very high-level" differentiates it from Java, which I see as more mid-level. It's also different than Perl 5, which is higher-level than Python in some ways, but convoluted and crusty in other ways (anything involving nested data structures, for example).

      "Dynamic" means you can test code interactively, you don't a build process, you don't waste time enumerating things and creating redundant headers and so on.

      "Reliably cross-platform" is the key. This is where Scheme and Lisp and Haskell fall down. Lisp has a standard definition, but the community is fractured by there not being a standard implementation. You can argue that diversity is good and all that, but it does tend to hurt overall. Python has a huge number of standard library modules as a result.
  • Is it just me? (Score:5, Interesting)

    by digitaltraveller ( 167469 ) on Tuesday November 30, 2004 @12:07PM (#10953799) Homepage
    Or has python strayed from it's original philosophy of 'one best way to do it'?

    I used python in the 1.5 days. The syntax was incredibly clean. Nowadays the language has tremendous idiomatic power, any programming language researcher should be familiar with it.

    But that power has brough alot of complexity. At the end of the day, languages are tools and the learning curve to understand (particularly others) python code seems to be increasing.
    • Re:Is it just me? (Score:2, Informative)

      by Anonymous Coward
      It's not just you.

      The "eye opener" for me was reading the Python cookbook. Almost every recipe listed 2-3 ways to do everything, most of them hard to understand and using Python "tricks". Many of them depended on new 2.x features. I realized that there are now two kinds of classes in Python for instance.

      The Python community has also grown arrogant like the Perl community. If a newbie writes something that can be re-written with a list comprehension for instance, it's pretty much given that nobody will act
      • Re:Is it just me? (Score:5, Insightful)

        by pclminion ( 145572 ) on Tuesday November 30, 2004 @12:27PM (#10954014)
        If a newbie writes something that can be re-written with a list comprehension for instance, it's pretty much given that nobody will actually answer his question, choosing instead to re-write his program for him using tricks and shortcuts.

        List comprehensions are not "tricks," they are an extremely powerful language feature. Newbies should be taught how to use them, and translating their loop-based code into list comprehensions is probably the best way to do that.

        Python can be written from either an imperative standpoint or a pseudo-functional one. Most of the highly skilled Python programmers code in the pseudo-functional style, because it is more efficient and (arguably) more elegant.

        Sure, you can get into some pretty scary territory with various combinations of sum(), map(), reduce(), and list comprehensions but that's your choice. I admit that there should not be such a big performance gap between the different styles... This is due to not enough effort being spent on improving the VM.

      • Re:Is it just me? (Score:4, Insightful)

        by tungwaiyip ( 608795 ) on Tuesday November 30, 2004 @02:27PM (#10955343) Homepage
        The 'one best way to do it' mostly mean basic language operations, like iterating over a list. Many recipes in the Python cookbook are really mildly complex utility programs. They are differ in features, complexity, performance and intented use. The are naturally many ways to do similar things. And if you take these variables into account, you will find they are not really doing the 'same' thing.

        Since Python 2.x there is a move toward iterators and generators. Rather than seeing this as bloats I would say this Python is maturing to handle real world applications. If you are handling simple data and performance is not an issue, use regular lists. If you writing application to handle arbitrary large data set or performance is an issue, go for iterators and generators. List comprehension is a neat language construct but I don't see any need to rush rewriting anything.
    • Re:Is it just me? (Score:5, Informative)

      by Jerf ( 17166 ) on Tuesday November 30, 2004 @01:29PM (#10954632) Journal
      Or has python strayed from it's original philosophy of 'one best way to do it'?

      To a degree, yes. Largely to the extent it has it is a result of backwards-compatibility; while the Python designers do not make the mistake of enshrining reverse compatibility above all else, they do try to avoid gratuitously compromising it.

      As a result, as better ways to do things have emerged, sometime the old ways hang around and muss things up. However, for any given version there is always a "core" that you can stick to that is very close to "one best way to do it"... and despite what a first reading tells you, you really don't throw much of the language away.

      For instance, while in modern Python you can say either
      a = []
      for i in range(5):
      a.append(i*2)
      or
      a = [i*2 for i in range(5)]
      the latter is the "one right way to do it". Few, if any, new additions truly leave you with two equally good choices.

      (One of Guido's examples is the "lambda" statement, but a lot of people, including me, rather like not needing to replace
      self.register("event", lambda event: self.keyPressed())
      with
      def handler(event):
      self.keyPressed()
      self.register("event", handler)
      but hey, that's life. (While that isn't code for any GUI toolkit in particular that is a pattern common to all of them.))

      By and large, none of these things have affected the difficulty of learning Python from scratch and using its libraries. It has affected the difficulty of reading other people's code, but I find the alternative, "keeping the language stagnant indefinately", completely unacceptable, and frankly, reading code is hard anyhow. (I was writing code for others long before I was reading other's code.)

      In fact, given as that is the alternative, "keeping the language stagnant indefinately", while I concede it is somewhat sad that we can't jump to an optimal language immediately so that nobody ever has to learn anything past their first impression (not sarcastic, that would be the ideal), that doesn't seem to be working for folks. You might try LISP, though, I gather that hasn't changed syntax, much. (Though I also gather mature programs in that language tend to start looking like their own languages themselves, so that just may move the pain...)
  • Now we just need to wait for 2.4 versions of py2exe, cx_Freeze3, wxPython 2.5.3.1, SPE, IDLE, PyQt, SWIG etc. before we can start using this!

    I expect some software will even die now - like McMillan Installer, as development stopped on 2.3, unless 2.4-devel has some excellent backwards compatibility with 2.3 libraries.

    I'm sticking to 2.3.4 for a good while yet, don't have a use for decorators.....
  • I've always liked Python, but I don't think this update is enough to make me learn it.

    In one respect, it is exactly what I've been hoping for. No more sweeping changes or vast syntactic variances, but they have eliminated some usability problems and silly errors. It's a very mature language now, and seems to be behaving as such, this makes me happy

    Still, though, they seem to be competing for a niche that Perl has a deathgrip on for me. I use Bash whenever I can, Perl when I can't or it would be ugly,

  • lazy question (Score:3, Interesting)

    by hey ( 83763 ) on Tuesday November 30, 2004 @12:17PM (#10953896) Journal
    Does it use that new Parot thingie that Python and Perl were supposed to share?
  • cobol (Score:3, Funny)

    by hey ( 83763 ) on Tuesday November 30, 2004 @12:22PM (#10953954) Journal
    The Decimal type! Finaly Python is catching up to COBOL. Yeah.

    Actually, its useful. Every language should have it.
    • Funny. And read the post just below yours. They finally have included Winsock2 support. This is about 5 years after its original release. Sweet.
  • I'm not sure what it means, but Python is looking an awful lot like CommonLisp, down to the somewhat controversial syntax.

    There are two big differences. One is that CommonLisp made it a lot easier to treat programs as data and vice versa, and it had a built-in high-performance native compiler. On the other hand, Python integrates a lot better with Linux and UNIX, there are tons more libraries for it, and is easier for new users to learn.
  • by dstone ( 191334 ) on Tuesday November 30, 2004 @12:42PM (#10954164) Homepage
    Currently in Python, the C floating point libraries used will produce this:

    >>> 1.1
    1.1000000000000001

    Thus, the Decimal data type was born.

    From PEP 327: "The inaccuracy isn't always visible when you print the number because the FP-to-decimal-string conversion is provided by the C library, and most C libraries try to produce sensible output. Even if it's not displayed, however, the inaccuracy is still there and subsequent operations can magnify the error."
    • No. This shows that interval arithemtic is needed. Why can't I know the precision of results? The printer should be able to know that the value is only accurate to n decimals (or binimals or whatever they're called :), and not print more. We let programs make a mistake that would have made us lose marks in Junior High, and (hopefully? I'm in health now, so I don't know) failed us in College.
  • by pragma_x ( 644215 ) on Tuesday November 30, 2004 @12:43PM (#10954168) Journal
    ...but I am impressed with the whole funciton-decorator addition to the language.

    Function Decorator Proposal/Specification [python.org]

    Its nice to see a language evolve in favor of use without sacrificing readability and overall utility.

    Before:
    def foo(cls):
    pass
    foo = synchronized(lock)(foo)
    foo = classmethod(foo)
    After:
    @classmethod
    @synchronized(lock)
    def foo(cls):
    pass
    Readable is of course in the eye of the beholder... and I am a C and Java programmer with a sizable fetish for D [digitalmars.com]. So while I don't find the syntax all that pleasing to me in terms of my own work, it certainly changes things for reading python code.

    I was also stunned to learn how flexible decorators were in the previous version of python. It's refreshing to be see functions treated as objects... unless I'm mistaken about the concept.

    However its a huge shame that the new decorator syntax isn't supported for classes in 2.4. Seems like that's going to become a wart on a rather consistent language syntax, IMO.

    • I was also stunned to learn how flexible decorators were in the previous version of python. It's refreshing to be see functions treated as objects... unless I'm mistaken about the concept.

      Another important part has been Python 2.2's new-style classes and descriptors [rcn.com]. Descriptors are basically objects with special methods (__get__, __set__, __delete__). When you access a class or instance attribute, instead of returning the descriptor, the a method of the descriptor is called. This is what allows clas

  • sigils sneaking in (Score:4, Insightful)

    by CatGrep ( 707480 ) on Tuesday November 30, 2004 @12:50PM (#10954242)
    So now that Python is using the '@' character for function decorators the Pythonistas can no longer crticize other languages like Ruby (which uses sigils responsibly) for their use of '@' (I'm not including Perl in the list of languages that use sigils responsibly, btw :)

    Welcome to the sigil club! Pandoras box is now open! '$' can't be too far behind :)
  • python - awesome (Score:5, Insightful)

    by hashmap ( 613482 ) on Tuesday November 30, 2004 @02:08PM (#10955094)
    In some of my last projects I had to analyze a Perl and a Java program. I programmed a few years in both of these, but now after a year with Python I was truly suprised of how primitive these languages felt.

    All those funny symbols, casting back and forth in perl just getting in the way yet don't really say anything useful ... here is an example:

    foreach my $val(@{$G->{spec_val}}) {
    ...@{$G->{species}} = $G->{dbh}->selectrow_array($G->{sth_species},undef ,$val);
    ...if(@{$G->{species}}) {
    ......$G->{spec_label}{$val} = $G->{species}[0]. '; '. $val;
    ...}
    }

    whether or not this is good code is not the point, I have to make it work, look at all that pointless markup, in python this same thing would look like this:

    for val in G.spec_val:
    ...G.species = G.dbh.selectrow_array(G.sth_species, None, val)
    ...if G.species:
    ......G.spec_label[val] = G.species[0] + ';' + val

    (leading . stands for a space )which version would you rather read?

    or that uselessly verbose java where you have to write X number of lines before any action starts ...

    Python is a simple, clean and powerful language where the real value comes tomorrow or next month, when you have to understand and modify what you wrote today. There are no objective measures of this quality you have to try it to believe it.

To be awake is to be alive. -- Henry David Thoreau, in "Walden"

Working...