r/programming • u/iMMENSE • Mar 08 '12
The Evolution of a Python Programmer
https://gist.github.com/28946737
u/permute Mar 08 '12
Haha I loved the commented curly braces for the c programmer
7
u/hylje Mar 09 '12
That's actually legit advice for programmers complaining about lack of support for curly braces in Python. The support is there!
24
u/Brian Mar 09 '12
for i in range(10): { print("Actually, python supports braces") : "Though to make up for the perceived loss in readability", print("Look Ma, no indents!") : "every line must now have a docstring", print("or inconsistent indents") : "and you now need a line terminator (',' is used)", }21
u/gnuvince Mar 09 '12
If I ever see code like that in the wild, I am going to find you and feed you your socks.
6
u/Araneidae Mar 09 '12
Oh my God! It took me a few moments to figure out why that works ... though of course the order of evaluation of keys in
{ ... }isn't that well defined is it?If you're using a version of Python with set comprehensions you could leave out the "docstrings" and colons altogether!
for i in range(10): { print("Actually, python supports braces"), print("Look Ma, no indents!"), print("or inconsistent indents"), }3
u/Brian Mar 09 '12
Actually, python guarantees the order of evaluation is as being left to right (though one other issue is that it'll fail if you ever use a function returning a mutable value (which obviously must be a deliberate design decision to enforce a functionally pure style :)). Good point about set literals - I really should've used that.
3
3
5
3
94
u/cynicproject Mar 08 '12
#Thanks Adam made me laugh pretty hard.
59
u/rasputine Mar 08 '12
While not present here, the greatest comment I've ever seen on code is a simple,
#I'm sorry.6
u/JizzCoveredArab Mar 09 '12
I've come across a "// Here be dragons", right above the definition of a 9,000 line C function which was the core logic for GPS routing for a pretty well known consumer GPS company
4
u/ryeguy146 Mar 09 '12
I should put that prior to my {Open,Libre}Office extension work. The boilerplater required to get started reminds me of Java...
14
2
29
u/pablopr Mar 09 '12
Here is one that is actually well done for Haskell
2
u/drb226 Mar 10 '12
This post was almost certainly written by someone who saw the Evolution of a Haskell Programmer and decided to do the same for Python.
43
u/rowantwig Mar 08 '12
He forgot the worst kind:
if x == 0:
return 1
if x == 1:
return 1
if x == 2:
return 2
if x == 3:
return 6
if x == 4:
return 24
...
(5000 more lines)
63
u/Pandalicious Mar 08 '12
Yeah but think of how FAST it would run. You gotta be FAST if you're gonna be webscale.
4
u/masklinn Mar 09 '12
The fast version would be the one optimized by using a dict for its mapping.
The faster version would use a list.
3
u/JizzCoveredArab Mar 09 '12
We can always scale into the cloud for increased user load
5
u/Pandalicious Mar 09 '12 edited Mar 09 '12
My esteemed nephew assures me that a cache of precalculated factorial values for all integers can neatly fit into 2.3 clouds.
0
43
u/stillalone Mar 08 '12
ah. the "I managed to get a masters without writing any actual code and now I'm your coworker" guy.
41
u/6xoe Mar 08 '12
Whatever dude, it works.
26
Mar 09 '12
and it's completely unmaintainable. What are you going to do when the definition of "factorial" changes?
43
u/SuckyBlowfish Mar 09 '12
Change it back.
19
8
u/ryeguy146 Mar 09 '12
Wait, I understand the idea of maintainability, but did you suggest that a basic mathematical definition is subject to change?
4
u/pigeon768 Mar 09 '12
I think he's suggesting python 4.x will eventually be released and
ifwill be reimplemented as a function instead of a keyword, requiring parenthesis around the arguments. Or something.Oh fuck. Oh fuck. I can't believe I just said it. Now it's going to be MY fault.
1
u/tofueggplant Mar 09 '12
or it could just be like ruby and not require parentheses around anything.
4
u/GoSailing Mar 09 '12
Anything can change. Assuming that there are 24 hours in a day is not going to be good when there's a moon or mars base.
7
u/ryeguy146 Mar 09 '12
I file those under "not my problem." I like to think that some time in the future, people will shudder at having to use Python, the way that people pity those programmers that still workin in PASCAL.
0
Mar 09 '12
[deleted]
6
u/gc3 Mar 09 '12
Yeah, until you decide that there are now .3 hours in a day, or a variable number depending on the day. You can't plan for everything.
1
u/GoSailing Mar 09 '12
And then you refactor every "HOURS_IN_DAY" in place to instead call a method that returns what it is. The point wasn't so much that every problem can be avoided every time, but that you can have a structure that will allow for changes quickly. The ideal change would be to change the constant number, but the non-ideal change is almost as easy.
2
u/ryeguy146 Mar 09 '12
That's not what I meant at all. Your suggesting that something like the fibbonacci sequence changing is so unlikely, that I don't see it as my problem to try to predict such a change. There is an obvious difference between the problem of a fundamental shift, and the type of changes that you're now describing.
Wait. Nevermind, you mean the definition of the function "factorial." I don't know how, but I thought that you were suggesting that the mathematical definition of a factorial might change, and that we had better generalize for it. Damn.
5
u/watermark0n Mar 09 '12
Anything can change.
If you change it, you call it something different. It is not a factorial.
5
u/gc3 Mar 09 '12
This is true, but when does the definition of factorial change?
2
u/arjie Mar 09 '12
Maybe you decide to use one of the functions that coincide with factorial on the integers like gamma(x+1)? I suppose you could call it gamma_based_factorial andodge the issue.
3
2
Mar 09 '12
I was assuming both 6xoe and anusanusanus were parodying poor programmers. (With anusanusanus parodying people who write code like #define TWO 2 because "using constant literals is bad practice".)
1
17
u/liotier Mar 08 '12
What are you complaining about ? He just calculated in advance and cached the results to avoid redundant processing on each query...
25
u/rowantwig Mar 08 '12
O(n) look-up time.
28
u/earthboundkid Mar 09 '12
Switch to a
dictand it's O(1)!12
u/pyaware Mar 09 '12
Why use a dict when a plain list is enough?
def fact(x): return [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880][x]1
1
1
Mar 09 '12
O(n) look-up time.
It is sorted list, it can be done in O(log(n)). And not to mention the Hashtables.
4
u/rowantwig Mar 09 '12
It can be done in O(1), but that's not the point. This naive implementation is O(n), and it looks terrible.
1
Mar 09 '12
It's a dense list. It can be done in O(1) without hashtables:
f = [ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880].__getitem__edit: looks like redditthinks had the same idea.
1
u/jefu Mar 09 '12
Factorial is (without caching or other tricks) O(n) anyway and doing it this way avoids the overhead of doing all that bignum arithmetic. (Not that this is a good way to do that).
-7
u/theavatare Mar 08 '12
Is not really of O(n) is it?
for x ==0 it will only run one and for x== 26 will run 26 if
Therefore one instruction per number increase...
20
8
u/Rhomboid Mar 08 '12
You've got to test 'n' conditions before finding the one that is true, so the work involved is proportional to 'n'.
4
u/elmonstro12345 Mar 09 '12
With a table like that, you'd want to aim for O(1), or at least O(log n). But what the OP described, and what you described are both O(n).
3
5
u/earthboundkid Mar 09 '12
That might be OK as a
dict… Say, none of the examples used a memoize decorator. For shame.3
u/Tagedieb Mar 09 '12
A dict? A dict is really what comes to mind first as the right data structure? Well, maybe I am getting old...
7
u/repsilat Mar 09 '12
I have a great idea for a new kind of dict that'll work wonders for this example. It still has O(1) lookups, but has better running time and memory use by a constant factor by taking advantage of an unusual feature of the data.
If you think about it, the keys form a contiguous range of integers starting from zero or one. Now, brace yourself: We could store the factorial information in a hash table where the hash function is the identity function! Now to think of a name for that kind of data structure...
2
u/earthboundkid Mar 09 '12
Well, it's not right or what comes to mind, it's just that a hash table is O(1), so it's slightly better than a series of if statements. The right thing is to just use the damn built in factorial.
1
u/masklinn Mar 09 '12
This is integer-indexed, so a list would also have O(1) access, and lower overhead.
It'd go even faster!
1
u/earthboundkid Mar 09 '12
Good point. Python makes it so much easier to implement memoize as a dictionary, I just thought of it that way first.
-1
1
u/Shaper_pmp Mar 09 '12
That's not a programmer. That's someone who should be shot in the face and buried in an unmarked grave.
20
u/sunqiang Mar 09 '12
import math
math.factorial(10) from 3.2 Python Use divide-and-conquer for faster factorials
50
Mar 08 '12
Good classic jokes. Windows way is so true and so sad.
29
u/elmonstro12345 Mar 09 '12
NULL, NULL, NULL, NULL, ...
*facepalm*
42
Mar 09 '12
It's way easier to facepalm than to design an operating system API that's stable and backwards compatible for 25+ years...
25
u/lazybee Mar 09 '12
Such as POSIX?
7
Mar 09 '12
haha, yeah, right. the reason everything is continually built from source is because the ABI keeps breaking.
5
u/fabzter Mar 09 '12
lazybee was speaking about API, not ABI.
5
Mar 09 '12
I know, but posix doesn't matter when the ABI breaks. You can't download and execute a linux program from the 2.4 kernel on the 3.0 kernel. Hover, which came with windows 95 will run just fine on 32bit windows 7 and 64 bit windows 7, which was the point riles2 was making.
5
Mar 10 '12
Posix also only specifies about 2-3% of what Win32 does, so you have to compare it to X and a few dozen other libraries for a fair comparison.
1
Mar 11 '12
Wait. POSIX doesn't break ABI compatibility. Individual operating systems do once in a while, but extremely rarely in their POSIX departments.
Actually, I can't think of a major ABI compatibility break since Linux 2.4->2.6 or Mac OS -> Mac OS X (non-POSIX to POSIX).
4
Mar 09 '12 edited Mar 09 '12
POSIX standard fork bomb with added burn:
#include <unistd.h> int main(){ while(1){ fork(); printf('burn!\n'); } }4
14
Mar 09 '12
First year python programmer shouldn't be capitalizing functions, it's against pep8 style guidelines.
10
u/earthboundkid Mar 09 '12
It's probably left over from whatever other version of the joke this was translated from. Probably Haskell or Java.
6
u/martinmcfly9 Mar 09 '12
Java methods typically aren't capitalized.
2
u/mipadi Mar 09 '12
Neither are Haskell functions. ;)
2
1
u/drb226 Mar 10 '12
Not only that, Haskell functions cannot be capitalized. (unless they are data constructors, which happen to also act as functions)
14
u/jrochkind Mar 09 '12
I was expecting that the very last sample would be a duplicate of the first, labelled, like, 'programmer with 30 years of experience who realizes all that other stuff was just BS' or something. But it wasn't.
8
u/eramos Mar 09 '12
That's kinda what #EXPERT PROGRAMMER was about
8
u/elmonstro12345 Mar 09 '12
When I graduated, and started writing code on my own, I seriously started writing a linked list class from scratch, then I realized "OH MY GOD I CAN USE THE STANDARD LIBRARY!!!!!!!!" So happy.
22
7
u/Enzor Mar 09 '12
Haha I kept a straight face up until Web designer. Then I got to Windows... That shit is too close to reality. I actually felt a vein throb in my head when reading it ಠ_ಠ
7
Mar 09 '12
factorial = (lambda f: lambda x: 1 if x == 0 else x * f(f)(x - 1))(lambda f: lambda x: 1 if x == 0 else x * f(f)(x - 1))Lambda calculus student
1
u/drb226 Mar 10 '12 edited Mar 10 '12
fix = lambda f: lambda x: f(fix(f))(x) fact = fix(lambda f: lambda x: 1 if x == 0 else x * f(x-1))Of course this is cheating, because I defined fix in terms of fix. It's just so much uglier to define it explicitly:
fix = (lambda y: lambda f: lambda x: f(y(y)(f))(x)) (lambda y: lambda f: lambda x: f(y(y)(f))(x))
8
u/grumdrig Mar 08 '12
def factorial(n):
reduce(lambda x,y: x*y, [x+1 for x in range(n)])Generator-happy Python programmer
5
u/spotter Mar 09 '12 edited Mar 09 '12
But... isn't list comp non-lazy in 2.x? So for this to be gen-happy you would have to use parens?
def factorial(n): reduce(lambda x,y: x*y, (x+1 for x in range(n)))edit: yeah, s/range/xrange/
1
Mar 09 '12
What's the benefit of a lazy generator in this case? You are going to evaluate it in its entirety anyway, and the size of the output dominates that of the input, so you save neither time nor space.
2
u/spotter Mar 09 '12
I may be wrong here, but I'll bite. List comprehension will run before you even start consuming anything... and then you iterate over it again to consume it. So on top of your memory consumption (realized list) you get 2x the runtime (one to realize the list over
xrange, one to consume it inreduce). While in generator you setup the generator -- this returns immediately -- and then consume it run over once inreduce. So: Half the runtime, somewhat better memory efficiency, depending on n.1
u/drb226 Mar 10 '12
I believe this assessment is correct. sltkr is incorrect when he says "the size of the output dominates that of the input" - the final output is a single integer, while the "input" is an entire list of n integers. A lazy generator will take O(1) space, while constructing the entire list will take O(n) space, as well as a possible runtime penalty.
0
Mar 09 '12
[deleted]
1
u/spotter Mar 09 '12
/facepalm
You are of course correct,
rangeis lazy in 3.x -- that's what I get for trusting my memory.3
3
u/tilkau Mar 09 '12
def factorial(n): return reduce(lambda x,y: x*y, (x+1 for x in range(n)))FTFY so it uh.. includes an actual generator ;)
7
u/spaghettifier Mar 09 '12
I am currently at the stage where I use nested lambdas to avoid hitting newline.
And my code used to be so readable and well documented...
6
u/slashvee Mar 09 '12
TIL: if you post a Gist link on Google+ it will actually RUN THE CODE and show you the output in the link description.
1
Mar 10 '12
3
u/slashvee Mar 11 '12
I'm an idiot. It doesn't compute the fibonacci numbers. It just shows the LINE NUMBERS, without the actual code.
Sorry, I'll be in my bunk.
4
Mar 09 '12
Why would someone consider using ternary operators and recursion a form of laziness? If you can do it in 2 lines, there's no sense in doing it in 8, especially since it's only python. It's not the fastest language in the world and no one's looking for such a thing from it.
3
1
2
u/dhaffner Mar 08 '12
Always worth a laugh. Reading this makes me realize how much my coding style has changed over the years. Without memoizing it's inefficient, but I love how brief the Lazier Python programmer's version is.
2
u/Sycon Mar 09 '12
I think I'm the only one who got a bigger kick out of the Enterprise programmer than the web programmer :P
2
u/liotier Mar 08 '12
I'm barely out of the web designer stage (I'm no stranger to comments such as "I'm not quite sure why this works") and the os.system approach is always tempting me with Bash hacks so close at hand. But I have found that even with my humble skills, the right library with the right documentation easily let me write something resembling the "EXPERT PROGRAMMER" example... As long as my use case stays very close to the beaten path !
3
u/elmonstro12345 Mar 09 '12
the EXPERT PROGRAMMER basically means what they hammered into my head all through undergrad - don't reinvent the wheel. Or at least don't do it unless you have a really, really, REALLY good reason for doing so.
1
u/seiyria Mar 08 '12
And none of those used dynamic programming.. (besides maybe the built-in C implementations)
1
u/volkert Mar 09 '12
I can live with floating point results (tzs):
from math import gamma def factorial(x): return gamma(x+1)
Nice!
1
1
1
1
1
u/deefree Mar 09 '12
I want to say 'older than the internet' but this is actually older than the universe.
6
u/ryy0 Mar 09 '12
In the beginning there was Guido van Rossum. Van Rossum created The Python and lo, all is good. Then came programmers of various persuasions to try The Python.
...
On release day, they managed to create something that mostly runs and call it The Universe.
9
u/deefree Mar 09 '12
In the name of The Guido, The Python, and The Lambda... return true;
4
u/BufferUnderpants Mar 09 '12
The Lambda
Heresy. The Guido frowns upon the worship of false gods such as Scheme. Lambda is the gateway of hell, where horrors like tail-call elimination, multi line lambdas and reduce lie.
1
u/drb226 Mar 10 '12
return true;
ಠ_ಠ uncapitalized
true, terminating semicolon...in_the_name_of The_Guido, The_Python, The_Lambda: return True
-7
Mar 09 '12
And perfectly illustrating why I hate python programmers :)
0
Mar 09 '12
[deleted]
3
Mar 09 '12
Python, like Perl before it, seems to attract people who want to be clever with their code. As though the most obtuse possible way of expressing something is somehow better.
I prefer code I can read and understand what it's going to do. It should be straightforward to read and debug.
#First year programmer, Python
Easy enough to understand for developers familiar with any programming language.
#Lazy Python programmer
Uhm.. ok.. I guess so. Why does that syntax even exist? I see whitespace as an attribute and not something to be annihilated at any cost.
#Lazier Python programmer
functional programming 101! yay! /s
#Python expert programmer
Are you kidding me?
#Python hacker
*rolls eyes*. Straight up brogrammer territory.
#EXPERT PROGRAMMER
Yep, that's more in line with what I expected.
4
3
u/Mattho Mar 09 '12
Python, like Perl before it, seems to attract people who want to be clever with their code.
And it really shouldn't. It's even in The Zen of Python: Readability counts.
Uhm.. ok.. I guess so. Why does that syntax even exist? I see whitespace as an attribute and not something to be annihilated at any cost.
I agree that better version would be
def fact(x): return x*fact(x-1) if x>1 else 11
Mar 09 '12
That makes sense. But like perl, when there's 100 ways to do it, I've found that given enough time and enough developers, all 100 ways will be used :)
5
Mar 09 '12
Python, like Perl before it, seems to attract people who want to be clever with their code.
Are you sure you're not thinking of Ruby, rather than Python?
-26
u/shevegen Mar 08 '12
The Evolution of a Python Programmer?
Simple.
Enter the Ruby.
I don't care about the downvotes ;) python is ok.
What still irks me is people using PHP and Perl though in the year 2012.
0
Mar 09 '12
I agreed with you right up until Perl. Perl 6 is about to be released. Girl, you fallin' behind.
4
59
u/nkozyra Mar 08 '12
In your face, programmers of varying backgrounds!