News for hackers. Stuff that matters.
Re:The Zen of Python (by example) by softbuilder on Tuesday March 13, 2012 @04:22AM (#3697491)
Troll bait for Pythonistas. At least I hope that's what that is, because this needs some serious zen-ification otherwise.

To summarize, while switching religions: "The Tao that can be expressed is not the eternal Tao".

But if you're going to try to express the Zen of Python, you can do a hell of a lot better than this.

Re:The Zen of Python (by example) by jacobolus on Tuesday March 13, 2012 @04:40AM (#3697531)
Indeed. Half of it seems to be bashing popular libraries the author doesn’t like, and the other half is a mixture of extremely contrived examples, and examples that miss the point of whatever particular part of the Zen they’re supposed to illustrate.
Re:The Zen of Python (by example) by cysun on Tuesday March 13, 2012 @05:07AM (#3697594)
I thought I was missing something. I sure feel better about myself now.
Re:The Zen of Python (by example) by xerula on Tuesday March 13, 2012 @05:47AM (#3697680)
Even as a fledgling Python coder, I found this distinctly unenlightening. But, as a biologist, the part that really bugged me were the functions that regard yeast as invertebrate animals.
Re:The Zen of Python (by example) by ramanujan on Tuesday March 13, 2012 @09:07AM (#3698202)
The "identify this animal" example has a serious bug. This:

  def identify(animal):
      if animal.is_vertebrate():
          return identify_vertebrate()
      else:
          return identify_invertebrate()
should be

  def identify(animal):
      if animal.is_vertebrate():
          return identify_vertebrate(animal)
      else:
          return identify_invertebrate(animal)
Arguably this mix of OO and procedural code is bad as well. But less arguably, the initial example (with a simple identify function) was far better than the rewrite.
Re:The Zen of Python (by example) by oinksoft on Tuesday March 13, 2012 @09:50AM (#3698384)
In any case the else: is pointless.
Re:The Zen of Python (by example) by dustingetz on Tuesday March 13, 2012 @03:03PM (#3699841)
its subjective, arguably a style using ternary operator is better because it is composable - it evaluates as an expression, as opposed to a series of statements. it's something the lisp and functional programming people like - no implied dependency on order in which statements execute.

i dunno if this is valid python but it demonstrates the idea

  doSomething(
    identify_vertebrate(animal) if animal.is_vertebrate() \
    else identify_invertebrate(animal))

  doSomething( if( is_vertebrate(animal)
                   identify_vertebrate(animal)
                   identify_invertebrate(animal)))

  (doSomething (if (is_vertebrate animal)
                   (identify_vertebrate animal)
                   (identify_invertebrate animal)))
this is part of "referential transparency", and once you get past "OMG parens" you realize its a Good Thing. parens are caused by a style preferring composition of expressions over executing statements, not lisp.
Re:The Zen of Python (by example) by bryanh on Tuesday March 13, 2012 @01:49PM (#3699526)
I dunno, I like the readability of an explicit else.
Re:The Zen of Python (by example) by alexatkeplar on Tuesday March 13, 2012 @04:52AM (#3697558)
In #3, SQLAlchemy loses because it's "complex" while JSON is "simple". In #4, SQLAlchemy loses because this time it's "complicated", whereas inlining SQL create table statements is merely "complex".

Conclusion: for Hunter Blanks, SQLAlchemy can never win.

Re:The Zen of Python (by example) by jobeirne on Tuesday March 13, 2012 @06:30AM (#3697767)
IMO, #3 was more about YAGNI[1], i.e. you probably won't need the speed, integrity constraints, relations, etc. delivered by SQL, so keep your data model flexible and lightweight until a shortage of those things is actually getting in your way.

I wouldn't be surprised if many people criticizing #3 had no practical experience with NoSQL and the benefits brought by its lack of baggage.

[1]: http://en.wikipedia.org/wiki/You_aint_gonna_need_it

Re:The Zen of Python (by example) by dchest on Tuesday March 13, 2012 @06:27AM (#3697761)
"The order of examples is not necessarily bad first, good second." http://news.ycombinator.com/item?id=2203101
Re:The Zen of Python (by example) by glassx on Tuesday March 13, 2012 @08:15AM (#3698036)
SQLAlchemy is "complex" in both #3 and #4, so it wins in #4.
Re:The Zen of Python (by example) by pjo on Tuesday March 13, 2012 @05:01AM (#3697580)
Re:The Zen of Python (by example) by hblanks on Monday March 19, 2012 @07:31PM (#3726923)
Hi, all. I'm Hunter Blanks ([email protected]).

Folks seem to have found a lot of implicit meaning and bugs in what was, at its grandest, a 5 minute talk at RedSnake Philly 2011. I'll just make two comments:

1) This in now up on GitHub at: https://github.com/hblanks/talks/tree/master/2011/zen_of_pyt...

so if you feel strongly about making this better, you should send me a pull request.

2) People seem to have decided that the top (or the bottom?) of every example is the more pythonic one. I suppose I should have kept a consistent order, but, as I noted in the initial HN thread, that just wasn't necessary since this was delivered in the context of a talk.

Re:The Zen of Python (by example) by wging on Tuesday March 13, 2012 @09:25AM (#3698261)
This doesn't work. I think it's an attempt at a closure, which you can do in the latest Python 3.x by `nonlocal i` as the first statement in the function definition...

  def make_counter():
    i = 0
    def count():
      """ Increments a count and returns it. """
      i += 1
      return i
    return count
Re:The Zen of Python (by example) by pash on Tuesday March 13, 2012 @12:51PM (#3699213)
You can cheat in Python 2.x by giving the inner function a keyword argument that defaults to the value you want to close over:

    ...
        def count(i=i):
            ...
    ...
Re:The Zen of Python (by example) by abecedarius on Tuesday March 13, 2012 @03:40PM (#3700012)
Won't do what's intended in this case. I tried it now just to make sure.

I'd use itertools.count().

Re:The Zen of Python (by example) by pash on Tuesday March 13, 2012 @10:03PM (#3701455)
Yes, I just meant to point out that there is a way to do closures in Python 2.x. Looks like here the author wants a function that saves its internal state, i.e., a generator.
Re:The Zen of Python (by example) by abecedarius on Wednesday March 14, 2012 @12:22AM (#3701770)
Closures actually do work without that trick since many versions back. It's setting a nonlocal that still sucks.
Re:The Zen of Python (by example) by pash on Wednesday March 14, 2012 @03:41PM (#3704953)
Well, they sort of work. Closures don't work properly [0] in some lexical contexts without using the default-argument trick because of the way function definition works in Python:

    fs = []
    for i in range(5):
      def f():
        print(i)
      fs.append(f)

    gs = []
    for i in range(5):
      def g(i=i):
        print(i)
      gs.append(g)
The functions in `fs` all print 4 because they all refer to the final object assigned to `i` in the `for` loop. The functions in `gs`, on the other hand, print 0 through 4, as they "should" because the `i` in `g` is assigned to the object currently referenced by the `for` loop's `i` each time the `def` statement is evaluated. This distinction in behavior is obscured in the classic function-inside-a-function example of closures because you pass the object to be closed over to the outer function each time you want to create a new closure. So the result is analogous to using the default-argument trick in the example above.

Anyway, that's all I meant to point out. I misinterpreted your reference to `nonlocal`, which I'm not very familiar with as I don't really use Python 3 much yet. So sorry for my nonsensical reply.

[0] By "properly" I mean as closures work in pure functional languages, where they originated. I realize a programmer who understands Python's data model shouldn't generally expect them to work that way in Python.

Re:The Zen of Python (by example) by abecedarius on Wednesday March 14, 2012 @06:15PM (#3705688)
Oh, yes, good point, though I wouldn't call it a problem with how closures work -- Lisp has the same issue, for example, if you did a (dolist) or (loop) just like your Python code's 'for' loop. In both cases we have a language not originally designed for a style using frequent closures and running into some gotchas thereby.

My answers above were really short because I was on a tablet. May have come across as curt.

Re:The Zen of Python (by example) by perfunctory on Tuesday March 13, 2012 @09:26AM (#3698263)
make_counter and make_adder are not equivalent. How can he compare the two?
Re:The Zen of Python (by example) by tzury on Tuesday March 13, 2012 @02:13PM (#3699625)

    from menagerie.models import cat as cat_models
This is not recommended at all
Re:The Zen of Python (by example) by iclelland on Tuesday March 13, 2012 @03:18PM (#3699904)
Also, it should have read

    from menagerie.cat import models as cat_models
    from menagerie.dog import models as dog_models
    from menagerie.mouse import models as mouse_models
Because otherwise it doesn't match the code in the first example for #3, and also because if your packages are ordered that way, then why not just

    from menagerie.models import cat, dog, mouse
and forget about changing the local module name.
Re:The Zen of Python (by example) by zackattack on Tuesday March 13, 2012 @02:22PM (#3699658)
By whom, and why not? I like it. It's explicit. Self-documenting.