See all articles
A gentle introduction to Python for hardcore Rubyists

A gentle introduction to Python for hardcore Rubyists

This article is not intended to be yet another “Python syntax tutorial for newbies”, or a “Ruby vs Python” comparison. Instead, we want to show you one of the possible paths you can take as a Ruby developer to learn Python quickly and easily. And to show you why it’s worth it to add Python to your programmer’s repertoire.

Why should a Ruby dev learn Python? Why is Python Cool?

As you’re probably aware, Python is an expressive, dynamically typed, multi-purpose language. It can be used for both desktop and web applications, as well as for complex scientific projects leveraging large volumes of data or using deep learning. Python offers a syntax that’s easy to learn and use, and this simplicity stands at the core of its philosophy. It makes Python somewhat similar to Ruby. In fact, Ruby is influenced by some core concepts from Python’s language philosophy, including simplicity.

Python’s design includes features that facilitate data analysis and visualization. Python’s libraries and APIs allow for presenting data in very appealing ways, and for conveying information effectively. This is very helpful for building custom big data solutions, as it saves the development team some time and effort. Python can also be used for artificial intelligence and natural language processing projects.

It’s no surprise that, over recent years, the language has gained a lot of positive attention. It’s currently one of the most popular programming environments.

What’s new in the Python world in 2020

While the existence of Python 3 is definitely not news, let’s take a quick look at this most recent version of the language. It was first presented in December 2008. Despite the fact that the actual current version (3.8) differs slightly from its 3.0 (or Py3k) predecessor, changes haven’t been huge, at least in terms of compatibility.

The shift between versions 3 and 2, on the other hand, was big. There is no backwards compatibility at all. As such, it might surprise you that, even as recently as 2-4 years ago, there was no clear preference between versions 2 and 3. No backwards compatibility would mean porting multiple legacy applications and modules, which wasn’t a trivial task. Those who felt it wouldn’t be a worthwhile endeavour simply continued on with Python 2. The community didn’t so much resist the change as it avoided it - but only for a time.

As of 01.01.2020, Python 2 is officially dead. That is, it has been retired. Those of us new to the world of Python development, or at least those not working on legacy apps, don’t need to worry about the change very much. (It’s a lot like what happened with Ruby 1.9). Those whose Python 2.x apps are still operational might need to consider switching to Python 3 in the near future.

Python from a Ruby expert’s perspective - tools of the trade

Every programmer has their own preferred set of tools, patterns and well-known solutions. Because of this, you might be reluctant to make the switch from Ruby to Python, as you wouldn’t have access to all the things you like. But worry not! We’ve prepared a quick breakdown of what’s available for both of these languages, and how the tools available compare to each other.

IDE

If you’re coming from the RubyMine world, then starting your journey with Python using PyCharm should be pretty painless. The whole IDE is almost identical, with only minor colour changes and language specific features. Which is hardly surprising, as the same company created both.

You might also want to take a look at other solutions, such as Spyder (if you’re interested in data analytics and data science), or PyDev which is essentially an Eclipse port for Python. Other plugins for a typical IDE include Atom and Sublime Text. Everyone should be able to find something for themselves.

Packages

In the Ruby world, package management is ruled by gems. Python has a close equivalent, called pip. Using it is fairly straightforward, and it has received recommendations by the Python core team.

Package versioning

By now you might be wondering about how to accomplish scenarios with multiple versions of different packets under specific bags. We have good news for all rvm, rbenv enthusiasts: there are viable alternatives in the Python ecosystem, virtualenv and pyenv. It’s difficult to declare one superior to the other - it’s a matter of personal preferences.

Working with virtualenv involves two main shell commands:

  • `$ virtualenv ENV`
  • `$ source /path/to/ENV/bin/activate`

That's pretty much it! You have a nice sandbox with only those packages that you want. If you want to change them, just hit `$ deactivate` and it’s done. Quick and easy.

Shell

Python offers its own shell, IPython, which allows for real-time interpretation. In the Ruby world, we can call it Python’s irb alternative. Like with Ruby, a developer can easily run snippets or load entire methods to namespace and play around. Typically for an interpreter, IPython allows rapid testing of new libraries and debugging.

Debugging

We all know that good and reliable software should be equipped with meaningful test coverage. Despite that, we might need a tool for temporary fixes when debugging something specific. In the Ruby ecosystem, we have Pry or ByeBug. Python offers its own options, including ipdb and pdb. Both are good at what they are meant to do.

Web frameworks

The most popular Python framework used for web development is Django. It’s quite mature and popular, but has a very different philosophy compared to Rails. Django emphasizes rapid development, but under the hood you won’t find typical RoR magic (e.g. an overriden autoloader). Django represents the MTV rather than the MVC approach. The framework's strengths include really great documentation, versatility, and its facilitation of rapid development.

For those who prefer more lightweight solutions, the Pyramid framework is a nice option. Its learning curve is significantly lower, too. Another similar framework is Flask, which is something of an alternative to Ruby’s Sinatra. It might not be as robust as other frameworks, but it’s still rather popular, particularly for data engineering work (thanks to its simple API and hassle-free approach). For non-mainstream enthusiasts looking for a robust and versatile framework (like Hanami in the Ruby World), the lightweight but powerful Falcon can be a good choice.

Traps Ruby experts might fall into when working with Python

The order of parameters or callers might look a bit weird for Rubyists

Take a look at the following equivalent code samples. Of note: Both are doing the exact same thing!

Ruby:

a = [1,2,3,4,5]
a.reduce(0) {|acc, el| acc = acc + el} # Alernatively a.reduce{|acc, el| acc += el}
a.map{ |x| x*x } # a.calls with block
"hello".gsub('ll', 'xxx')
printf("%s %7.2f\n", "Cathy", 13.4345)
# List comprehension
(0..99).select {|x| x % 2 == 0 }.map {|x| x ** 2 } # is likely easier to understand than the Python’s

Python:

import re 
a = [1,2,3,4,5]
reduce(lambda x, y: x + y, a) 
reduce(lambda x: x*x, a) # reduce takes lambda (with block) and takes ‘a’
re.sub("ll", "xxx", "hello")
print("%s, %7.2f" % ("Cathy", 13.4345))
# List comprehension
[(x ** 2) for x in range(100) if (x % 2 is 0)] # More like calculus style

It’s not an issue of which language is better, but a matter of proficiency and convention. Anyone with a Ruby background might be momentarily confused. “I cannot count how many times I tried to trigger in the wrong direction,” says one of iRonin.IT’s developers.

The “yield” keyword is the same, but different

This difference, at least, is quite commonly known. A Ruby `yield` (with or without a block) allows you to pass a set of extra instructions during a method invocation. Whereas for Python, `yield`'s definition is more precise (and concise, as is most of the language’s syntax). The keyword is used like `return`, except the function will return a generator.

It’s crucial to understand that, whenever you call the function, the code written in the function body does not run. All the function does is return the generator object. That’s the difference between Python and Ruby.

Read Similar Articles