Snakes for Camels – Why? – The actual reasons



Snakes for Camels – Why? – The actual reasons

0 1


snakes-for-camels

Python 101 for Perl programmers

On Github miquelruiz / snakes-for-camels

Snakes for Camels

Python 101 for Perl programmers

I started learning Python less than 1 year ago because I changed jobs.

Why?

Why the Pythonists think we have to learn Python.

Easy to learn

I wouldn't say it's easier than i.e. Ruby

Easy to read

import collections
class Solution:
  def canFinish(self, n, prs):
    m = collections.defaultdict(lambda: collections.defaultdict(set))
    map(lambda pr: m[0][pr[0]].add(pr[1]) or (m[1][pr[1]].add(pr[0])), prs)
    m[2][0].update(set(filter(lambda c: not m[0][c], xrange(n))))
    while m[2][0]:
      v = (lambda x: (m[2][1].add(x) or x))(m[2][0].pop())
      m[2][0].update(filter(lambda o: m[0][o].discard(v) or 
        (not m[0][o] and o not in m[2][1]), m[1][v]))
    return len(m[2][1]) == n
					

Source: https://leetcode.com/discuss/34793/my-10-line-unreadable-python-solution

Yes, sure, whatever

Focus on productivity

Besides Java and Brainfuck, do you know any other which doesn't?

The actual reasons

Lots of platforms/implementations

  • CPython (reference implementation)
  • ActivePython (from ActiveState)
  • IronPython (.NET and Mono platforms)
  • Jython (JVM)
  • Pypy (Python implemented in RPython)

Lots of awesome projects

  • BitTorrent
  • Ansible
  • Calibre
  • Deluge
  • Mercurial
  • Bazaar
  • Trac
  • GNU Mailman
  • OpenERP
  • YUM
  • Portage
  • And several more ...

Job oportunities!

Source: http://www.indeed.com/jobtrends

What is it?

  • Scripting language
  • Interpreted
  • General purpose
  • Multi paradigm (imperative, functional, ...)
  • Dynamically typed

Perl, anyone?

  • Scripting language
  • Interpreted
  • General purpose
  • Multi paradigm (imperative, functional, ...)
  • Dynamically typed

What's really different?

  • Syntax (obviously)
  • Strongly typed
  • Philosophy: TIMTOWTDI vs. "import this"
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
use Acme::this;
The Zen of Perl, by bellaire

Beauty is subjective.
Explicit is recommended, but not required.
Simple is good, but complex can be good too.
And although complicated is bad,
Verbose and complicated is worse.
Brief is better than long-winded.
But readability counts.
So use whitespace to enhance readability.
Not because you're required to.
Practicality always beats purity.
In the face of ambiguity, do what I mean.
There's more than one way to do it.
Although that might not be obvious unless you're a Monk.
At your discretion is better than not at all.
Although your discretion should be used judiciously.
Just because the code looks clean doesn't mean it is good.
Just because the code looks messy doesn't mean it is bad.
Reuse via CPAN is one honking great idea -- let's do more of that!

Credit: bellaire Source: http://www.perlmonks.org/?node_id=752029

Getting started

Install Python to play around

virtualenv is a tool to to create isolated Python environments

$ virtualenv my_python
Using base prefix '/usr'
New python executable in my_python/bin/python3
Also creating executable in my_python/bin/python
Installing setuptools, pip, wheel...done.

$ source my_python/bin/activate
(my_python)$ which python
/home/mruiz/my_python/bin/python

(my_python)$ deactivate
$ which python
/usr/bin/python
				
It doesn't support downloading and compiling Pythons It copies whatever Pythons you have installed to a new location So now that we have our own Python environment, let's write an application which uses, i.e. Redis. Get the spec, open sockets, etc. I can hear you all, waking up in the middle of the night, and screaming...

Where is my CPAN?!?!

Fear not! PyPI to the rescue The Python Package Index The official third-party software repository for Python

Not to be confused with PyPy (the implementation and JIT compiler)

Let's install some shit

pip vs. easy_install

pip ➔ cpanm easy_install ➔ cpan

pip (2008) easy_install (2004) Install from Wheels Yes No Uninstall Packages Yes (pip uninstall) No Dependency Overrides Yes No List Installed Packages Yes (pip list) No PEP438 Support Yes No Installation format 'Flat' packages Encapsulated Egg sys.path modification No Yes Install from Eggs No Yes pylauncher support No Yes Multi-version Installs No Yes

Source: https://packaging.python.org/en/latest/pip_easy_install.html

Now that we are motivated, and have our own Python env, let's dive into some details.

Python vs. Perl: Fight!

use strict;
use warnings;

use feature 'say';
use feature 'signatures';
no warnings 'experimental::signatures';
				
Since I'd like Perl to win, I'm going to cheat a bit.

Syntax overview

x = 0
while x < 10:
  print(x)
  x += 1

def sum(x, y):
  return x + y

print(sum(2, 3))
				
my $x = 0;
while ($x < 10) {
  say $x++;
}

sub sum($x, $y) {
  return $x + $y;
}

say sum(2, 3);
				
no parenthesis in the condition no curly braces line breaks to delimit statements compulsory indentation to delimit blocks subroutine signatures no ++ operator

Types

Python

  • int
  • float
  • str
  • byte
  • dict
  • list
  • set
  • tuple

Perl

  • scalar
  • array
  • hash

Everything's an object

list = ["Objects", "all", "over", "the", "place"]
print('.'.join(list))
list.append('xxx')

dict = {'key1': 'value1', 'key2': 'value2'}
keys = dict.keys()

(1.3).hex()
				

Anonymous functions

anon = lambda x:
  if x > 5:
    raise Exception("Too big")
  else:
    return x ** 2

print(anon(2))
				
my $anon = sub {
  my $x = shift;
  if ($x > 5) {
    die "Too big";
  } else {
    return ** 2;
  }
};
say $anon->(2);
				
anon = lambda x: x ** 2
print(anon(2))
				

Classes

class MyObj(object):

  def __init__(self, value):
    if value > 5:
      raise Exception('Too big')
    self.value = value

  def __add__(self, obj):
    return MyObj(self.value + obj.value)

  def __str__(self):
    return 'odd' if self.value % 2 else 'even'

  def double(self):
    return self.value * 2

a = MyObj(1)
b = MyObj(2)
c = a + b

print(c.value)
print(str(c))
print(c.double())
				
package MyObj;
use Moo;

use overload
  '+'  => \&_add,
  '""' => \&_str;

has value => (
  is => 'ro',
  isa => sub { die "Too big" if shift > 5; },
  required => 1,
);

sub _add {
  MyObj->new({value => shift->value + shift->value});
}

sub _str { shift->value % 2 ? 'odd' : 'even' }

sub double { shift->value * 2 }

1;
				

Other Pythonic cool stuff

Generators (state variables / Coro)

def gen():
    i = 0
    while True:
        yield str(i)
        i = i + 1

x = gen()
for i in range(0, 10):
    print(next(x))
				
use 5.010;

sub gen {
    state $i = 0;
    return $i++;
}

say gen() for (0..9);
				

List comprehensions (map, grep)

list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
squared_even = [x ** 2 for x in list if x % 2 == 0]
				
my @list = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
my @squared_even = map { $_ ** 2 } grep { $_ % 2 == 0 } @list;
				

More stuff

  • built in exceptions (Try::Tiny)
  • built in REPL (re.pl)
  • huge standard library (cpan)

Versioning shitshow

Python 2 vs. Python 3

Perl, anyone?

Perl 5 vs. Perl 6

Versioning shitshow

  • Python 3 released in December 2008
  • Breaks backwards compatibility with Python 2.x
  • No new features will go into 2.x branch
  • 3.x does not offer enough coolness to encourage migration
  • Lots of projects still in 2.x
  • 13779 PyPI ported packages out of 65396 (source: caniusepython3.com)

How to write portable code?

Prepend this to your Python 2 modules

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
				

Further reading

Snakes for Camels Python 101 for Perl programmers I started learning Python less than 1 year ago because I changed jobs.