Live data from Hacker News

Unpythonic Python

skien.cc

51–60 of 156 posts

Re: Unpythonic Python

#51
A reminder that Python generator functions let you use multiple yields.

    from __future__ import print_function
    
    
    def fizzbuzzify(integers):
        for i in integers:
            if i % 15 == 0:
                yield 'Fizbuzz'
            elif i % 3 == 0:
                yield 'Fizz'
            elif i % 5 == 0:
                yield 'Buzz'
            else:
                yield str(i)
    
    
    print(', '.join(fizzbuzzify(range(1, 101))))
    
    for i in fizzbuzzify(range(1, 101)):
        print(i)

Re: Unpythonic Python

#52
post #14

Earlier quoted context omitted.

I generally don't particularly like giving punctuation meaning that, well, isn't punctuating. The bottleneck when writing code is almost never keypresses. I think CoffeeScript gets it probably the most right of languages I've worked with, in that the choice of punctuation makes intuitive sense... "Hey! It's an Arrow. It goes from here to here". FWIW, I don't like the word "lambda" either... Naming things with one let…

The reasoning behind using '\' for lambda in Haskell was because it sort of looks like a lambda character ( λ vs \ ) if you squint hard enough.

I wonder if that explains the Ballmer peak...

Re: Unpythonic Python

#53
Since we're all sharing our fizzbuzzes, here's mine (from my blog http://seriously.dontusethiscode.com/2013/04/29/bad-intervie...)

Note that this solution is generalised for any divisors and generates an infinite sequence.

    from itertools import chain, combinations, count
    from operator import mul, add
    fizzbuzz = lambda terms: (lambda terms: ({x%d:w for d,w in terms}.get(0,str(x)) for x in count(1)))(tuple((lambda (d,w):(reduce(mul,d),reduce(add,w)))(zip(*x)) for x in chain.from_iterable(combinations(sorted(terms.iteritems()),s) for s in xrange(1,len(terms)+1))))

    terms = {3:'fizz', 5:'buzz', 7:'baz'}

    from itertools import islice
    print list(islice(fizzbuzz(terms),None,25))

Re: Unpythonic Python

#54
post #3

Playing code golf with Python, this is the shortest I could get: https://gist.github.com/tghw/3702360 Definitely a little unpythonic.

Here's mine: ['Fizz' * (not bool(i % 3)) + 'Buzz' * (not bool(i % 5)) for i in xrange(1,101) if i % 3 == 0 or i % 5==0] EDIT: I hate lambdas. Also I'm not saying the above is pretty or a good idea, but I had some fun.

[deleted]

Re: Unpythonic Python

#55
One of the solutions in the comments I found quite pythonic and concise. Somehow people have it in their heads that "Pythonic" means long-winded. And yes, you have to read the code and think for a second to understand it, but that's no crime.

  [(not x % 3) * 'Fizz' + (not x % 5) * 'Buzz' or x for x in range(1, 101)]

Re: Unpythonic Python

#56

The superfluous semicolons on line endings in the C example gave me a chuckle.

He forgot one on the "i += 1" (which would be i++ in a for loop but Python doesn't have that operator).

But that whole line is weird, because I think the C example should use a "for" loop, not increment the main counter at the top of a while loop, even if it has to use "for i in range(1, 101)" like in pythonic python. A C programmer like me (who loves python too) would immediately think "for (i = 1; i <= 100; i++)" for that (although counting from 1 is strange, it's what the problem asks for).

Re: Unpythonic Python

#57
post #35

A highly Pythonic, Easier to Ask Forgiveness than Permission[1] version: FIZZ=3 BUZZ=5 cache = {} for i in range(FIZZ-1, FIZZ*BUZZ, FIZZ): cache[i] = 'Fizz' for i in range(BUZZ-1, FIZZ*BUZZ, BUZZ): try: cache[i] += 'Buzz' except KeyError: cache[i] = 'Buzz' for i in range(100): try: print cache[i%(FIZZ*BUZZ)] except KeyError: print i+1 [1] https://docs.python.org/2/glossary.html#term-eafp A generator version: from ite…

Or better yet, don't even bother asking for forgiveness or permission:

    from collections import defaultdict
    FIZZ=3
    BUZZ=5
    cache = defaultdict(str)
 
    for i in xrange(FIZZ-1, FIZZ*BUZZ, FIZZ):
        cache[i] = 'Fizz'
     
    for i in xrange(BUZZ-1, FIZZ*BUZZ, BUZZ):
        cache[i] += 'Buzz'
 
    for i in xrange(100):
        print cache.get(i%(FIZZ*BUZZ), i+1)
But I'm rather partial to the generator versions you and others posted.

Re: Unpythonic Python

#58
post #14

Earlier quoted context omitted.

I generally don't particularly like giving punctuation meaning that, well, isn't punctuating. The bottleneck when writing code is almost never keypresses. I think CoffeeScript gets it probably the most right of languages I've worked with, in that the choice of punctuation makes intuitive sense... "Hey! It's an Arrow. It goes from here to here". FWIW, I don't like the word "lambda" either... Naming things with one let…

So what about the '*' in C or even better the '.' in so many object oriented language. > The bottleneck when writing code is almost never keypresses. No, it's readability and that often comes with terseness. Every line break because I have to spell out lambda or every refactoring that removes the function from its original context so I can avoid a line break is bad for readability. In that aspect the '\' in Haskell d…

> So what about the '*' in C

I don't like it... I don't what I'd do if starting from scratch, and there might not be better, but it definitely causes readability pain.

> the '.' in so many object oriented language

I have less of a problem with this, because there's some non-programming analog to be found (Section 1.1, Article 3.2, etc.). That said, I think, at some point, it's harmful to OOP in that it makes it hard to sort out properties and messages, and the roles of one or the other.

I agree 100% on readability - the problem for me comes when words get mapped onto abbreviations and symbols that are almost entirely constructed and/or alien to most readers.

Re: Unpythonic Python

#60

One of the solutions in the comments I found quite pythonic and concise. Somehow people have it in their heads that "Pythonic" means long-winded. And yes, you have to read the code and think for a second to understand it, but that's no crime. [(not x % 3) * 'Fizz' + (not x % 5) * 'Buzz' or x for x in range(1, 101)]

Things taking longer to read and understand is perhaps the central crime of unmaintainable code, no matter how concise otherwise.
Post reply on HN