A presentation I gave at the Vienna.rb Meetup in February:
A presentation I gave at the Vienna.rb Meetup in February:
You probably know the feeling. You’re writing a piece of code, and just by looking at it, you know it could be better – but you don’t know how. You have that feeling that the right solution is just around the corner, if only you could reach it… but you don’t, and you have to live with whatever you’ve got. You have to live with the knowledge you were not good enough to write better code.
This happens especially if you’ve just left the beginner stage behind, and are slowly advancing through the intermediate stage. Many plateaus await you, frustrating you in your quest for progress. Some days, it seems like you’ve hit your limits, the very best you can do, and that you cannot go any further.
But there are things you can do to help yourself. I’d like to tell you about a few.
Similar to training a muscle, your skills won’t grow when you keep repeating the same things over and over. So it is important that you expose yourself to new concepts and ideas. Often, you’ll feel out of your element, and like the biggest n00b on the planet. And that’s ok. If it’s not hard, if it doesn’t suck, you probably won’t learn much from it. Become comfortable with your Discomfort Zone.
Expose yourself to new ideas. Read about something you do not yet quite understand. Listen to podcasts about topics you do not know much about. Watch screencasts about things you’ve only dreamed of.
Ask other people about books, blogs, screencasts, or podcasts they recommend. But also always ask them why they recommend them. What is right for them may not be right for you.
I like Ruby Rogues, Avdi Grimm’s Ruby Tapas, Real Talk, Vimcasts, Build an App with Cory Haines and Gary Bernhardt’s Destroy All Software. Each one of these has exposed me to new ideas, or a new way of doing things that I hadn’t know of or considered before.
But even more important, do new stuff. Just collecting information in your head is not enough, you also have to implement it. Want to learn functional programming? Go learn Haskell. Want to work in a statically typed language? Learn Scala. Always wanted to know more about the actor model? Learn Erlang.
Here’s the thing: After that initial explosion of cognitive growth, they noticed a decline in both cortical thickness, as well as the amount of glucose used during that task. However, they remained just as good at Tetris; their skill did not decrease. The brain scans showed less brain activity during the game-playing, instead of more, as in the previous days. Why the drop? Their brains got more efficient. Once their brain figured out how to play Tetris, and got really good at it, it got lazy. It didn’t need to work as hard in order to play the game well, so the cognitive energy and the glucose went somewhere else instead.
And then write programs in those languages. They don’t have to be things that will actually be put in production, but you should write non-trivial programs that do something useful (ie., anything but printing
You are functionally blind when you only have book knowledge.
PeepCode’s Play by Play series shows how masters work on a given exercise, telling you about their thought process and explaining their decisions as they go along.
And, if you can, find a mentor, someone who can guide you, show you the way, and provide you with useful criticism that will let you grow.
Languages and frameworks come and go, but the classics are forever.
You might call some of these things “computer science”, but many of the best programmers I know have no formal training in such. These things can be learned by anybody, many of them are learned best in a hands-on environment.
Investing your time learning things like networking, concurrency, regexes, or system programming will not go out of style in your lifetime.
Languages and frameworks are only tools, a means to an end. Understand why those tools exist, and why they work the way they do, and you will gain a deeper understanding of how things work.
Sites like Exercism.io or Code Wars present you with programming challenges in various languages that allow you to “exercise” in a very defined way. Exercism.io is especially great because its emphasis is on getting and giving feedback, forcing you to think and argue about your design decisions. This can be very enlightening even with apparently very simple exercises.
Using Katas to Improve Yourself is another possibility to train your programming abilities, while at the same time picking up a new language or framework.
The Ruby Rogues episode on coding exercises, quizzes and katas also contains useful information on that topic.
Go outside and get fresh air. Sleep more (about 7 hours seems to be the right amount for most people). Work out, even if it’s only 15 minutes every other day. And start meditating for 2 minutes each day. Doing these things will improve every area of your life, not just your programming.
Always remember that the biggest factor that determines your success is not intelligence, or talent. Grit, the perseverance and passion for long-term goals, and your attitude towards getting better are what determines your path ahead.
Something to meditate on:
One day a monk visited Master Wq, and inquired, “Master, how will my code be different when I have mastered Vim?”
Master Wq answered, “Before Vim: declare, define, process, print. After Vim: declare, define, process, print.”
Thanks to eclubb, Tekhne, augiedb, michael, newton10471, and markijbema of the RubyRouges Parley forum for suggestions and feedback.
Even though the post discusses mastery in the context of a business and startup founders, its lessons are easily applicable to mastery in general. ↩
A presentation I gave at the Vienna.rb Meetup in June:
A small presentation I gave at the Vienna.rb Meetup in March:
If you installed Mercurial, but it fails with the following error message when you try to use it:
Traceback (most recent call last): File "/usr/local/bin/hg", line 38, in <module> mercurial.dispatch.run() File "/Library/Python/2.7/site-packages/mercurial/dispatch.py", line 28, in run sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255) File "/Library/Python/2.7/site-packages/mercurial/dispatch.py", line 41, in dispatch req.ui = uimod.ui() File "/Library/Python/2.7/site-packages/mercurial/ui.py", line 45, in __init__ for f in scmutil.rcpath(): File "/Library/Python/2.7/site-packages/mercurial/scmutil.py", line 464, in rcpath _rcpath = osrcpath() File "/Library/Python/2.7/site-packages/mercurial/scmutil.py", line 436, in osrcpath path = systemrcpath() File "/Library/Python/2.7/site-packages/mercurial/scmutil.py", line 489, in systemrcpath path.extend(rcfiles(os.path.join(p, root))) File "/Library/Python/2.7/site-packages/mercurial/scmutil.py", line 474, in rcfiles for f, kind in osutil.listdir(rcdir) File "/Library/Python/2.7/site-packages/mercurial/demandimport.py", line 86, in __getattribute__ self._load() File "/Library/Python/2.7/site-packages/mercurial/demandimport.py", line 58, in _load mod = _origimport(head, globals, locals) ImportError: dlopen(/Library/Python/2.7/site-packages/mercurial/osutil.so, 2): no suitable image found. Did find: /Library/Python/2.7/site-packages/mercurial/osutil.so: mach-o, but wrong architecture
Then your Python most likely runs in 32-bit mode. To force Python to run in 64-bit mode, run this command:
defaults write com.apple.versioner.python Prefer-32-Bit -bool no
One feature of any shell that is immensly useful is the history. Any command you made gets recorded, and you can then retrieve it later on with various commands (my favorite:
Ctrl-R, which allows you to search through your history).
At any given time, I usually have anywhere between 10 and 20 terminals open somewhere (not counting remote sessions). Thanks to zsh I can share every command I enter between all those terminal after I enter it and make it accessible via the history.
This means I no longer have to remember which terminal I entered my command in, all I have to do is search the history.
# Appends every command to the history file once it is executed setopt inc_append_history # Reloads the history whenever you use it setopt share_history
REPORTTIME is a nifty feature of
zsh. If you set it to a non-negative value, then every time, any command you run that takes longer than the value you set it to in seconds,
zsh will print usage statistics afterwards as if you had run the command prefixed with
So, for example, if we run
rake to rebuild any out of date files in Rubinius, we get this:
~/Development/Rubinius ☺ » rake [ … Lots of output …] Finished in 136.926808 seconds 3866 files, 21497 examples, 59187 expectations, 0 failures, 0 errors rake 160.78s user 26.49s system 81% cpu 3:50.20 total
(Yes, my prompt has a smiley in it. It turns sad and red when the exit status is non-zero)
Since this only makes sense in interative shells, I set this value in my
# Report CPU usage for commands running longer than 10 seconds REPORTTIME=10