Unpythonic Python
skien.cc
skien.cc
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. >>> let = lambda
File "<stdin>", line 1
let = lambda
^
SyntaxError: invalid syntax
Am I misunderstanding you?>>> print let(4)
8
Edit: Awesome, downvoted for helping.
print expensive_computation(), expensive_computation()
You can do: (lambda x: print x, x)(expensive_computation())
Which would be equivalent to, with an imaginary let syntax: (let x be expensive_computation(): print x, x) def let(x):
yield x
And use it by "iterating": ...
for x in range(1, 101)
for divisible_by_5 in let(x % 5 == 0)
Still not as nice as having actual syntax for it. import contextlib
@contextlib.contextmanager
def let(*values):
yield values
with let(1, 2, 3) as (a, b, c):
print(a, b, c)print([(x%3==0) && (x%5==0) ? "FizzBuzz" : (x%3==0) ? "Fizz" : (x%5==0) ? "Buzz" : x for x in 1:100])
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) ] ) 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. const char *fb[][2] = {{"%d\n", "Fizz\n"}, {"Buzz\n", "FizzBuzz\n"}};
int i;
for (i = 1; i <= 100; ++i)
printf(fb[i % 5 == 0][i % 3 == 0], i);
(It's a pity we have to specify the second dimension manually . . .) 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-eafpA 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)) def fbgen(text, divisor):
while True:
for i in range(1, divisor):
yield ""
yield text
def derrangedBuzz(max):
fizzer = fbgen("Fizz", 3)
buzzer = fbgen("Buzz", 5)
for i in range(1, max + 1):
s = fizzer.next() + buzzer.next()
if s == "":
print i
else:
print s 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. [(not x % 3) * 'Fizz' + (not x % 5) * 'Buzz' or x for x in range(1, 101)] 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.Treating a boolean as an integer is iffy
Multiplying a string by a boolean frankly should be a no-no.
If writing in French for people who are not fluent, I think it would be a good idea to avoid idiomatic language.
Of course, this is true to a certain extent of all programming languages, but I do find Python particularly easy in this respect.
If you make the generator always return a string, then you can make it print, thus:
print '\n'.join((not x % 3) * 'Fizz' + (not x % 5) * 'Buzz' or str(x) for x in range(1, 101)) ['FizzBuzz' if 0 == n % 15 else 'Fizz' if 0 == n % 3
else 'Buzz' if 0 == n % 5 else str(n) for n in range(1,101)] True * "String"
>"String"
And... not 0
>True
I guess knowing the "truthiness" of all regular Python types is useful.or
let f = (replicate . fromEnum . (==0)) .: mod in [concat $ f x 3 "Fizz" ++ f x 5 "Buzz" | x <- [1..101]]
A non-programmer’s solution to “Fizz Buzz” https://news.ycombinator.com/item?id=4853509
FizzBuzz Still Works http://www.globalnerdy.com/2012/11/15/fizzbuzz-still-works/
FizzBuzz with CSS http://dabblet.com/gist/2628265
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)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) ] ) 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 );
}Use this and avoid it( and the second array as well ):
char * a[] = { "%d\n" , "Fizz\n" , "Buzz\n" , "FizzBuzz\n" } ; 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 );Yuck.
Wow... I've never felt the need to the use the factory technique.
Interfaces instead are completely unpythonic. Or, maybe I should call them antipythonic?
[setattr(self, x, kwargs[x]) for x in kwargs.keys()]
Though of course that is a bit too slow and he should do self.__dict__.update(**kwargs)
or for maximum correctness import os; os.remove(__file__)https://gist.github.com/tghw/3702360
Definitely a little unpythonic.
for x in range(100):
print x%3/2*'Fizz'+x%5/4*'Buzz' or x+1for ($i = 1; $i <= 100; $i++) {
$str = str_repeat('Fizz', !($i%3)&1) . str_repeat('Buzz', !($i%5)&1);
echo $str ? "$str\n" : "$i\n";
}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.It's not: with def() you have to explicitly write return, while with lambda it is implicit.
For tghw's solution to work you'd have to have a print outside of the function call (since you can't print from a lambda). With the def, you can print inside of the function (and don't need a return, since you're just printing).
map(print, some_list)
Unfortunately, it returned a map object, which I guess is also new in Python 3 (I assume it's a lazy application device). print(*[1,2,3], sep='\n') def do(gen):
for x in gen:
pass
It evaluates all elements of a generator with storing them in memory. If you don't mind generating some garbage, you can just use the list function instead.https://twitter.com/jooon/status/25054586175
But that isn't a whole lot shorter than the solution pcmonk posted in the thread.
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.
I normally forgive languages being hard to learn if the bring enough utility.
Full list here: https://github.com/haskell/haskell-mode/blob/master/haskell-...
As a lisper, I prefer names and prefix operators - there's a few exceptions where infix operators add improvements to the language, but I dislike having user-defined operators (they make searching a pain, although Hayoo eases some of that).
What is really great is how Haskell enables you to write extremely succinct code by providing powerful abstractions and tools. The fact that you have a type annotation already gives enough meta information in the code that you often can omit a long name. The fact that Haskell functions tend to be short in lines gives you something that is closer to an equation than a command language.
I don't know how to put this in words, but I'll try: Naming things well in programming is the most difficult task after mastering the very basics. I think this is because names are not fundamental for algorithms and programs but are like bookmarks for the programmer and their human brain. In C, a function with one-letter argument names is a nightmare, in Haskell, it actually improves readablity over a verbose version with whole-word names. And then, I have seen a lot of functions that were named very specific in terms of a problem the programmer tried to solve at the time, that however where quite generic, or could have been very generic (think of `sort_customers_by_name()` instead of a `sort_by()`.
I share your dislike of extreme operator usage. It is a problem that whatever permutation of +-!@#! are used as operators in libraries for functionality that the user rarely needs. But the general approach of haskell for succinctness is a good one.
I suppose these things are a matter of taste as much as anything else. But when people talk about a Haskell program being 'elegant', I never think to myself "what, that mess?"
> 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 does great. Also in Haskell anonymous functions are so important that they definitely deserve their own special character to shorten many expressions.
I only see this becoming a problem if it is used in excess, like in C++ and especially in C++11.
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.
If you don't like typing it, have a macro. Otherwise, as Objective C shows, the verbosity of code is not relevant at all. It's what it says and what it does, which is.
And access modifiers are + and - rather than static and nonstatic.
Objective-C definitely isn't above using lightweight syntax. Where it favours verbosity is APIs.
But I hoped you'd see beyond the direct comparison of lambdas with Objective C's blocks.
I'm saying that short code doesn't automatically translate to more readable or better code, Objective C's message syntax is the proof (if I have to be painfully specific about it).
I write a lot of JS and typing out "function" or "return" was never on the list of things I found a problem, despite I also work in C#, which uses the short => variation.
Yes, short code doesn't automatically translate to readible code. But neither does long code.
You can't wheel out objective-c's fondness for long self-documenting message names as self-evident proof that the syntax for lambdas must be verbose.
Long message names are good because they let you clearly describe what is otherwise a big black box of unknown behaviour.
The syntax for a lambda will always be a lambda, so it doesn't need to be spelt out explicitly each time. Shorter syntaxes such as used by Haskell are easier to visually pattern match on and so can actually aid comprehension.
It's not as simple as longer is always better and anyone who disagrees is obviously foolish and lazy.
IMHO, the objective of the crippled `lambda` really is to make the programmer refactor into reusable functions instead of having λs littered everywhere, which would hurt maintainability.
IMHO, if a feature is useful enough to have in the language, it deserves a good implementation. If it isn't, it shouldn't be there at all. And if it is useful sometimes but doesn't fit well in other situations, providing better alternatives in those situations is a more effective way to avoid dubious code than just artificially crippling the entire feature to discourage its use.
['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.
from itertools import cycle , izip
[(f + b or x) for f, b, x in izip(cycle([''] * 2 + ['Fizz']), cycle([''] * 4 + ['Buzz']), range(1, 100))]
Edit: not sure how to post code in comments. e.g. * is lost
> Edit: not sure how to post code in comments. e.g. * is lost
Put a couple of blanks before each line. This displays it in a monospace font, too.
' '.join(["FizzBuzz" if n%15==0 else "Fizz" if n%3==0 else "Buzz" if n%5==0 else str(n) for n in range(1,101)])
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
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 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 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) 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 (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? #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;
} printf(n%15 ? n%3 ? n%5 ? "%d\n" : "Buzz\n" : "Fizz\n" : "FizzBuzz\n", n); 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. 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'write the haskell solution in python, I already ported it to Rust:
x = dict()
x['a'] = 'string'
x['b'] = list()
x['b'].append('foo')
x['b'].append('bar') x = dict(a = 'string', b = list(('foo', 'bar')))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?
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))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
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. 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. >>> Tree = lambda: defaultdict(Tree) 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] 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> 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.
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?
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).
> 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?
This is very off-topic, but I'm not sure I agree with it. You're assuming that it would be easy to find the one unique way to express a given computation such that anybody could write it down. Even if English had this uniqueness property, I don't think that would be true at all.
Natural language can be used with precision, and this is an important skill for engineers. Being able to identify ambiguity and inconsistency is an important part of that skill so yes, noticing it within a question should count in favor of the candidate. Dismissing it as being pedantic is the wrong response, because if you are working on something critical (secure communications software, for example) you need to handle ideas with precision.
It been commented the Perl I write, it written like C programmer.
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>");
}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);}});
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).
Format strings feel like C. And not the fun parts of C.
[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?This reminds me of a similar effort called "evolution of a python programmer" and published in this gist:
https://gist.github.com/ghoseb/25049
something like 30 different implementations of factorial; my favorites are the 'expert programmer' and the "web designer"
[edit: proper place https://news.ycombinator.com/item?id=7564988]
this assures me that python is the right language for me :)
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?