
Why People Should Learn Python - LaSombra
https://iluxonchik.github.io/why-you-should-learn-python/
======
greenspot
Is it just my feeling or are there languages which are preferred on HN?

Indicators for languages which are liked by the HN community:

\- Positive stories get many upvotes and are instantly at the top of HN

\- Most comments are positive

\- Frequent coverage on HN about the language

Indicators for languages which are not liked by the HN community:

\- Rants get many upvotes and are instantly at the top of HN

\- Most comments are negative about the language

\- Rare coverage on HN

Applying those indicators, following languages should have these like-levels
(on a range from 1 to 5):

    
    
      Python  *****
      Go      ****
      Node.js *
      C#/.NET ***
      Java    ***
      RoR     **
      Ruby    ***
      Elixir  ***
      Haskell ****
      Closure ***
      C       ****
      Rust    *****
      C++     ***
      PHP     *
      Swift   ****
      

This is just my feeling, happy to hear your perception. And this does not
reflect my opinion about those languages in any way.

~~~
dismantlethesun
At a glance, it looks like all languages are reasonably well loved except PHP
and Node.js (shouldn't this just be Javascript? Does having a different
standard lib make it a different language?)

I think that's due to people having flash backs to terribly written code in
both languages.

For example, PHP apps pre-2005 rarely if ever used frontend controllers,
preferring instead to twine in configuration and helper functions into
isolated pages that were directly served by Apache. This meant that there was
no single obvious place to put things like caching.

Additionally, once upon a time, PHP didn't really have well developed ORMS, so
everyone just wrote queries and hopefully parameterised queries---but not
always. So if you had a hobby project that took off, then within 3 years it'd
be a roiling ball of mud where it's difficult to do basic things like tracing
which calls happen per page.

PHP came to prominence early in the web, and it was easy to use so _everyone_
had a hobby project that took off, or had to work within something like that.
Hence the hate.

To compare it to Javascript, I think the disdain for both languages is due to
their initial nature---they were both written over an short period of time,
and evolved in spurts rather than being carefully designed from day one or
designed to overcome the shortcomings of another language.

The quality of the above really shows up in the inconsistency of the standard
libraries, and the fact that certain semantics were inconsistent or danger
zones in practice but couldn't be changed.

\---

I do remember though when everyone hated C, and loved C++, then went back to
loving C... so maybe programmers are just fickle and none of what I said makes
sense. :)

~~~
kayoone
just to chime in on this, modern PHP is nothing like what people remember from
the pre ROR days, i still use it to this day and the major frameworks and libs
are really well written to the point i feel some are even over engineered and
almost looking like Java (just take a look at the latest Guzzle PHP Library)

~~~
collyw
As my PHP fluent colleague said to me - don't bother learning PHP or you will
end up having to fix (our) Wordpress sites and thats a nightmare. We have a
Python application, and while its not written well, the PHP sites we have seem
to be a fair bit worse even the ones not done in Wordpress.

~~~
dreistdreist
Wordpress is horrible. Never going to touch that again (Senior PHP Dev myself)
or anything else like it (Magento, Drupal,...).

And yes there is a lot of horrible PHP code out there, writting by bad
developers. I guess newer or not as accessible languages don't have as many
bad devs as PHP/JS.

But if you have good devs, I prefer a good PHP codebase to any other language
that I have come across (I tried a lot of them).

~~~
TheLarch
Around 2001 I felt jaded with the industry and determined to do whatever was
expedient to earn money. That meant using PHP, because that was purportedly
the place to be at the time.

I have never felt so uninspired by a language. My overwhelming feeling from
the get-go was that it was a collection of libraries, which would be fine --
but why create a new language?

PHP has the rare distinction among languages of not containing any novel
features or ideas. Not only that, but it borrows liberally from several other
languages, resulting in an overabundance of syntax. Instead of a tool for
attacking problems, it's a reheated leftover. There is not suggestion of a
better or worse way to accomplish some goal.

Finally, the original premise of PHP, interspersed functional code and HTML,
is high on my list of really bad ideas. Code written in this style is doubly-
challenged in terms of reuse and maintainability. Again, there is again no
semblance of better or worse with this approach. If you had Richard Stallman
and Linus Torvalds produce the same website with PHP, there would be very
little in common between their approaches.

Given the success of Facebook et al, I presume that the interspersed code/html
thing has been superseded, and further that the egregious security issues in
PHP have been fixed. But the picture in my mind's eye is something that
lumbers along despite its thorough mediocrity. I will allow that making PHP
adequately consistent and secure are impressive feats.

Sincere question: how am I wrong here?

====== edit ====== Drop extra 'the'

~~~
jdhawk
Since when did something need to have novel features or ideas in order to be
productive?

I'll counter that one of the main reasons PHP became such a used language
(other than ease of deploy) is exactly the reasons you dislike it. There are
multiple ways to do things - that coincide with the ways you do things in many
other languages (which it steals from).

You dont have to learn anything radically new to use it, and that makes it
very easy to do things quickly.

~~~
TheLarch
"Since when did something need to have novel features or ideas in order to be
productive?"

It doesn't. But if your language ideas are _admittedly_ no better than the
next guy's, what's the point?

~~~
jdhawk
It's easy, fast (both Development speed and Page Views), and can deploy
anywhere with a few clicks? It has no novel concepts that require learning
something new. It has a plethora of existing code, documentation, frameworks,
and StackOverflow answers to solve almost any problem (albeit, not always
correctly).

Its the lowest barrier to entry web language - and honestly, I'm ok with
people writing shit PHP. It gets good Ideas out there quickly - allowing the
business to grow without a focus on the Development. This creates
opportunities for sharp developers to come in and work on proven ideas.

------
K0nserv
I switched to writing python as my main backend/scripting language with my new
job. Previously I was using Ruby for most of this stuff with some Go. I must
say that so far Python has been a vastly inferior experience for me. The
languages are fairly similar all though I prefer the more talkative/english
style of ruby and the use of functions over list and dict comprehension.

The thing that really stands out to me though is the poor state of python
tooling and the library ecosystem. Having used Rubygems and bundler pip feels
like taking an enormous step back. It's much less expressive. It doesn't
handle the difference between production only dependencies, regular
dependencies and development only dependencies in a good way. It's difficult
to differentiate between locked dependencies vs desired dependencies(the
Gemfile/Gemfile.lock distinction). PyPi and especially using private PyPi
registers is more complex than it is in Ruby. There seems to be fewer nice
libraries and they seem to be spread across the web whereas Ruby centralises
around GitHub. I also find that Python libraries have lacking or hard to find
documentation in many cases.

I wonder how much of this is due to the community spending a lot of time on
the unproductive Python2/Python3 debacle instead of moving the language and
the ecosystem forward. It seems like Ruby and Python would be in more similar
positions had it not been for the problems around the Python 2/Python 3
upgrade. Ruby had the risk of a similar problems in the 1.8 to 1.9 upgrade,
but it seems to have worked out better than the Python 2/Python 3 upgrade.

~~~
euroclydon
I wish Ruby had the math and scientific library support of Python.

Also, I've been using Jupyter lately to brush up on data structures and
algorithms. It's been pretty sweet to write code in a web notebook and render
output including digraphs beneath each block of code. Is there anything like
that for Ruby?

~~~
_Wintermute
You can use other kernels in jupyter notebooks. I've never tried ruby, but you
could try this:
[https://github.com/SciRuby/iruby](https://github.com/SciRuby/iruby)

------
iagooar
Now that I have a chance to ask: I've always found the def __init__ method
with 4 (!) underscores one of the ugliest things I've seen in a programming
language.

Don't get me wrong: I like Python and know it's truly good, but __why__??

~~~
zubspace
Call me ignorant, but I agree. Having something like __init__ and __new__ is
very confusing for a beginner, along with stuff like "__init__.py".

It doesn't stop there: Take something like __str__ and __repr__ combined with
str(), repr(), vars(), dir(), print(), pprint.pprint()... I have no idea how
anyone ever thought it was a good idea to have that many ways to output the
content of a variable. Even after all the time I used python I never managed
to find a consistent way to output variable values.

I generally like python as a scripting language. But stuff like this made me
constantly lookup obscure details in the documentation which made it very hard
for me to completely embrace the language. It also prevented me from diving
into more arcane stuff like meta-programming...

~~~
amyjess
The dunder functions are there to provide an interface to global functions and
operators.

If you want to affect how str(x) behaves, you override x's __str__() method.
Operators behave this way too: for example, if you want to overload the ==
operator for a class, you override __eq__() in that class (for any Java
developers reading: Python == works like Java equals(); the Python version of
Java == is the _is_ operator, which cannot be overloaded). Yes, that means _x
== y_ is just syntactic sugar for _x.__eq__(y)_.

The dunders are there so you have the freedom to name your methods what you
want without having to worry that you'll accidentally clobber a method that
affects a global or an operator, as most people won't just up and decide to
both begin and end a method's name with __.

------
eddd
I use python on daily basis for 5 years now. It's a really cool language, but:

* Packaging is horrible

* Releasing python code is a non-standarised nightmare. Every solution has it's own flaws

* Big and complex projects in python are really hard to reason about

* Poor support for concurrency (fixed in py3)

Don't get me wrong, python is really cool as a proof-of-concept scripting
language. But for mature and complex stuff, I'd recommend something with type
checking and better support for release process.

~~~
typon
I've programmed in a few other languages than Python. I'm curious to know
which languages you think have an easier time managing mature and complex
stuff?

~~~
bcbrown
Statically typed languages. Personally, java or C#.

~~~
typon
I've worked with large C++ projects and large C# projects (both at large
software corporations) and the code was not particularly less unwieldy than an
equivalent Python projects I've worked on.

I think static typing alone doesn't make managing complexity easier.

I'd like to know what other features people think Python is lacking that make
it much worse than C# or Java when handling large projects.

------
hacker_9
Why you shouldn't learn Python:

1\. In-consistant syntax.

2\. The language uses exceptions to control flow of logic.

3\. Divided community, since Python 3+ included breaking changes to the
standard.

4\. Un-discoverable APIs. You better hope the documentation is bulletproof
else the API could change in any which way during runtime.

5\. Poor error messages. If an import goes wrong you are not told why, and so
on.

6\. Ultimately slow performance for anything marginally complex.

7\. Poor tooling.

~~~
wiz21c
1\. a matter of tast

2\. care to elaborate ?

3\. it's not divided, it's evolving from 2 to 3. Java's community is under
Oracle's grip, don't know if it's any better...

4\. it's not because you can do it that it's worth to do it, so in practice
API are just not changing at runtime

5\. I can say the same of my industrial strength Java environment...

6\. Not a problem since what you do doesn't require speed

7\. Ever used PyCharm ? I wouldn't say it's poor tooling. The debugger is
fine. What I miss is something like a good profiler to look at running code.

But I'd say :

8\. Optional typing should've been there from day one, it'd made code editor,
tooling better

9\. The date/time handling is not good

10\. SOA support is weak (and in the kind of setting I am, we use tons of XSD,
WSDL, XML, security, signature you name it)

~~~
nhumrich
PyCharm comes with cProfile and let's you "run with Profiler". But maybe
that's only the paid version.

~~~
dagw
Yup. The integrated profiler is only in the paid version

------
atemerev
The person who wrote this obviously has "the hacker's mindset". He praises
expressivity and malleability of the language.

Well, in this case it might be advisable to take a look at Perl. And never go
back. Perl (especially Perl6) is hacker's paradise, where everything's true
and nothing is forbidden.

As somebody who shares the same mindset, I truly enjoyed my years with Perl,
and I occasionally return to this experience.

~~~
viach
> is hacker's paradise

And support engineer's hell

~~~
tgfeathers
So is Python. I've worked on code bases in several languages, and the greatest
horrors I've seen are in Python and C++, in that order.

Python is a strange case. The CPython code base seems to be quite well
organized and well written, and about 10% of packages on GitHub or PyPI are
extremely solid.

The problem is the staggering amount of packages (public or in-house) that
have 100000+ LOC and use the worst features of OO, functional, and procedural
programming at the same time.

The result is not spaghetti code, but ravioli code where there's zero control
flow and "everything happens somewhere else". Add to that the "consenting
adult" philosophy, and you have the modern equivalent of goto mixed with self-
modifying code.

I'm sure Perl has all that, but it's far from the only language.

------
joshvm
Always fun writing compact Python:

    
    
        import sys
        from collections import Counter
        
        cnt = Counter([n.strip() for n in sys.stdin.readlines()])
        
        for key, val in cnt.most_common():
            print(val, key)
    

This isn't just playing code golf, it goes with point (2) - awesome libraries.
One of the joys and curses with Python is finding the Pythonic ways to do
things that you've hamfistedly written your own way for months.

~~~
masklinn
FWIW the Counter line can be simplified slightly:

    
    
        cnt = Counter(n.strip() for n in sys.stdin)
    

* no need for a list comprehension, a generator expression will do

* file objects are iterable, and iterated line-wise

------
clumsysmurf
A new & free introduction to Python from Jake VanderPlas can be gotten here:

[http://www.oreilly.com/programming/free/a-whirlwind-tour-
of-...](http://www.oreilly.com/programming/free/a-whirlwind-tour-of-
python.csp)

I was looking for a dense & concise guide to the language, but one of the most
popular books "Learning Python 5e" by Lutz was too long @ 1600 pages.

~~~
thewhitetulip
His book is awesome! I wish I had it when I started Python. I had gone through
the documentation tutorial thrice, the entire documentation once or twice.
Started writing code and then understood python.

I found that learning Python is simple, mastering it is difficult, the magic
which happens all the times makes it difficult to understand, which is the
reason why static languages are awesome as less magic as possible.

------
technomancy
> Another thing is strict typing and debugging: since Python is an interpreted
> language, finding bugs wasn’t as easy

Wait, what? How is its interpreter remotely relevant to its semantics?

> if you have a syntax error in C, the program will simply not compile, on the
> other hand, in interpreted languages, the problem might go unnoticed for
> quite some time

Hang on--Python allows you to run code that has syntax errors? I'm so
confused.

~~~
forkerenok
To my knowledge syntax within a file is completely checked when that file is
loaded. I think the OP referred more to errors in method and other reference
names.

~~~
michaelt
If you write this:

    
    
      #!/usr/bin/python
      import time
      time.sleep(5)
      fdafadsfadsf
    

It'll take 5 seconds to crash with a "NameError: name 'fdafadsfadsf' is not
defined". Likewise, if you do this:

    
    
      #!/usr/bin/python
      import time
      x = 1
      time.sleep(5)
      print "x is "+x
    

It'll take 5 seconds to crash with "TypeError: cannot concatenate 'str' and
'int' objects"

In a language like Java, these would be syntax errors, and they'd be picked up
at compile time as they're illegal in Java's syntax.

I assume they're legal in Python's syntax, because for all the syntax checker
knows, time.sleep() might define fdafadsfadsf and convert x into a string. So
they're runtime errors in Python.

Of course, Java still has runtime exceptions - null pointer exceptions, for
example.

~~~
jasonpeacock
Java and Python are apples and oranges - one is a compiled language, the other
is interpreted. Better to look at other interpreted languages like Ruby &
Perl...and they have the same issue. It's a side-effect of using an
interpreted language, but it also allows such languages to be self-modifying
which can be very powerful when you need it.

~~~
technomancy
Python and Java are both compiled to bytecode and both interpreted as
bytecode. It has absolutely nothing to do with compilers.

------
kozikow
Addressing some criticism from various comments:

> Python 2 vs 3

It is mostly over. All important libraries are accessible on 3. It is clear
that if you are starting from scratch you should go with 3. There are good
tools to help with the migration (e.g. six). Some libraries start dropping
python 2 support.

> Bad tooling

Having used Emacs with jedi for a while I switched to PyCharm to leverage
optional typing. PyCharm beats my tooling experience in all languages I used
expect Java:

\- Auto imports work well.

\- Code completion works very well, especially on optionally typed code.

\- Even refactoring works very well, failing short only to my experience with
Java, but beating C++ or even Scala.

\- Debugging is actually a highlight - I can drop into full fledged REPL at
break point. "Evaluate expression" in C++ or Java didn't come close.

Profiling is indeed not as advanced as what I was used to on the JVM, but IMO
it is sufficient for 95% of use cases. For that 5% it is clear from the start
that you shouldn't go with python. Language specific performance monitoring in
production becomes less of an issue when you start running inside containers
and it starts to make more sense to monitor containers rather than individual
processes.

> Maintainability at scale

I am using Python 3.5 optional typing and I feel my project is much more
maintainable as a result. Among others, refactoring in PyCharm works very
well.

> Packaging and deployment

As mentioned in another comment, personally I moved away from relying on
language specific tools to do more than just "install version X of library Y"
and manage my deployment and dependencies using docker. It have it's own
problems, but so far it works very well, and it's quickly improving.

> Performance

In domain of scientific computing by using correct libraries and things like
Cython or Numba you can come close to C++ performance levels. In other domains
it's becoming more common to be disk/network bound, and then it doesn't matter
if you use Assembler or Python. Also JITs are coming to Python:
[https://lwn.net/Articles/691070/](https://lwn.net/Articles/691070/).

> Syntax/libraries/language features/etc.

It is the most subjective section, but my experience with python in this
regard is highly superior to Scala/Java/C++/JS.

------
kuma4
In PowerShell,

    
    
       PS> Import-Csv .\names.txt -Header name | group name | select name, count
       
       Name  Count
       ----  -----
       cat       3
       dog       2
       mouse     1
       bird      1

~~~
latkin
Seriously, the author seems to have fairly limited knowledge of powershell.

A 13-line python script is presented, followed by a smug "you can almost hear
the UNIX folks complain about how verbose the PowerShell version is".

First off, the provided Unix commands _don't work_ (should have used `sort -rn
-k 2`), while the provided powershell, as verbose as it is, does work.

Second, _the entire python script along with the wrapping unix commands_ is
encapsulated with a powershell 1-liner:

    
    
        cat ./names.txt | group | sort -d Count

------
interdrift
As the author mentioned Python is good for small stuff. If you are building a
huge system where the jobs are spread between a dozen of people things could
easily get out of control and you could end up in the dirt.

~~~
thearn4
Do you feel this way due to the dynamically typed nature of the language (and
the possibility of having ambiguous interfaces)? I've had pretty good luck
with rather large scale python projects, though we've been pretty strict about
working within a framework.

~~~
interdrift
Yeah mainly due to that. If you don't have a VERY strict approach to writing
code, one wrong decision could turn into a few days of debugging..

~~~
jasonpeacock
Where 'strict' == 'unit tested', then I agree with you. You don't need strong
typing to make good code.

~~~
thearn4
I would agree that complete and meaningful unit and integration tests are
definitely a necessity for a large Python projects. Or really for any software
project meant to be maintained.

------
cdnsteve
Python is in space [1].

There is such a large breadth of fields that it has been successful in. Web
apps, data analysis, machine learning, micro controllers, etc.

It has a long track record for being stable, reliable and secure. The
popularity over the years has been steady and with the recent addition of data
science field and machine learning, it's seeing another growth spike.

In my opinion, it's a highly versatile and very productive language that seems
to be able to handle just about any job or industry you can throw at it. I
personally switched to it full time and love it.

[1]
[https://www.youtube.com/watch?v=Zm08hXeuv-I](https://www.youtube.com/watch?v=Zm08hXeuv-I)

------
paistropical
If you want to learn more in-depth Python:
[https://pythonspot.com](https://pythonspot.com)

~~~
josteink
I just went with the "Fluent Python" O'Reilly book.

[http://shop.oreilly.com/product/0636920032519.do](http://shop.oreilly.com/product/0636920032519.do)

It's a bit pricey, but I managed to score it on a 50% sale, and I have to say
I think it's a very good book for people already fluent in other programming
languages.

------
agentgt
If only the JVM didn't have slow startup speed I would almost exclusively
write Groovy scripts.

There is just something so awesome about shoving your dependencies right in
the script and not worrying about pip, easyinstall, system libraries etc [1].

Maybe Java 10 will fix the startup speed (or whenever jigsaw is done
correctly) but I doubt it.

[1]: [http://docs.groovy-
lang.org/latest/html/documentation/grape....](http://docs.groovy-
lang.org/latest/html/documentation/grape.html)

~~~
vorg
> There is just something so awesome about shoving your dependencies right in
> the script

Groovy needs two lines (@Grab and import) to get a dependency. Golang only
requires the import. Perhaps Groovy needs to be rewritten in Go.

~~~
agentgt
_> Groovy needs two lines (@Grab and import) to get a dependency. Golang only
requires the import. Perhaps Groovy needs to be rewritten in Go._

I'm not dissing Golang but it isn't even remotely the same. A major portion of
the OP content was about using Python instead of shell scripts.

Golang is not scripting language. You need to compile for each platform and
the code is opaque once it is compiled. Not to mention Golang might not have
dependency issues at runtime but the overarching consensus is that certainly
has issues with compile time dependencies management (auto checking stuff out
from github is not effective).

 _> Perhaps Groovy needs to be rewritten in Go._

I normally don't say this... but that is just dumb fanboy comment.

 _EDIT:_ apparently you are working on a scripting language powered by Go
called Gro. I'm not sure if you just mistyped and meant Gro instead of Go....
and reading your blog it seems you must have been severely burned by the
Groovy community.

~~~
vorg
> I'm not sure if you just mistyped

I didn't mistype. Go would make a good language for writing dynamic languages
such as Apache Groovy in. My own Gro is just one example of such a dynamic
language.

~~~
dragonwriter
> Go would make a good language for writing dynamic languages such as Apache
> Groovy in

Wasn't the whole point of Groovy to have something Ruby-like that was more
intimately tied into the JVM ecosystem? Seems to me that Go would be just
about the _worst imaginable_ [0] implementation language for that.

[0] Or at least, in the class of extremely poor choices that includes all
languages that are not themselves especially targeted to the JVM platform.

~~~
agentgt
I think his point was instead of using the JVM runtime to now use the Go lang
runtime. Of course you would need the interpreter for each platform like
Python does but Go has a unique runtime. I'm not sure how dynamic it is but
you can certainly run a scripting language in it and make it easy to access
other Go stuff.

I'm not sure how easy it would be to access ad-hoc libraries without recompile
though since Go doesn't really have dynamic loading of libraries (or maybe it
does now?).

Little tangental ... After reading his blog I'm a little concerned though that
the dude (Gavin) has spent an enormous effort defending his stance on how
poorly the Groovy organization is... I'm not saying his wrong but is almost
obsessive and a waste of energy.

~~~
dragonwriter
> I think his point was instead of using the JVM runtime to now use the Go
> lang runtime.

Right, my point was that a central part of the _point_ of Groovy was being for
the JVM, it wasn't a language in search of a runtime.

So, while there might be an argument that a language _like_ Groovy for Go
runtime might be useful (I'm somewhat unconvinced of that), it just seems not
to be the case that Go is a good choice for a language _such as_ Groovy (that
is, it is not the case that Groovy is an example of a language for which it
would make sense to use Go as the implementation language.)

------
wibr
I first learned Python and then much later C, and for me at least learning
Python first was very motivating because you can get things done so easily,
due to the built-in batteries and the wealth of external libraries. Seeing
that the computer needs less than a second for what would have taken me many
hours of tedious work was pretty eye opening.

Learning C later on helped me understand some basic concepts better and being
able to speed up Python e.g. using Cython can come in quite handy.

------
jokoon
Python is so easy to write, use and read, I would not understand how a
programmer would not know it already.

It literally has everything you want in a language.

Granted, it's not on-the-metal fast, and it still has some gimmicks, like
variables behaving like pointers or references (which can be a little
awkward), but still, python is the language of the decade.

~~~
retro64
Ugh. I tell you, I keep trying to pick it up because I hear so much about it.
However, when I code in it I feel completely uninspired. I can only get so far
into a book or tutorial before my eyes glaze over and I'm thinking about
something else.

I think when I code, I want to _own_ the machine, not just skate on the
surface. Python doesn't even crank my engine the way BASIC did years ago.

I also think part of my problem is it doesn't solve any needs right now.

~~~
jokoon
Well python is not for solving hard problems. If you want to own the machine
you need C++ or C.

Python is a language that makes programming easy. That's a lot.

------
agounaris
One my feeling about python is that is a great language for "reference".
Probably everybody and write and read it and its already good enough for
general programming. There are edges where other languages are better but
still is a great language to establish communication among different types of
developers

~~~
sjellis
Yes, I've seen Python described as "everybody's second-favourite language".
It's not the best at anything, but if your main requirement is a bunch of
different people all need to be able to read and edit the same code then it's
a good choice.

~~~
enrmarc
Couldn't we say the same thing about Ruby?

~~~
dagw
Not really. Ruby isn't anywhere near as widespread or well supported in fields
like finance, math, various scientific fields and GIS. Python on the other
hand has at least has pretty good support in just about any domain you happen
to stumble into.

------
nrjames
The long history of Python support in the scientific community has produced a
rich catalog of domain-specific analysis libraries. Warts and all, it's simply
not possible, in most languages, to achieve the analytical productivity you
get when working in Python.

------
hiram112
I've had to deal with Python for a long time. I even wrote my senior research
project with it in college.

But since then, I've never really had a need to use it, and I don't even feel
there is a good reason for it.

If you're writing something more than a quick shell script or a project that
will last more than a few days, then there a dozen static languages that have
better libraries, more powerful IDEs, etc. And misspelling a variable or
missing a comma is not going to cause all sorts of problems.

On the other hand, if you do need a quick one-off script or some duct tape,
things like Perl or AWK, sed, and friends seem like a better bet.

Python (and Ruby) seem bloated for quick scripts, and wholly lacking for
larger projects.

------
agentgt
I have contemplated writing a "Why You Should Learn Bash" article and then
maybe "Why You Should Learn Regex" followed by "When to not use Regex".

If you know bash you probably have a pretty good idea how to manage Linux and
roughly how things work on Linux (you could apply this to other Bash capable
OS as well).

If you know Bash fairly well you probably also know how to automate many
things and you probably already know regex which is fairly useful in GSD. If
you know Bash you obviously know the command line well.

You should learn Bash (or some shell but Bash is so ubiquitous).

------
enriquto
The "namecount" example is rather silly though. It can be solved by a shell
script much shorter than one line (sort|uniq -c).

~~~
iluxonchik
Hey there! I've answered a similar observation in the comment section of the
blog :)

> Of course it can be done all with command-line tools, but the point was not
> to show you how you can count and sort word occurrences. I just wanted to
> show that it's possible to include Python scripts in your "command line
> workflow". I wanted to give a simple example that would give you a taste of
> the idea :)

------
_c_
Why do programmers try to convince others which programming language to use?
Why should they care what languages others are using?

~~~
jorge-fundido
The more popular your preferred tooling, the more opportunities in the job
market.

------
denfromufa
I read lots of people complaining about medium-to-large scale Python projects,
due to lack of static typing. Aren't people using reflection and dynamic in
C#? As soon as the code touches such run-time features, the testing at run-
time is essential.

I wonder how large projects such as OpenStack, Django, Edx, PyPy deal without
static types?

------
lllorddino
I hate Python. My linux distro comes with version 2.7 yet I should be using
version 3?? Yes it makes writing complex programs quickly with its endless
libraries, but I don't consider myself learning anything if all I'm doing is
copy pasting the API docs. I've recently switched to Go and the language is
small and easy, docs/source code are well commented, and lastly I'm actually
learning how computer programs work.

~~~
jasonpeacock
Most ppl are trying to solve problems/get work done, not learn how to re-
implement functionality already available in libraries. Copy & pasting the API
docs lets you focus on solving much harder & more interesting problems.

If you want to learn how computer programs work, you don't have to use
existing libraries - you can still implement the functionality yourself.

By your argument (I hate python...it has libraries) any modern & moderately
successful language with a large library ecosystem is bad, and you prefer Go
precisely because it lacks those libraries?

------
ekzy
I'm learning python just to be able to use tensorflow. I wish there was an
interface in Ruby

------
danso
I was a long time Rubyist but switched over to Python because even though its
characteristics and philosophy made me reflexively shirk it at first --
particularly significant whitespace, one-line-lambdas, and the clusterfuck of
2.x vs 3.x -- it seemed to me to be an obviously easier language to _teach_ ,
nevermind its significantly stronger libraries for numerical work.

I'm glad I made that decision. The language was easy enough to pick up in my
spare time. I hardly ever use pandas/numpy unless I'm doing some really
serious statistical work; the core language and patterns in Python are now
pleasant enough for me to use in day-to-day data wrangling and hacking. I'm
now mixing in Ruby for a current project -- mostly because I like Rakefiles,
and also, Ruby's static site generators like Middleman -- and it's been
surprisingly painful to do things in Ruby. I used to hate how when doing a
Google search for something in the Python stdlib would bring up 2.x before
3.x...but it almost seems even more problematic in Ruby, where 1.9.3 and 2.0.0
docs keep coming up, even though official maintenance of them has been
dropped.

(2.0's maintenance ended in Feb. 2016 [http://ruby-
doc.org/core-2.0.0/Array.html](http://ruby-doc.org/core-2.0.0/Array.html))

If I didn't know better, I wouldn't even know what Ruby's official version
was. For me, Google results show no other documentation for Ruby's Array, as
the next results are from tutorialspoint and sitepoint.

And that's not even getting into the issue of how problematic the do-things-
how-you-like freedom of Ruby is incredibly hard to discern as an outsider. To
give one example I recently had: how do you iterate through a human-calendar-
based time interval, such as a month (i.e. any interval that doesn't have a
constant length in seconds)?

In Python, I remember how frustrating it was to figure out what the hell the
difference was between datetime, time, calendar, the gmtime function, and then
timedelta, and then the third-party libraries of pytz and python-dateutil. But
once I understood them, which was largely a matter of realizing how naive I
was about the nature of measuring time, doing something like iterating over
calendar intervals is straightforward.

This is my first Google result for "python iterate month intervals" \-- it's
from 2008 and still works perfectly:
[http://stackoverflow.com/questions/153584/how-to-iterate-
ove...](http://stackoverflow.com/questions/153584/how-to-iterate-over-a-
timespan-after-days-hours-weeks-and-months-in-python)

Now here's the result for Ruby; all of the answers, as far as I can tell, are
not only not-very-Rubyish, but not reliable either:
[http://stackoverflow.com/questions/1724639/iterate-every-
mon...](http://stackoverflow.com/questions/1724639/iterate-every-month-with-
date-objects)

FWIW, I remember solving this problem by using the DateTimein ActiveSupport.
Which is a credit to how much fun and joy it is to build things in Rails right
out of the box. But that complexity catches up quick, and including
ActiveSupport in day-to-day Ruby work can sometimes to unwanted
monkeypatching.

~~~
ezrast
As a Ruby fan who is baffled by Python's continued popularity, I like this
comment - I'm always interested to hear why people have such different
experiences than me trying to move from the former to the latter.

That said, unless "recently" was years and years ago, Date#next_month is a
thing:

    
    
      require 'date'
      date = Date.today
      while (date < Date.today.next_year)
        puts date
        date = date.next_month
      end
    

One thing that I think throws a lot of people is that the official Ruby docs
are actually _better_ than Google for figuring stuff like this out - it only
takes a couple minutes to find #next_month by perusing the method listing at
[http://ruby-doc.org/stdlib-2.3.1/libdoc/date/rdoc/Date.html](http://ruby-
doc.org/stdlib-2.3.1/libdoc/date/rdoc/Date.html), but do a web search and you
get a bunch of Railsy crap.

Though I will grant you that even searches on ruby-doc.org keep bringing up
results for Ruby 2.0.x and whatnot. That part is pretty bizarre.

------
mxuribe
I thought this was a helpful article!

------
ferrari8608
I just wanted to point out a bit of syntax from the article. I'm a huge fan of
compact variable declaration if statements. The code from the article:

    
    
        if name in names:
            names[name] += 1
        else:
            names[name] = 1
    

That can actually be written as just one neat, readable line:

    
    
        names[name] = names[name] + 1 if name in names else 1
    

It may not be as readable to some who are used to spelling it out as an
if/else block, but I really prefer the one line way. It reads closer to
regular English I think.

~~~
jasonpeacock
NO. That is not more readable, and is warned against in most style guides and
code-quality books.

In the original, at a glance I know exactly what is going on.

In your version, I have to read the whole sentence carefully to notice that
it's even a conditional and not a normal assignment, and then I have to
mentally unpack it to understand the logic that you're trying to implement.
If/else should never be a one-liner.

Good code is boring code :)

~~~
avyfain
Yup, but the right way to do it would be a defaultdict, or a Counter anyway.

    
    
        from collections import defaultdict
    
        def count_names():
            names = defaultdict(int)
            for name in sys.stdin.readlines():
                name = name.strip()
                names[name] += 1
                ...

------
douche
My initial progression of languages was: QBasic, Visual Basic, C++, Java
(1.5), Python. Python was leaps and bounds more fun and productive than
flailing away with any of those.

But today, I'm less excited about it. I've gotten spoiled by C#, that has
static typing, and consequently, better tooling, as well as a good measure of
the flexibility of Python, through dynamics, lambdas, LINQ.

It seems Python is finally getting over the 2.X -> 3.X schism, but that kind
of threw a wrench into things for a number of years, as well.

------
myst
Is it 2006 again?

------
probably_wrong
For all its virtues, I feel introductions to Python tiptoe around a very
important topic: yes, Python is nice and easy, but _you 'll have to program
the Python way too_.

Try running a nested loop on a non-trivial example, and you can end up
spending minutes in what would take milliseconds in any other language. If you
want to program in Python, you must get used to the functional paradigm. Not
"should", "must".

Now, I'm all in for bringing more functional programming into daily life, but
I find a bit dishonest that beginners are not told about this. My first
serious program took about a week for a task, and shaving that time down
involved a lot of pain changing simple nested loops into multiplications of
Numpy matrices. There was a lot of caching too. I have no idea how someone
without a CS degree would have dealt with this.

~~~
jnbiche
> Try running a nested loop on a non-trivial example, and you can end up
> spending minutes in what would take milliseconds in any other language.

Huh? Can you provide an example? There's nothing about writing nested loops in
Python that is qualitatively different from other languages.

> If you want to program in Python, you must get used to the functional
> paradigm. Not "should", "must".

This is incorrect, much to my chagrin. Python's trend over the past few years
has been not only _not_ to encourage functional programming, but to explicitly
_discourage_ functional programming. For example, starting in Python 3,
`reduce` has been banished from the language proper to the standard library.

~~~
dagw
_Huh? Can you provide an example?_

Well he did mention numpy and obviously doing something that can be done in
numpy with nested loops will be much much slower. However that is as much a
case of numpy being really fast as python being slow.

For example, just tested elementwise multiplication of two 10kX10k matrices
and with numpy and numpy arrays it took ~350 ms vs ~15 seconds with a nested
for loops and python lists. Still minutes vs. milliseconds seems like extreme
hyperbole.

edit: Figured I'd test how long the naive nested loop approach would take in a
'fast' language like Julia, and much to my surprise it took over 50 seconds.

edit2: cleaned up all my code to try to make it as similar as possible across
both languages:

Nested for loops python 2.7: ~30 seconds

Nested for loops Julia 4.6; ~50 seconds

Nested for loops PyPy 5.3.1 ~0.9 seconds

Make of these numbers what you will

~~~
ced
Could you post the Julia code? Unfortunately, you do have to make sure that
the types are correctly inferred by the compiler in high-performance loops. Or
maybe you used a global.

[http://docs.julialang.org/en/release-0.4/manual/performance-...](http://docs.julialang.org/en/release-0.4/manual/performance-
tips/)

~~~
dagw
I'll admit I don't really know that much Julia and basically wrote naive
MATLAB code (and I wanted to make it as close as possible to my python code):

    
    
      s=10000;
      a=ones(s,s);
      b=ones(s,s);
      c=zeros(s,s);
    
      tic();
      for i in 1:s
        for j in 1:s
          c[i,j]=a[i,j]*b[i,j]
        end
      end
      toc();
    

Obviously in real code I'd simple write

    
    
      c=a.*b 
    

and get basically the same performance as numpy

~~~
ced
Tarrosion is right, on my machine, putting the code inside a function is 10X
faster, and then swapping the order of the loops gives another 10X
improvement:

    
    
        function f(s)
          a=ones(s,s);
          b=ones(s,s);
          c=zeros(s,s);
    
          tic();
          for j in 1:s
             for i in 1:s
              c[i,j]=a[i,j]*b[i,j]
             end
          end
          toc();
          return c
        end
    

Note that you also might have to run the function twice, because the first
time JIT-compilation kicks in.

Julia 0.5 also now automatically devectorizes some code (eg. x = a .* b .+ c)
so that you don't have to write explicit loops to get performance benefits.

~~~
dagw
Thanks. To both you and Tarrosion.

Guess I need to take some time at some point to sit down and actually learn
'proper' Julia.

