python for php developers

80
Python for PHP Developers @ben_nuttall Raspberry Pi Foundation

Upload: bennuttall

Post on 07-Aug-2015

152 views

Category:

Technology


6 download

TRANSCRIPT

Python for PHP Developers

@ben_nuttallRaspberry Pi Foundation

About me

● Education Developer Advocate for Raspberry Pi Foundation– Developer & maintainer of www.raspberrypi.org– Education – teacher training & learning resources– Outreach – open source, education & programming conferences

● From Sheffield● BSc Mathematics & Computing in Manchester (MMU)● Lived in Cambridge since late 2013● Interested in programming, open source, Linux

About Raspberry Pi

● Family of affordable single board computers– ~£15 700MHz single core 256MB RAM– ~£25 900MHz quad core 1GB RAM

● Designed for use in education● Used in education, industry and by hobbyists● We're a charity (UK charity 1129409)● Founded and based in Cambridge● Staff of < 20● Raspberry Pi manufactured in Pencoed, Wales (not China)● Sold 6 million units since 2012 launch

What this talk is not

PHP● $a = 1;

● function foo() {

    return “bar”;

}● T_PAAMAYIM_NEKUDOTAYIM

Python● a = 1

● def foo():

    return “bar”

● ???

What this talk is also not

YOU ARE ALL IDIOTS YOU SHOULD BE USING PYTHON NOT PHP IT'S NOT EVEN A REAL LANGUAGE IT'S SO INCONSISTENT I DON'T EVEN

What this talk is

● Examples of Python● What makes Python code Pythonic● How to think like a Python programmer● Python Idioms● Practical Python – frameworks, libraries, infrastructure

About Python

● General purpose high-level programming language● Created in 1991 by Guido van Rossum● Cross-platform● Implemented in C (alternatives: Java, Python, C#)● Multi-paradigm (OO, Imperative, Functional, Procedural)● Dynamic type● Designed for readability

Python is for...

● Web programming (Django, Pyramid, Bottle, Flask...)● GUI development (wxPython, tkInter, PyGtk, PyQt...)● Scientific and Numeric (SciPy, NumPy, Pandas...)● Software development (Buildbot, Trac, Roundup...)● System Administration (Ansible, Salt, OpenStack...)● Embedded computing (Raspberry Pi, MicroPython, BeagleBone...)● Education (Raspberry Pi, Turtle, Robotics...)

Why Python?

● Professional and powerful modern language● Focus on readability● Strong community● Good documentation● Flexible● Full stack

Python 2 or Python 3?

● Python 3 was released in 2008, its current version is 3.4● Python 2 is considered legacy, its EOL is 2020

– No more major revisions (2.7.x – no 2.8)– However, everyone still uses it

● Python 3 is the present and future of the language● Python 3 contains some nice new features

– But apparently not different enough for people to bother to change– What version of PHP are you currently using in production? My guess: 5.3

● Some libraries don't support Python 3 yet● Examples in this presentation are for Python 3

Which version do I have?

● Linux (including Raspberry Pi):– python is Python 2

– python3 is Python 3

– (except Arch Linux – rebels)● Mac:

– Python 2 pre-installed, Python 3 available from python.org/downloads● Windows:

– Download either or both from python.org/downloads

Hello world

print(“Hello world”)

Built-in Numerical Types

● Numbers:– Integer

● Decimal● Binary● Octal● Hex

– Float

– Complex

● 123● 0b01111011● 0o173● 0x7b

– 123.0

– 123 + 123j

Strings

● Single quotes● Double quotes● Triple quotes

● s = 'hello'

● s = “Hello”

● s = “””

Hello world,

how are you?

“””

Built-in Data Structures

● List● Tuple● Dictionary

● Set

● [1, 2, 3]

● (1, 2, 3)

● {

    'a': 1,

    'b': 2,

    'c': 3,

}

● {1, 2, 3}

Keywords

● False

● None

● True

● and

● as

● assert

● break

● class

● continue

● def

● del

● elif

● else

● except

● finally

● for

● from

● global

● if

● import

● in

● is

● lambda

● nonlocal

● not

● or

● pass

● raise

● return

● try

● while

● with

● yield

Built-in functions● abs

● all

● any

● ascii

● bin

● bool

● bytearray

● bytes

● callable

● chr

● classmethod

● compile

● complex

● delattr

● dict

● dir

● divmod

● enumerate

● eval

● exec

● filter

● float

● format

● frozenset

● getattr

● globals

● hasattr

● hash

● help

● hex

● id

● input

● int

● isinstance

● issubclass

● iter

● len

● list

● locals

● map

● max

● memoryview

● min

● next

● object

● oct

● open

● ord

● pow

● print

● property

● range

● repr

● reversed

● round

● set

● setattr

● slice

● sorted

● staticmethod

● str

● sum

● super

● tuple

● type

● vars

● zip

Import

● import time

● from time import sleep

● from picamera import PiCamera

● Import the whole time module, namespaced as time

● Import only the sleep function from time module

● Import only the PiCamera class from the picamera module

Import

● from datetime import datetime, timedelta

● import numpy as np

● from numpy import *

● Import only the datetime and timedelta functions from the datetime module

● Import the numpy module, namespaced as np

● Import all objects from numpy module, polluting the namespace

(don't do this)

Paradigms

● Procedural● Functional● Object Oriented

Procedural

● C● Go● Fortran● Pascal● BASIC

Loops

for i in range(10):

    print(“Hello world”)

i = 0

while i < 10:

    i += 1

    print(“Hello world”)

    

while True:

    print(“Hello world”)

Iterables & Enumeration

people = [“Alice”, “Bob”, “Charlie”]

for person in people:

    print(“Hello %s” % person)

for i, name in enumerate(people):

    print(“%i: %s” % (i, name))

Functions

def greeting():

    print(“Hello”)

greeting()

Functions

def greeting(name):

    print(“Hello %s” % name)

greeting(“Ben”)

Functions

def greeting(name=None):

    if name:

        print(“Hello %s” % name)

    else:

        print(“Hello”)

greeting()

greeting(“Ben”)

Functions – positional & named argumentsdef birthday_greeting(name=None, age=None):

    if name and age:

        print(“Happy %ith birthday, %s” % (age, name))

    elif name:

        print(“Happy birthday, %s” % name)

    elif age:

        print(“Happy %ith birthday” % age)

    else:

        print(“Happy birthday”)

birthday_greeting()  # use default arguments

birthday_greeting(“Ben”)  # positional argument

birthday_greeting(name=”Ben”, age=26)  # named arguments

birthday_greeting(age=26, name=”Ben”)  # named arguments, reverse order

birthday_greeting(age=26) # named argument

Functions – keyword arguments

def foo(**kwargs):

    if 'name' in kwargs:

        print(“Hello %s” % name)

Functions – globals (read only)

pi = 3.14159265358979

def circumference(radius):

    return 2 * pi * radius

Functions – globals (read/write)

total = 0

def add_one():

    global total

    total += 1

Functions – return vs. yield

def get_square_numbers(n):

    squares = []

    for i in range(n):

        squares.append(i**2)

    return squares

>>> get_square_numbers(10)

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Functions – return vs. yield

def get_square_numbers(n):

    for i in range(n):

        yield i**2

>>> square_numbers = get_square_numbers(10)

>>> square_numbers.next()

0

>>> square_numbers.next()

1

Functional

● Haskell● ML● Common Lisp● Scheme● Clojure● Erlang● F#

List comprehension

squares = []

for n in range(10):

    squares.append(n**2)

print(squares)

squares = [i**2 for i in range(10)]

Set comprehension

>>> [i**2 for i in [­5, ­4, ­3, 2, 3, 4, 5]]

[25, 16, 9, 4, 9, 16, 25]

>>> {i**2 for i in [­5, ­4, ­3, 2, 3, 4, 5]}

{4, 9, 16, 25}

Dictionary comprehension

>>> {i: i**2 for i in range(5)}

{

 0: 0,

 1: 1,

 2: 4,

 3: 9,

 4: 16,

}

Generator Expressions

>>> squares = (i**2 for i in range(5))

>>> squares.next()

0

>>> squares.next()

1

Map

def square(n):

    return n**2

>>> things = [1, 2, 3]

>>> square_things = map(square, things)

>>> print(list(square_things))

[1, 4, 9]

functools & itertools

● functools - for higher-order functions: functions that act on or return other functions

● itertools - a number of iterator building blocks inspired by constructs from APL, Haskell, and SML, each recast in a form suitable for Python– product

– combinations

– permutations

Object Oriented

● C++● Objective-C● Smalltalk● Java● C#● Ruby

Classes

class Dog:

    pass

>>> d = Dog()

Classes – init and properties

class Dog(object):

    def __init__(self, name):

        self.name = name

>>> d = Dog(“Bingo”)

>>> print(d.name)

Classes - methods

class Dog(object):

    def __init__(self, name):

        self.name = name

    def bark(self):

        print(“woof”)

>>> d = Dog(“Bingo”)

>>> d.bark()

woof

Classes - @property

class Dog(object):

    def __init__(self, name):

        self.name = name

        self.born = time()

    @property

    def age(self):

        return time() ­ self.born

>>> d = Dog(“Bingo”)

>>> print(d.age)

Classes – magic methodsclass PlayingCard(object):

    VALUES = ('2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A')

    SUITS = ('H', 'D', 'S', 'C')

    def __init__(self, value, suit):

        self.value = value

        self.suit = suit

    def __repr__(self):

         return “%s%s” % (self.value, self.suit)

    def __eq__(self, other):

        return self.VALUES.index(self.value) == self.VALUES.index(other.value)

    def __lt__(self, other):

        return self.VALUES.index(self.value) < self.VALUES.index(other.value)

    def __gt__(self, other):

        return self.VALUES.index(self.value) > self.VALUES.index(other.value)

>>> card_1 = PlayingCard('A', 'S')

>>> card_2 = PlayingCard('9', 'D')

>>> print(card_1 > card_2)

True

>>> cards = [card_1, card_2]

>>> print(max(cards))

AS

The Zen of Python

The Zen of Python● 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!

Python Idioms

● “The specific grammatical, syntactic, and structural character of a given language”

● “A commonly used and understood way of expressing a fact, idea or intention.”

Examples by Safe Hammad

http://safehammad.com/downloads/python-idioms-2014-01-16.pdf

Python Idioms

● "Programs must be written for people to read, and only incidentally for machines to execute."

- Abelson & Sussman, SICP

● “There should be one - and preferably only one - obvious way to do it.”

- The Zen of Python

● The use of commonly understood syntax or coding constructs can aid readability and clarity.● Some idioms can be faster or use less memory than their “non-idiomatic” counterparts.● Python's idioms can make your code Pythonic!

Make a script both importable and executable

if __name__ == '__main__':

    main()

Test for “truthy” and “falsy” values

if x:

if not x:

Test for “truthy” and “falsy” values

# GOOD

name = “Ben”

if name:

    print(“Hello %s” % name)

# BAD

if name != “”:

    print(“Hello %s” % name)

Truth

● True:– Non-empty string

– Number not 0

– Non-empty container (len(x) > 0)

– True

● False:– Empty string

– Number 0

– Empty container (len(x) == 0)

– False

– None

in

● Contains:

if x in items:

● Iteration:

for singular in plural:

in – iteration (list)

people = [“Alice”, “Bob”, “Charlie”]

# GOOD

for name in people:

    print(name)

# BAD

for i in range(len(people)):

    print(people[i])

in – iteration (dictionary)

people = {“Alice”: 23, “Bob”: 21, “Charlie”: 30}

# GOOD

for name, age in people.items():

    print(“%s is %i” % (name, age))

# BAD

for name in people:

    print(“%s is %i” % (name, people[name]))

in - contains

people = [“Alice”, “Bob”, “Charlie”]

name = “Ben”

if name in people:

    print(“in”)

else:

    print(“out”)

Swap variables

a = 1

b = 2

# GOOD

a, b = b, a

# BAD

c = a

a = b

b = c

Join

words = ['hello', 'world']

# GOOD

print(' '.join(words))

# BAD

s = ''

for word in words:

    s += word + ' '

print(s)

with – self-cleanup

# GOOD

with open('file.txt') as f:

    line = f.readline()

# BAD

f = open('file.txt')

line = f.readline()

with – self-cleanup

# GOOD

with PiCamera() as camera:

    camera.start_preview()

    sleep(2)

    camera.capture('image.jpg')

    camera.stop_preview()

# BAD

camera = PiCamera()

camera.start_preview()

sleep(2)

camera.capture('image.jpg')

camera.stop_preview()

Exceptions

people = {“Alice”: 23, “Bob”: 21, “Charlie”: 30}

name = “Ben”

# OK

if name in people:

    age = people[name]

else:

    age = None

Exceptions

people = {“Alice”: 23, “Bob”: 21, “Charlie”: 30}

name = “Ben”

# GOOD

try:

    age = people[name]

except ValueError:

    age = None

# BAD

try:

    age = people[name]

except:

    age = None

Exceptions – try/except not try/catch!

try:

    import GPIO

except ImportError:

    GPIO = None

if GPIO:

    …

else:

    print(“Cannot access GPIO”)

Exceptions – patch to work in Python 2 and 3

try:

    input = raw_input

except NameError:

    pass

Exceptions – patch to work in Python 2 and 3

from __future__ import (

    unicode_literals,

    print_function,

    division,

    absolute_import,

)

# Make Py2's str and range equivalent to Py3's

str = type('')

try:

    range = xrange

except NameError:

    pass

PEP : Python Enhancement Proposals

PEP8 - Style Guide for Python Code● Indentation● Tabs or spaces?● Maximum line length● Blank lines● Source file encoding● Imports● String quotes● Whitespace● Comments● Versioning● Naming conventions● Programming recommendations

PyPi: Python Packaging Index

● Free-for-all upload of Python packages and modules● Namespace based● Browsable online● Easy to upload & update● Easy to download● Easy to install & upgrade

What a Python package looks like

 ├── energenie

     │ ├── energenie.py

     │ └── __init__.py

 └── setup.py

Write in C - optional

● Python modules can be written in C for optimal speed

Installing packages with pip

$ pip install energenie

$ pip3 install energenie

Virtualenv

● Isolated environment for running an appplication with specific version dependencies

● Run multiple apps requiring different versions of libraries● Use pip to install within a virtualenv

Secrets from the Future

● from __future__ import print_function, division

Bring Python 3 features into Python 2

2to3

● Convert a Python file, set of files or module from Python 2 to Python 3 syntax– Often trivial– Sometimes requires manual intervention– Dry run to see suggested changes first

Tips

● IPython shell● IPython Notebook● Trinket● PEP8● python.org – docs, examples, wiki● PyPi

Community

● PyCon– PyCon (Montreal)– PyConUK (Coventry)– EuroPython (Bilbao)– PyCon Ireland (Dublin)– EuroSciPy (Cambridge)– Many more!

● User groups & organisations– Campug– London Python Dojo– PyLadies– Django Girls– Python Software Foundation

Further reading

● Why Python is a Great First Language http://blog.trinket.io/why-python/

● Python Success Stories

https://www.python.org/about/success/● Python in Education

http://www.oreilly.com/programming/free/python-in-education.csp

Learn Python

● Python Challenge

http://www.pythonchallenge.com/● Python Docs

https://www.python.org/doc/● Project Euler

https://projecteuler.net/● Raspberry Pi Learning Resources

https://www.raspberrypi.org/resources/● Trinket

https://trinket.io/python

Python for PHP Developers

@ben_nuttallRaspberry Pi Foundation