Slide 1

Slide 1 text

Python for Ruby Programmers MIKE LEONE LA RUBYCONF 2013 FEB 23 2013

Slide 2

Slide 2 text

This presentation: 1. Fast-paced 2. Python in 30 mins 3. It's easy!

Slide 3

Slide 3 text

About Me

Slide 4

Slide 4 text

Web Mobile Embedded

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

That's it.

Slide 13

Slide 13 text

Ruby: 2006 Python: 2010

Slide 14

Slide 14 text

New appreciation Better Rubyist

Slide 15

Slide 15 text

What we'll cover

Slide 16

Slide 16 text

1. Example program 2. 13 Design similarities 3. 13 Differences 4. 5 Problem domains 5. “Feelings”

Slide 17

Slide 17 text

What we WON'T cover

Slide 18

Slide 18 text

1. Implementations 2. Performance (Good enough) 3. Parallelism (GIL) 4. Minor syntax (You'll get it)

Slide 19

Slide 19 text

What I'll try to convince you:

Slide 20

Slide 20 text

1. VERY similar! 2. You're already ready 3. Python = Better Rubyist 4. Hire a Pythonista

Slide 21

Slide 21 text

Zen of Python (abridged)

Slide 22

Slide 22 text

1. Explicit is better than implicit. 2. Flat is better than nested. 3. Readability counts. 4. There should be [only] one obvious way to do it. 5. Namespaces are a great idea -- let's do more of those!

Slide 23

Slide 23 text

Example: Create a Person class

Slide 24

Slide 24 text

1. Name and age 2. Can greet you 3. Knows if it's Beiber 4. Greets Google directors

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

13 Similarities

Slide 28

Slide 28 text

1. Dynamically Typed

Slide 29

Slide 29 text

def print_object(some_sorta_object): print some_sorta_object.read() print_object(my_file) >>> “This is the file contents”

Slide 30

Slide 30 text

2. Everything is an Object (even functions!)

Slide 31

Slide 31 text

Python example: 5 + 3 >>> 8 (5).__add__(3) >>> 8 (5).__str__() >>> “5”

Slide 32

Slide 32 text

3. Arrays

Slide 33

Slide 33 text

things = [1, "hello", 2.5, 43] things[1] >> 'hello' Ruby (array)

Slide 34

Slide 34 text

things = [1, "hello", 2.5, 43] things[1] >> 'hello' Python (list)

Slide 35

Slide 35 text

4. Hash Tables

Slide 36

Slide 36 text

color_map = { red: "#FF0000", purple: "#800080"} color_map[:red] >> "#FF0000" Ruby (hash)

Slide 37

Slide 37 text

color_map = { "red": "#FF0000", "purple": "#800080"} color_map["red"] >> "#FF0000" Python (list)

Slide 38

Slide 38 text

5. No special line terminators (no semicolons!)

Slide 39

Slide 39 text

6. Strong functional programming paradigms

Slide 40

Slide 40 text

def triple(number): return number * 3 list = [1, 2, 3, 4] map(triple, list) >>> [3, 6, 9, 12] Map

Slide 41

Slide 41 text

def is_even(number): return number % 2 == 0 list = [1, 2, 3, 4] filter(is_even, list) >>> [2, 4] Filter

Slide 42

Slide 42 text

list = [1, 2, 3, 4] map(lambda x: x *3, list) >>> [3, 6, 9, 12] Anonymous Functions (lambda)

Slide 43

Slide 43 text

7. Awesome function parameters

Slide 44

Slide 44 text

Optional / named arguments

Slide 45

Slide 45 text

def greet(name, greeting="Hello"): print greeting + ", " + name greet("Bob") >>> Hello, Bob greet("Bob", greeting="Bonjour") >>> Bonjour, Bob greet("Bob", "Bonjour") >>> Bonjour, Bob

Slide 46

Slide 46 text

Argument Unpacking

Slide 47

Slide 47 text

def greet_everyone(*names): for name in names: print "Hello, " + name names = ["Bob", "Steve", "Jim"] greet_everyone(*names) Hello, Bob Hello, Steve Hello, Jim

Slide 48

Slide 48 text

8. Raising Exceptions

Slide 49

Slide 49 text

inputted_age = 30 if inputted_age > 25 raise ArgumentError, "must be under 26" end ArgumentError: must be under 26 (stack trace...) Ruby

Slide 50

Slide 50 text

inputted_age = 30 if inputted_age > 25: raise ValueError("must be under 26") (stack trace...) ValueError: must be under 26 Python

Slide 51

Slide 51 text

9. Handling Exceptions

Slide 52

Slide 52 text

begin 23 / 0 puts "all good" rescue ZeroDivisionError puts "can't do that, bro" end >> can't do that, bro Ruby (rescue)

Slide 53

Slide 53 text

try: 23 / 0 print “all good” except ZeroDivisionError: print "can't do that, bro" >> can't do that, bro Python (except)

Slide 54

Slide 54 text

10. One-line conditionals

Slide 55

Slide 55 text

“equal” if 3 == 3 >> “equal” 2 == 3 ? “equal” : “not equal” >> “not equal” Ruby

Slide 56

Slide 56 text

if 3 == 3: “hello” >>> “hello” “equal” if 2==3 else “not equal” >> “not equal” Python

Slide 57

Slide 57 text

11. Nice interactive shells

Slide 58

Slide 58 text

$ python Python 2.7.3 (default) >>> 2 + 2 4 $ irb irb(main):001:0> 2 + 2 => 4

Slide 59

Slide 59 text

12. Strong object reflection features

Slide 60

Slide 60 text

steve = Person("Steve Ballmer", 54) steve.__dict__ >>> {'age': 54, 'name': 'Steve Ballmer'} steve.__class__ >>> dir(steve) # all methods/attrbutes ['GOOGLE_DIRECTORS', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'greet', 'greet_google_directors', 'is_justin_beiber', 'name', 'say_name_and_age']

Slide 61

Slide 61 text

13. Radically simpler than C++/Java!

Slide 62

Slide 62 text

13 Differences

Slide 63

Slide 63 text

1. No blocks

Slide 64

Slide 64 text

Blocks are the killer feature of Ruby

Slide 65

Slide 65 text

1. Powerful metaprogramming 2. DSLs 3. Great frameworks (Rails)

Slide 66

Slide 66 text

Decorators are a powerful Python feature similar to blocks.

Slide 67

Slide 67 text

They let you inject or modify code in a function, like blocks. But not enough time.

Slide 68

Slide 68 text

2. First-class Functions

Slide 69

Slide 69 text

Functions as variables

Slide 70

Slide 70 text

def add(a, b): return a + b def subtract(a, b): return a – b def process_numbers(a, b, func): return func(a, b) process_numbers(20, 5, add) >>> 25 process_numbers(20, 5, subtract) >>> 15

Slide 71

Slide 71 text

Similar behavior is possible in Ruby, but you must wrap functions in procs.

Slide 72

Slide 72 text

3. One-line lambdas, by design

Slide 73

Slide 73 text

Can't do this in Python: [1, 2, 3, 4, 5].map do |num| if num % 3 == 0 0 elsif num % 4 == 0 num * 2 else num end end

Slide 74

Slide 74 text

But do you really want to do that? 1. Harder to test 2. Harder to follow 3. Accidentally duplicate

Slide 75

Slide 75 text

Python pushes you to factor things out into granular methods.

Slide 76

Slide 76 text

def process_num(num): if num % 3 == 0: return 0 elif num %4 == 0: return num * 2 else: return num return map(process_num, [1,2])

Slide 77

Slide 77 text

Python even supports inner methods to this end.

Slide 78

Slide 78 text

def start_program(): def process_num(num): if num % 3 == 0: return 0 elif num %4 == 0: return num * 2 else: return num return map(process_num, [1,2])

Slide 79

Slide 79 text

4. Python has “tuple,” an immutable list.

Slide 80

Slide 80 text

[1, 2, 3] # can change (1, 2, 3) # can't change (Should be homogeneous, but not enforced)

Slide 81

Slide 81 text

5. Python has more fine-grained importing

Slide 82

Slide 82 text

require 'open-uri' result = open(“http://google.com”) Ruby You bring in everything from open-uri With lots of requires, which one is responsible?

Slide 83

Slide 83 text

from urllib2 import urlopen response = urlopen(“http://google.com”) Python “Explicit is better than implicit.” You can write from urllib2 import * , but not a best practice.

Slide 84

Slide 84 text

You can import any number of specific functions or variables from a python module(file).

Slide 85

Slide 85 text

6. Python enforces indentation

Slide 86

Slide 86 text

In practice, this is pretty awesome.

Slide 87

Slide 87 text

Doesn't cause headaches. Makes code style more consistent.

Slide 88

Slide 88 text

7. Python has more values that evaluate to False.

Slide 89

Slide 89 text

False None (nil) [ ], (), {} ' ' 0

Slide 90

Slide 90 text

8. Instead of Enumerable, Python has built-in functions

Slide 91

Slide 91 text

filter() map() reduce()

Slide 92

Slide 92 text

Convenient, but not as powerful as Enumerable.

Slide 93

Slide 93 text

9. Python has simpler conditionals

Slide 94

Slide 94 text

No case statements (use if... elif... else instead) if n == 0: print "You typed zero.\n" elif n== 1 or n == 9 or n == 4: print "n is a perfect square\n" elif n == 2: print "n is an even number\n" elif n== 3 or n == 5 or n == 7: print "n is a prime number\n"

Slide 95

Slide 95 text

No “unless” unless !person.present? && !company.present? puts "do you even know what you're doing?" else puts "and now we're really confused" end

Slide 96

Slide 96 text

10. No automatic return values

Slide 97

Slide 97 text

Functions return None if they don't have an explicit “return” statement. def add(a, b): a + b add(2, 3) >>> None

Slide 98

Slide 98 text

11. “self” as an argument to every class instance method

Slide 99

Slide 99 text

Pro: Explicit No clashes with local variables or other imported objects Con: More verbose

Slide 100

Slide 100 text

Class Person(object): def __init__(self, name): self.name = name def say_hi_to(self, name): print self.name + “ says hi to ” + name Person(“Steve”).say_hi_to(“Bob”) >>> “Steve says hi to Bob”

Slide 101

Slide 101 text

12. No powerful module mixins like Ruby.

Slide 102

Slide 102 text

Multiple inheritence only (yuck)

Slide 103

Slide 103 text

13. Ruby has stronger metaprogramming features

Slide 104

Slide 104 text

Python doesn't have define_method class_eval method_missing

Slide 105

Slide 105 text

Can't reopen a class and extend it Can't extend built-in types (maybe for the better?)

Slide 106

Slide 106 text

5 Problem Domains

Slide 107

Slide 107 text

1. Web Development

Slide 108

Slide 108 text

Ruby: Rails, Sinatra Ruby community is dominated by web development

Slide 109

Slide 109 text

Python: Django, Zope, Flask, Pylons. Web dev is just one piece of the gigantic python community.

Slide 110

Slide 110 text

2. Mobile Applications

Slide 111

Slide 111 text

Neither language is popular for mobile apps. Interesting Ruby projects: Rhodes, RubyMotion.

Slide 112

Slide 112 text

3. Desktop Applications

Slide 113

Slide 113 text

Python has PyQT, wxPython, PyGTK. Ruby has shoes, wxRuby, RubyGTK, but not popular or mature.

Slide 114

Slide 114 text

4. Scientific Programming

Slide 115

Slide 115 text

Python has numpy, scipy. Widely used. Ruby doesn't have any mature scientifc/numeric libraries.

Slide 116

Slide 116 text

5. Windows Deployment (if you must)

Slide 117

Slide 117 text

Ruby: RailsInstaller is great. Doesn't target deployment. JRuby makes windows deployment much easier.

Slide 118

Slide 118 text

But Python on windows is generally easier. Why? Because entire toolchain is well- supported. Windows neglect is self-perpetuating.

Slide 119

Slide 119 text

The Python community is just bigger.

Slide 120

Slide 120 text

“Feelings”

Slide 121

Slide 121 text

It's harder to write code that pisses off other developers in Python.

Slide 122

Slide 122 text

1. Smaller grammar 2. Forced indentation 3. Fewer ways to handle conditionals 4. The source of imported functionality is obvious 5. Explicit class and method structure makes code easier to follow.

Slide 123

Slide 123 text

Ruby is more elegant, but in practice, Python is easier to read.

Slide 124

Slide 124 text

Rails still wins for web development.

Slide 125

Slide 125 text

Nothing as good as Rails will ever be implemented in Python. (metaprogramming, reflection)

Slide 126

Slide 126 text

Need to hire a Rubyist? Hire a Pythonista instead.

Slide 127

Slide 127 text

1. Ruby developer market is out of control. 2. There are more Python developers 3. Pythonistas can ramp up EASILY (hours/days, not weeks/months)

Slide 128

Slide 128 text

Wrap-up

Slide 129

Slide 129 text

1. VERY similar! 2. You're already ready 3. Python = Better Rubyist 4. Hire a Pythonista

Slide 130

Slide 130 text

MIKE LEONE panopticdev.com leone.panopticdev.com @panopticdev @facebiff THANK YOU!