
Unpythonic Python - bluedino
http://skien.cc/blog/2014/04/09/unpythonic-python/
======
exDM69
When you write too much Haskell, your Python code starts to look like this:

    
    
        print('\n'.join(
            'FizzBuzz' if x%5==0 and x%3==0
            else 'Fizz' if x%3==0
            else 'Buzz' if x%5==0
            else str(x)
            for x in range(1, 101)))
    

I would really like to have a "let" expression in Python to avoid having to
write a new function with a def statement when you could get away with a
simple lambda or generator expression.

~~~
acqq
And when you write C carefully, the C code looks like this (thanks
seanjensengrey and rhth54656 for ideas):

    
    
        int i; static char* a[] = { "%d\n", "Fizz\n", "Buzz\n", "FizzBuzz\n" };
        for ( i = 1; i < 101; i++ )
            printf( a[ (i%5==0)*2 + (i%3==0) ], i );
    

The loosely similar Python:

    
    
       for i in range( 1, 101 ):
            print( [ i,'Fizz','Buzz','FizzBuzz' ][ (i%5==0)*2 + (i%3==0) ] )

~~~
acqq
And my Visual C 6 compiles the above C to this x86 asm with a single
conditional jump, just for the loop:

    
    
        mov	edi, DWORD PTR __imp__printf
        mov	esi, 1
       L1:
        mov	eax, esi
        cdq
        mov	ecx, 5
        idiv	ecx
        mov	eax, esi
        mov	ebx, 3
        push	esi
        mov	ecx, edx
        neg	ecx
        sbb	ecx, ecx
        cdq
        idiv	ebx
        inc	ecx
        neg	edx
        sbb	edx, edx
        inc	edx
        lea	edx, DWORD PTR [edx+ecx*2]
        mov	eax, DWORD PTR arr[edx*4]
        push	eax
        call	edi
        add	esp, 8
        inc	esi
        cmp	esi, 101
        jl	SHORT L1
    

The magic is in the neg sbb combination: The neg changes reg to two's
complement but also sets or clears the CF if the argument was != 0 then sbb
reg,reg effectively moves CF to the reg avoiding conditional jump for != 0.

------
JackC
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](https://docs.python.org/2/glossary.html#term-eafp)

A generator version:

    
    
        from itertools import izip, islice
        
        def fizzes():
            i=0
            while True:
                yield '' if i%3 else 'Fizz'
                i += 1
            
        def buzzes():
            i=0
            while True:
                yield '' if i%5 else 'Buzz'
                i += 1
            
        def numbers():
            i=0
            while True:
                yield str(i+1) if i%3 and i%5 else ''
                i += 1
                
        print "\n".join("".join(parts) for parts in islice(izip(fizzes(), buzzes(), numbers()), 100))

~~~
binarycrusader
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.

------
softbuilder
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)]

~~~
ehsanu1
Things taking longer to read and understand is perhaps the central crime of
unmaintainable code, no matter how concise otherwise.

~~~
MichaelDickens
I think this code is easier to read than the more verbose 12-line version
given in the article. It takes longer to read per line, but less time total.

~~~
Shish2k
It's not just more complexity per line, it's also a higher level of
complexity, using language-specific features that people who aren't fluent in
python wouldn't be familiar with (multiplying a string by a boolean)

~~~
groovy2shoes
By that logic, no one should write anything in idiomatic French because anyone
who isn't fluent in French wouldn't be able to read it.

~~~
icambron
I was curious about that. Is multiplying a string by a boolean idiomatic
Python? I don't write nearly enough Python to know, but it strikes me that
this might be more like writing French using lots of obscure words.

~~~
softbuilder
This starts to get into "what is idiomatic python?" which changes as the
language evolves. For example, before Python had an official ternary form,
this was a common idiom:

    
    
        account.status = ["paid", "unpaid"][amount_due > 0]
    

This does the same thing as the FizzBuzz example, coercing a bool to int. Here
the int is used as an index into the list of the two strings.

Personally, I found this handy and liked it a lot. Others didn't and now there
is this, which isn't bad:

    
    
       account.status = "unpaid" if amount_due > 0 else "paid"
    
    

Maybe it's less like using obscure French and more like speaking in a slightly
different dialect, or in a different region with different cultural
references.

------
platz
The actual Java implementation:
[https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...](https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition)

A non-programmer’s solution to “Fizz Buzz”
[https://news.ycombinator.com/item?id=4853509](https://news.ycombinator.com/item?id=4853509)

FizzBuzz Still Works [http://www.globalnerdy.com/2012/11/15/fizzbuzz-still-
works/](http://www.globalnerdy.com/2012/11/15/fizzbuzz-still-works/)

FizzBuzz with CSS
[http://dabblet.com/gist/2628265](http://dabblet.com/gist/2628265)

------
seanjensengrey
[https://gist.github.com/seanjensengrey/d053e7fa709e0699e291](https://gist.github.com/seanjensengrey/d053e7fa709e0699e291)

If free version.

    
    
        t = {}
        t[0,0] = lambda x: x
        t[1,0] = lambda x: "Fizz"
        t[0,1] = lambda x: "Buzz"
        t[1,1] = lambda x: "FizzBuzz"
        
        def tests(x):
            return (x % 3 == 0, x % 5 == 0)
        
        for x in range(1,101):
            print t[tests(x)](x)

~~~
acqq
Good idea. Enhancing:

If, lambda, logical operators except == and string concatenation free version
(Python 3)

    
    
        for x in range( 1, 101 ):
            print( [ x,'Buzz','Fizz','FizzBuzz' ][ (x%3==0)*2 + (x%5==0) ] )

~~~
acqq
And also C based on the same idea as my Python (but this has to ? for 0s):

    
    
        int i;
        char* a[] = { 0, "Buzz", "Fizz", "FizzBuzz" };
        char* f[] = { "%s\n", "%d\n" };
        for ( i = 1; i < 101; i++ ) {
            char* s = a[ (i%3==0)*2 + (i%5==0) ];
            printf( f[!s], s ? s : i );
        }

~~~
rhth54656
Don't ruin that version with an if statement.

Use this and avoid it( and the second array as well ):

    
    
      char * a[] = { "%d\n" , "Fizz\n" , "Buzz\n" , "FizzBuzz\n" } ;

~~~
acqq
Brilliant, thanks! The C version is now:

    
    
        int i; char* a[] = { "%d\n", "Fizz\n", "Buzz\n", "FizzBuzz\n" };
        for ( i = 1; i < 101; i++ )
            printf( a[ (i%5==0)*2 + (i%3==0) ], i );

------
th0ma5
Reminds me of "Evolution of a Python Programmer"
[https://gist.github.com/fmeyer/289467](https://gist.github.com/fmeyer/289467)
... seems like I've perhaps seen other versions of this?

~~~
platz
The Evolution of a Haskell Programmer

[http://www.willamette.edu/~fruehr/haskell/evolution.html](http://www.willamette.edu/~fruehr/haskell/evolution.html)

------
solox3
This was what one of our Java coworkers wrote a while back:
[https://gist.github.com/1337/8155054](https://gist.github.com/1337/8155054)

~~~
elwell
I don't think you need to even explicity say he's used to Java.

Wow... I've never felt the need to the use the factory technique.

~~~
marcosdumay
I use factories a lot when using Django... But, of course, in Python they are
functions that return a class, not classes.

Interfaces instead are completely unpythonic. Or, maybe I should call them
antipythonic?

------
tghw
Playing code golf with Python, this is the shortest I could get:

[https://gist.github.com/tghw/3702360](https://gist.github.com/tghw/3702360)

Definitely a little unpythonic.

~~~
gamegoblin
Something annoying about python is that the word "lambda" is so long for what
are supposed to be one-off functions.

You have

    
    
      f=lambda x,y=1,a='Fizz',b='Buzz': ...
    

But it's actually shorter to say

    
    
      def f(x,y=1,a='Fizz',b='Buzz'): ...
    

I much prefer Haskell's

    
    
      \x -> x
    

Style lambdas.

~~~
jowiar
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 letter
are generally a bad idea that we'd do better to divest ourselves of, but there
is a bit of legacy to deal with. Either way, they make a field (and statistics
is a major offender here, with p-values and t-tests and whatnot), terribly
inaccessible.

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

~~~
tormeh
That's just horrible. I don't know what more to say about it than that. How
did anyone think this would be a good idea on balance?

~~~
gamegoblin
Mmm I suppose it's really just preference. I love that syntax. But I guess
there's no arguing about taste.

~~~
tormeh
Well, it's typing-friendly but not (re)learning-friendly. I guess it depends
how you weigh those concerns.

~~~
marcosdumay
It's also very reading friendly.

I normally forgive languages being hard to learn if the bring enough utility.

------
bluepnume
Nobody ever seems to go for the general solution:

words = ( (3, 'Fizz'), (5, 'Buzz') )

def fizzbuzz(num): for value, word in words: if i % value == 0: yield word

for i in range(1, 101): print ''.join(fizzbuzz(i)) or i

~~~
cantcopy
It works even though it should be:

    
    
        words = ((3, 'Fizz'), (5, 'Buzz'))
    
    
        def fizzbuzz(num):
            for value, word in words:
                if num % value == 0:
                    yield word
    
        for i in range(1, 101):
            print ''.join(fizzbuzz(i)) or i

~~~
epidemian
I think a list comprehension reads better than a generator (and works the
same) in this case:

    
    
      def fizzbuzz(num):
          return (word for value, word in words if num % value == 0)
    

And even dropping the fizzbuzz function altogether reads quite nicely IMHO,
though it starts to look a bit golfed:

    
    
      words = ((3, 'Fizz'), (5, 'Buzz'))
    
      for i in range(1, 101):
          print ''.join(s for n, s in words if i % n == 0) or i

------
tormeh
Java doesn't have to be written like that you know. Idiomatic code is
overrated in my opinion. Make it readable and correct, fuck the rest.

------
jdnier
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)

------
antoncohen
My short yet readable Python version:

    
    
        for i in range(1,101):
            if not i % 15: print 'FizzBuzz'
            elif not i % 5: print 'Buzz'
            elif not i % 3: print 'Fizz'
            else: print i
    

The same in Bash:

    
    
        for i in {1..100}
        do
            let "$i % 15" || { echo "FizzBuzz"; continue; }
            let "$i % 5" || { echo "Buzz"; continue; }
            let "$i % 3" || { echo "Fizz"; continue; }
            echo $i
        done

------
agentultra
Here's one in Hy (a homoiconic frontend to Python... it really is just
Python™):

    
    
       (require hy.contrib.anaphoric)
      
       (ap-each (range 1 101)
        (print (cond [(= (% it 15) 0) "Fizzbuzz"]
                     [(= (% it 5) 0) "Buzz"]
                     [(= (% it 3) 0) "Fizz"]
                     [True it])))
    

Reads pretty good too, doesn't it?

[http://docs.hylang.org/en/latest/](http://docs.hylang.org/en/latest/)

------
tubs

        #include <stdlib.h>
        #include <stdio.h>
        #include <sys/types.h>
        #include <sys/mman.h>
        #include <sys/stat.h>
        #include <fcntl.h>
        
        static char c[9];
        
        int p(int i)
        {
            putchar(c[i++]);
            putchar(c[i++]);
            putchar(c[i+(7-i)]);
            putchar(c[i+(8-i)]);
            return 0;
        }
        
        int f(int i, int x) {
            i -= x;
            if(!i) { return p(x); }
            if(i<0) return i+x;
            return x + (f(i,x)  ?: - x);
        }
        
        int d(int a, int b)
        {
            return a-b?d(--a,b)+1:0;
        }
        
        void x(int i)
        {
            if(f(i,3)&f(i,5))printf("%d",i);
            printf("\n");
        }
        
        int i( int c, int target, void (*fn)(int i) )
        {
            return d(target+1,c)?({ fn(c); i(++c,target,fn); }):0;
        }
        
        int main( int argc, char **argv )
        {
            int fd=open(argv[0], O_RDONLY);
            char *m=mmap(NULL,20000,PROT_READ,MAP_PRIVATE,fd,0);
            c[3] = (char)(0x20|m[3]);
            c[4] = m[342];
            c[5] = m[343];
            c[6] = m[351];
            c[8] = c[7] = (char)(((0x38|m[1])<<1)&~0x80);
            i(1,atoi(argv[1]),&x);
            return 0;
        }

~~~
fyolnish
This'd be more fun if it didn't segfault

    
    
        printf(n%15 ? n%3 ? n%5 ? "%d\n" : "Buzz\n" : "Fizz\n" : "FizzBuzz\n", n);

~~~
tubs
Probably segfaults with the shitty ELF hackery :(

------
kazagistar
Since we are talking about crazy python fizzbuzz, allow me to share a creating
I have had sitting around for a while:

    
    
        def fbg(s,r):print("\n".join(map(lambda x:str(x[1])if x[0]==''else x[0],zip(("".join(a for a,b in s if n%b==0)for n in range(1,r+1)),range(1,r+1)))))
        fbg((('Fizz',3),('Buzz',5)),100)
    

Cause, you know, fizzbuzz one-liners need to work for the generic case.

------
mdlthree
This problem is like Project Euler #1. You don't strictly need to divide. I
prefer to skip along the array and put in the new values.

    
    
      n,f,b= 100,3,5
      a = [str(i) for i in range(1,n+1)]
      for i in range(n/f):
          a[(i+1)*(f)-1] = 'Fizz'
      for i in range(n/b):
          a[(i+1)*(b)-1] = 'Buzz'
      for i in range(n/(f*b)):
          a[(i+1)*(f*b)-1] = 'FizzBuzz'

------
iopq
[https://web.archive.org/web/20130511210903/http://dave.fayr....](https://web.archive.org/web/20130511210903/http://dave.fayr.am/posts/2012-10-4-finding-
fizzbuzz.html)

write the haskell solution in python, I already ported it to Rust:

[https://bitbucket.org/iopq/fizzbuzz-in-
rust](https://bitbucket.org/iopq/fizzbuzz-in-rust)

------
mmagin
Doesn't even touch on my personal pet peeve, people who don't use list and
dict literals. I assume they're former Java programmers who got ahold of
enough python knowledge to be dangerous. e.g:

    
    
      x = dict()
      x['a'] = 'string'
      x['b'] = list()
      x['b'].append('foo')
      x['b'].append('bar')

~~~
prescindor
You can say

    
    
        x = dict(a = 'string', b = list(('foo', 'bar')))

------
Myk267
The value in FizzBuzz is the iteration process.

What's the first step? Well, you probably make a stream of numbers. And then a
set of if blocks to test and return strings. Why not keep going?

What happens if you want more fizz buzz strings? Does the giant if-or
statement seem a little unwieldy? Okay, pull the rules out and see if that's
better. Is it easier to test now that it's a function and not a little
stateful object? Do you want your fizzbuzz function to concatenate the strings
or use explicit replacement? Can you make a switch for that? And so on.

That stuff only scratches the surface. I'm sure there's some brain burning
fizz-buzz interviewers out there. It really puts you on the spot to deal with
a stateful program.

One thing that seems really weird to me is this: given the first set of rules,
why does almost everyone write the program that is the least extensible? Is it
the way the question is phrased or scar tissue from imperative programming?

~~~
mturmon
YAGNI.

------
jamesdutc
Since we're all sharing our fizzbuzzes, here's mine (from my blog
[http://seriously.dontusethiscode.com/2013/04/29/bad-
intervie...](http://seriously.dontusethiscode.com/2013/04/29/bad-interview-
answers.html))

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))

~~~
iopq
Much better, you didn't have to do manage 15, 35, 21, 105, etc.

------
novaleaf
I'm not a Java developer, but it seems that the "Javacious Python" example
isn't very Javacious.

it looks like the author was trying really-really-really hard to prove a
point, thus turned a single function into an OOP architecture.

I know that Java is known for bloat, but that's a bit too much of an
exageration

------
rodrodrod
Neat! I'd be interested in seeing pythonic solutions written in other
languages (to the extent that those languages may allow 'Pythonic' style),
too. I find it fascinating to see how certain languages will, for one reason
or another, trend towards certain design patterns and styles.

~~~
hcarvalhoalves
Actually, most Python I write (influence from reading experienced programmers)
tends to the last one, although it's semi-jokingly:

    
    
        def fizzbuzz(n):
            return 'FizzBuzz' if n % 3 == 0 and n % 5 == 0 else None
    
        def fizz(n):
            return 'Fizz' if n % 3 == 0 else None
    
        def buzz(n):
            return 'Buzz' if n % 5 == 0 else None
    
        def fizz_andor_maybenot_buzz(n):
            print fizzbuzz(n) or fizz(n) or buzz(n) or str(n)
    
        map(fizz_andor_maybenot_buzz, xrange(1, 101))
    
    

It's pleasing to use HFOs in Python, as long as you don't abuse lambdas. Also,
some functional types like `defaultdict` can be used to describe code/business
logic with datastructures rather than a bunch of if's, keeping things tidy.

~~~
gamegoblin
I use defaultdict all the time. Very often when describing graphs.

    
    
      g = defaultdict(dict)
    

Allows you to do

    
    
      g[node1][node2] = edge_weight
    

without checking if node1 exists, and if not, saying g[node1] = {}

Also a neat trick (of dubious use) is:

    
    
      def auto_tree(): return defaultdict(auto_tree)
    

Gives you infinitely nested defaultdicts.

~~~
hcarvalhoalves
defaultdict is really multipurpose, quick trees is only one of the neat
tricks. I like the following definition :)

    
    
        >>> Tree = lambda: defaultdict(Tree)

------
dmayle
Two more variants. The first is precomputed without code-based initialization:

    
    
      fizzbuzz = ['FizzBuzz', None, None, 'Fizz', None, 'Buzz', 'Fizz', None,
                  None, 'Fizz', 'Buzz', None, 'Fizz', None, None]
      for x in xrange(1, 101):
        print fizzbuzz[x % 15] or x
    

The second is unique in that there are no conditionals at all. (Not efficient,
especially for large numbers)

    
    
      fizzbuzz = ['FizzBuzz', 1, 1, 'Fizz    ', 1, 'Buzz    ', 'Fizz    ',
                  1, 1, 'Fizz    ', 'Buzz    ', 1, 'Fizz    ', 1, 1]
      for x in xrange(1, 101):
        print str(fizzbuzz[x % 15] * x)[:8]

------
netdog
My for-real-not-humor implementation:

    
    
        def fizzbuzz(i, n):
            while i <= n:
                yield i%15 and (i%5 and (i%3 and i or 'fizz') or 'buzz') or 'fizzbuzz'
                i += 1
    
        for x in fizzbuzz(1, 100):
            print x

~~~
nailer
Tight, but I'd still use multiple yields, all the conditions in the one liner
may be difficult to read.

------
nilkn
There's something minor that's always bothered me about the usual description
of FizzBuzz:

> If the number is divisible by 3, print Fizz instead of the number. If it’s
> divisible by 5, print Buzz. If it’s divisible by both 3 and 5, print
> FizzBuzz.

In a strict interpretation, the first two sentences could be seen as
incorrect. If a number is divisible by 3, you cannot just print 'Fizz' and
move on. You also have to check if it's divisible by 5.

~~~
mantrax4
This is why the description is good.

Sure, it tests whether you can write a set of statements a computer can
understand.

But it also tests whether you can understand the intent behind a set of
statements a human would make, without going on a diatribe about how the
definition is not good enough.

After all, if English was a formal strict language where only one right way
existed to express something, we wouldn't need programmers, would we?

~~~
dragonwriter
> After all, if English was a formal strict language where only one right way
> existed to express something, we wouldn't need programmers, would we?

If you just solved the fact that one meaning can have many expressions, we'd
still need programmers (and, more relevantly, system analysts) just as much.

The relevant problem is that English isn't a formal strict language _where a
particular expression can only have one meaning_ (and, more importantly, that,
people don't use it that way even when it superficially seems to be.)

That is, the problem that requires specialized work to develop unambiguous
requirements for the implementation of (among other things) information
systems isn't that English maps (many expressions) -> (one meaning), but that
it maps (one expression) -> (many meanings).

------
acomjean
We used to have ADA-TRAN code at work. Fortran code migrated to Ada. It was
awful, but it worked so we left it.

It been commented the Perl I write, it written like C programmer.

------
pyrocat
JS version for funsies. I didn't like the idea of specifically checking for
simultaneous mod3 and mod5, so I made this.

    
    
      for (i=1; i<101; i++) {
      	var result = "";
      	if(i%3 == 0)
      		result += "Fizz";
      	if(i%5 == 0) 
      		result += "Buzz";
      	if(result.length == 0)
      		result = i;
      	document.write(result+"<br>");
      }

~~~
olegbl
Ugly version:
for(i=1;i<101;i++)console.log((i%3?"":"fizz")+(i%5?"":"buzz")||i)

------
zachary12
C#

Enumerable.Range(1, 100).ToList().ForEach(a =>{if (a%5 == 0 && a%3 ==
0){Console.WriteLine("FizzBuzz");}else if (a%3 ==
0){Console.WriteLine("Fizz");}else if (a%5 ==
0){Console.WriteLine("Buzz");}else{Console.WriteLine(a);}});

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

~~~
drivers99
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).

~~~
eriktaubeneck
This is what I originally had but I felt that the Python `while` was actually
a bit more true to the way a C for loop is constructed (and `range` seems a
very not C thing to do.) It's not perfect!

------
pizza

        [print(("Fizz" * (n % 3 == 0) + "Buzz" * (n % 5 == 0) + str(n) * (0<(n % 3 * n % 5)))) for n in list(range(1,101))]
    

side effects don't matter right?

------
doug1001
i loved this; studying multiple implementations of the same recipe, even if
most are not intended to be "exemplary" but rather cautionary, is a great way
to learn.

This reminds me of a similar effort called "evolution of a python programmer"
and published in this gist:

[https://gist.github.com/ghoseb/25049](https://gist.github.com/ghoseb/25049)

something like 30 different implementations of factorial; my favorites are the
'expert programmer' and the "web designer"

------
danbmil99
for i in range(1, 101): print (i if i%3 else "Fizz") if i%5 else "Buzz" if
i%15 else "FizzBuzz"

[edit: proper place
[https://news.ycombinator.com/item?id=7564988](https://news.ycombinator.com/item?id=7564988)]

------
hit8run
+1 for the pythonic version -1 for the weird rest

this assures me that python is the right language for me :)

------
ryangallen
Programming language accents.

------
Systemic33
Not enough factories in the java-ic python...

------
mantrax4
There's no honest attempt to explain the philosophy behind every language with
real-world examples in Python. It's just childish jokes.

It's the equivalent of saying "Ze fish in le river" is "Frenchish English". Ha
ha, stupid French people, right?

It's easy to make fun of programming languages like this, but what does that
teach us? Aside from to mock what is different than what we use right now?

~~~
eriktaubeneck
While I wrote this with tongue in cheek, I also aimed to illuminate the power
of Python's flexibility along with the inherent danger therein. I do admit the
Javacious example was over the top though ;)

