One of the main selling points of Python are its multi-paradigm philosophy. You can code in imperative, object-oriented or aspect-oriented style, use meta-programming techniques, etc. It also has an immense amount of libraries available. Finally, it's both a simple language to pick up for beginners, and a powerful language for more experienced programmers.
I've been programming for the last six or seven years, and I feel that my main strength is also my main weakness: I've been mainly coding in Python since the beginning. It means that I can now use Python's features and standard library pretty well, but it also means that I tend to think of every problem in terms of Python features and libraries (standard or not).
A proverb programmers are taught quite early is
If all you have is a hammer, everything looks like a nail. (Source)
It means that if you're only comfortable with a single tool, then you'll try to use it in every situation, even in one where it's not appropriate. I strongly feel that to become a better programmer, I now need to learn other programming languages and even other paradigms. I was initially thinking of functional languages, like Haskell or oCaml, but then I remembered something Fredrik told me a while ago, at a EuroPython after-party: reading "Structure and Interpretation of Computer Programs" immediately made him a better programmer. I remember being curious as to why.
It so happens that the books is written under a Creative Common license, and can be downloaded here, AND uses Scheme as a teaching language. It thus combines three things I strive for: a new language, a new programming paradigm and more insight into the art of programming itself.
I'm thus laying out my n-step plan to become a better programmer:
- Read the book thoroughly
- Solve the exercises
- Stop conceiving every solution in Python
Behold, one of my first Scheme programs, a pavement in the road of my improvement.
; Implementation of cubic root Newton approximation technique in Scheme (define (square x) (* x x)) (define (cubic-root x) (define (improve guess) (/ (+ (/ x (square guess)) (* guess 2)) 3)) (define (good-enough? new-guess old-guess) (< (abs (/ (- new-guess old-guess) old-guess)) 0.001)) (define (try new-guess old-guess) (if (good-enough? new-guess old-guess) new-guess (try (improve new-guess) new-guess))) (try 1.0 x) ) (cubic-root 9) ; => 2.0800838232385224
Note: If you want to experiment with various languages (Scheme included) without having to install them on your machine, have a look at repl.it.