

Python Facts - ronreiter
http://facts.learnpython.org/

======
pace
Can it be true that the Python coverage on HN is overproportional compared to
its real world usage?

If I look around the world is full of Ruby and Rails. Sites, libs, meetups,
developers, everything is on Ruby or Ruby on Rails. Python and Django devs are
so damn rare in real world -- I just know two of 100.

Not that I don't like Python but I am really wondering why Python gets such a
strong coverage on HN. Every second day there's some Python thing on HN. BTW
with Clojure it's the same but Clojure is something new, so I understand the
visibility there.

Please don't downvote -- it's nothing against Python, I just want to see if
the Python base increased or something happend I've missed. Thanks

How can it be?

EDIT: Thanks to all for the replies. What's interesting about this thread: I
got tons of downvotes (besides upvotes) for the first comment. So, I assume
this Python vs Ruby discussion seems to be a very emotional topic. Thanks to
the replies I have now a better understanding that Python is older and
dominant in a many non-web environments. My impression is still that
especially in web environments we have much more pace and development in Rails
than Django (just compare what DHH put in 3.1, Coffee, Sass, etc. -- no flame
war just a questions dear downvoters, don't freak out again)--Rails feels just
more vibrant regarding web dev. But Rails is not Ruby ;-) It's just that I see
all the Python stuff on HN -- which is slightly focussed on
online/web/Internet -- and I really considered learning Python for web dev
until I checked
[http://www.google.de/trends?q=python+django%2C+ruby+rails...](http://www.google.de/trends?q=python+django%2C+ruby+rails&ctab=0&geo=all&date=all&sort=0)

EDIT2: but there's a new rising star:
[http://www.google.de/trends?q=python+django%2C+ruby+rails%2C...](http://www.google.de/trends?q=python+django%2C+ruby+rails%2C+node.js&ctab=0&geo=all&date=all&sort=0)

~~~
callahad
As far as I can tell, Python has a _much_ broader base than Ruby, at least in
the english-speaking world, but is generally quieter about it. As a few
examples:

Thanks to SciPy, NumPy, Sage, and so on, Python is extremely popular in
scientific computing and academia in general, drawing hundreds each year to
Enthought's Scientific Python conference.

Apple's iCal Server is written in Python with the aid of the Twisted async
library, the same library used by LucasFilm for communications in its render
farm, or Justin.tv's caching engine.

Google has found great success with Python: YouTube, for instance, is written
in Python.

Thousands of undergraduates have their introduction to computer science each
year taught in Python, even at MIT.

And let's not forget the sizable Django, Pyramid, and Plone web development
communities, all of which seem to have surprisingly little overlap.

The thing is, Python's been around for a long time -- longer than Java -- and
it's been useful for a similarly long time, especially in the same domains
that Perl traditionally excelled at. Thus, its growth was bottom-up: Many
sysadmins were eventually expected to simply know Python just as they were
expected to know Shell and Perl, and thus being functionally proficient in
Python wasn't really a defining characteristic.

In this way, Python's expansion has been more of a slow burn as it creeps into
more and more corners of software development. Rails, by contrast, came
coupled with a wonderful promoter in DHH, and brought scores of front-end
talent and PHP refugees into the fold from day one. That audience seems to
simply be more innately talented at vocalizing the cool things they're doing,
and making sure they mention that they did it all "...with Ruby!"

So while I'd wager that the Python community is larger than the Ruby
community, it certainly seems less concentrated, and less vocal about it.

To wit, did you know that Dropbox is primarily written in Python? And that the
same goes for Eve Online?

~~~
JanezStupar
And this were all the factors that got me into Python when I was pondering
whether to go down the Rails or Python road, when I wanted to crossover.

And I was carrying quite a torch for Ruby before. But when you realize how
much broader Python is - Ruby doesn't look that good any more, no matter the
hype.

~~~
petercooper
_But when you realize how much broader Python is - Ruby doesn't look that good
any more, no matter the hype._

It's not all about "hype," of course. There are many distinctions and
comparisons that can be made over which language is best for the job beyond
the number of people using it or how much hype it has.

Ruby looks _great_ at things Ruby is much better at. Python looks great at
things that it's better at. For the rest, it's a wash.

~~~
JanezStupar
Oh no, I don't believe that Ruby is all hype.

I actually find Ruby more elegant.

But it's kinda like Porsche 911 Turbo vs Aston Martin DB9. Where AM is
arguably a prettier sight, but Porsche can do all the driving of DB9 while
offering a far superior dealer network.

------
michaelschade
Neat project. One critique: I don't like having only five lines of the snippet
visible at any given time, it makes it harder to easily understand what's
going on in some of your longer snippets.

I suspect that the five line limitation was done so that the "Give me another
one!" button was always in relatively the same place and easily clickable (I
appreciate that), but perhaps there could be a small, duplicate text link up
above the snippet for this purpose too, thereby also letting you make the
snippets longer.

~~~
ronreiter
I like the idea. Yes, there's the need for both. I'm thinking about just
making the text size variable according to the number of lines in the snippet
- I think that makes more sense.

~~~
michaelschade
That's a thought, but even moderately sized snippets might get hard to read. I
think this concern is especially valid because the rest of the text on the
site is large and easily readable from a distance, so making the most
important text–the snippet–smaller would be out of place.

------
mapleoin
It would be nice if all these "facts" could be downloadable under a CC
license.

~~~
ronreiter
good idea. will do

~~~
ralph
"View All" only give me the titles, I still need to look at each individually.
It's a bit like a FAQ that doesn't put multiple Qs and As on the same page; a
pain. Part of the benefit would be scrolling through at speed, no comments
interspersed, learning quickly, skipping already-known at a glance. Could be N
per page to handle when total number is large as long as N >= 20. I'm looking
at View All thinking some look interesting but I haven't the time to click
round it all.

------
rhdoenges
> How can addition be more easier than this?
    
    
        print eval('+'.join(map(str, [1, 1])))
    

Seriously?

~~~
ronreiter
It's a joke :)

~~~
rhdoenges
phew :)

------
kisielk
A bit of a nitpick, but it would be nice if the facts were PEP8 compliant so
they encouraged good code style as well as showing off Python features.

~~~
cbo
Not just PEP8-compliant. Some of these are just plain bad.

The first one I was greeted with when I opened the site was:

> print eval('+'.join(map(str, [1, 1])))

If I ever saw this in production code, I would lose my mind.

It's the kind of one-liner I'd expect to find in an obfuscated code
competition. It's not intuitively understood, shows a lack of basic Python
functionality (the builtin sum() function), and most of all, it's SLOW. As in,
54 times slower than a simple sum -- tested on xrange(1,10) -- on my
development Macbook Pro.

That said, clicking through some other examples, there are a lot of great
Python examples on this site. Just beware of some of them, and always make
sure you test new code yourself.

~~~
gbog
Slowness is not the worst, eval is evil, and should be forbidden, that's all.

------
cschmidt
If whoever created this stops by, I got an error message on this snippet:

    
    
        import itertools
        name_generator = itertools.imap("name-{}".format,itertools.count())
        # to get the next name:
        new_name = next(name_generator)

~~~
ronreiter
thanks

~~~
rplnt
<http://facts.learnpython.org/2003> gives me error as well

------
antirez
"While passing a single value to string formatting works, it's dangerous and
can fail in subtle ways". AKA Python design errors.

~~~
irahul
> it's dangerous and can fail in subtle way

The only subtle way it fails, which I can think of is:

    
    
        In [27]: foo = (1,2)
    
        In [28]: '%s' % foo
        ---------------------------------------------------------------------------
        TypeError                                 Traceback (most recent call last)
        ----> 1 '%s' % foo
    
        TypeError: not all arguments converted during string formatting

~~~
jrockway
And, that's easy to fix:

    
    
       '%s' % (foo,)
    

Ugly, but you can be safe if you don't mind three more bytes of source code.

~~~
irahul
Or '{}'.format(foo). Personally, I have never faced this issue as:

1\. I know/control the input while string formatting.

2 String-formatting tuple comes up rarely.

~~~
jrockway
I format tuples for debugging on a regular basis, but tend to just wrap every
arg to the format string in repr, so this never comes up.

~~~
TheNewAndy
This won't solve the immediate problem, but if you use "%r" instead of "%s",
python will do the repr() for you.

------
gren
Not convinced by this one: <http://facts.learnpython.org/1004>

~~~
RyanMcGreal
I prefer:

    
    
        [int(x) for x in "10 20 30".split(' ')]

~~~
omaranto
Why? It's longer and requires an extra check to make sure that it's the same
variable mentioned twice (i.e., you read to read it carefully to distinguish
from [int(x) for y in "10 20 30".split(' ')]). Is it just that since
comprehensions are more commonly used you think some people might forget what
map does nad have to look it up?

------
gcr
Nice project, but you NEED some sandboxing.

    
    
      import os
      print os.listdir('.')
      print open('turtle.py').read()
    

_Edit_ : It seems like you're doing some; i can't inspect any directories
outside the "jail", but being able to list the source code of your scripts is
a security risk.

~~~
shenberg
Python had an implementation of sandboxing (rexec), but gave up plugging the
holes people kept finding in it (see
<http://docs.python.org/library/rexec.html>).

The problem is that sandboxing wasn't designed into the language so they don't
give users a false sense of security with a bad sandbox.

To see the legacy of the sandbox, open an interpreter and run 'del
__builtins__' to activate the restricted execution mode. Now, a lot of simple
things like the import statement should fail. A good exercise in python
internals is to manage to execute unrestricted code from this state via clever
use of introspection.

Note: 'del __builtins__' is more than just removing access to builtin objects:

    
    
      >>> f = file
      >>> del __builtins__
      >>> f('a.txt','w')
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      IOError: file() constructor not accessible in restricted mode

------
kisielk
Sorry, I think I broke your site. I realized based on one of the comments here
that you seem to be running a persistent interpreter and then just running the
code snippets. So I decided to see what would happen if I changed one of
them...

So I found the snipped that did something like

import collections foo = collections.defaultdict

and added

collections.defaultdict = None

to the end of it.

Next time I ran it the original snippet just gave a stack trace. Oops :)
Anyway, looks like you need to work on sandboxing the snippets some more.

I would have sent this to you via email or other means, but I couldn't find
any other way to contact you in your HN profile or on your site.

------
Rexxar
Bug at the third try: <http://facts.learnpython.org/7006>

    
    
        Output:
        Traceback (most recent call last):
          File "/base/data/home/apps/s~learnpythonjail/1.350338289496947596/main.py", line 99, in post
            exec(cmd, safe_globals)
          File "<string>", line 2, in <module>
        TypeError: 'start' is an invalid keyword argument for this function

~~~
shenberg
The start argument was only added in Python 2.6...

------
c4urself
cool initative! seems like snippet numbers are random: 1 works but 2, 3, 4
don't. it would be nice to have categories or tags and a place to let others
contribute snippets. i like the fact that the snippets are small and
communicate one thing, otherwise it's comparable to the ActiveState website.
It would be nice to make it downloadable in a pdf.

EDIT: Never mind I see there is an "Add" button.

------
hardik988
A small bug: Go on any random fact, eg: <http://facts.learnpython.org/3007>
Click on "Add your own", and then click go Back in your browser. The snippet
is blank. This is Chrome 15 on Windows 7.

------
bnegreve
When I click play it says "Error!"

running debian linux with ff 3.5

~~~
test5625
"Error!" in Opera 11.52 and Internet Explorer 6.0 on Windows XP.

------
brown9-2
Love this idea, I think one small way to look some snippets look nicer would
be to remove the absolute width/height on the snippet text box (to prevent the
need for scrollbars).

------
veyron
Is this approach (sending the commands to a backend) preferable to a
javascript-based repl (using something like emscripten)?

~~~
ronreiter
yes, but it's jailed pretty good and it's not a lot of CPU power to execute,
so it's OK.

~~~
nanotone
It looks like you're using GAE. Not having much experience with it, I'm
wondering if GAE provides the CPU jailing, or did you have to write some
voodoo yourself?

I ask because it's trivially easy to send a statement containing a single
bytecode that takes a really long time to execute, at least in CPython:

>>> print 9 __9 __9 * 0 # = > 0, so not a bandwidth issue

If I send this to your backend in a bunch of tabs (I didn't) could that be a
DoS?

Also, are you thinking of putting the backend code on github?

EDIT: HN swallowed my exponentiation. That should read "print nine to the nine
to the nine, times zero". Without the times zero, that's a huge number.

~~~
d0mine

      >>> print 9**9**9*0 # => 0
    

Text after a blank line that is indented by two or more spaces is reproduced
verbatim. <http://news.ycombinator.com/formatdoc> (the help link is in the
bottom-right corner)

------
domlebo70
Would anyone be interested in something like this for Scala?

------
msinghai
Works fine, except that scrolling doesn't work on an iPad.

------
codecaine
added this to my start tabs

