Post on 19-Feb-2017
PYTHON: AN INTRODUCTION FOR PHP DEVELOPERS
What will we talk about?
Some general information about Python
Some code - enough to be able to read and understand python code
Some minimal practical examples of python code and that based on things that I picked up @ Dx-Solutions.
Any questions ? Feel free to interrupt !
What is python ?Python is a widely used general-purpose, high-level programming language.
Its design philosophy emphasises code readability.
Python supports multiple programming models, including object-oriented, procedural and functional programming.
Has a large and comprehensive standard library.
Python can be run on many operating systems and (embedded) platforms.
Things that ruleIt’s easy, flexible and powerful. Good to have in your toolbox!
String handling is fantastic
A wide range of good third party libraries (because it has a close relationship with C)
It is extremely versatile (web, gui apps, arduino yun, scripting …)
Great prototype language
It’s really fun
Things that can biteUses whitespace (tabs) to delimit program blocks (personal preference)
It isn’t the fastest language (but projects like cython, pypy, … counters that)
Python 3 is not backward compatible unfortunately. In this presentation we will focus on Python 2.x.
Package management could be better and isn’t that good like in node.js or PHP
Who uses it ?
In BelgiumNot a lot of big players
Mobile Vikings
Belgacom BIC
GDF Suez
Belfius
…
Lot of misconceptions
(toy language, only for experiments, small startups, …)
Starting to get some traction in higher education (university of Gent, Leuven, Antwerp)
Some web frameworks
https://github.com/vinta/awesome-python
BeautifulSoup
Work project: GhelamcoCSV fields -> doctrine generator. Really speeded up the process to create entities.
SQL generator to automatically generate dump queries
Tool to dump table column names (for example to use in certain queries)
RAW dump importer (that served as a prototype for a PHP symfony command)
From CSV data
To generate doctrine entity fields
… now imagine if you need to do that manually…Average runtime: less than a second…
Personal project: WebGL baking tool
http://www.simplicity.be/improving-realism-in-webgl-scenes-by-using-texture-baking/
Now for the code stuff…
IDEPython comes with a builtin IDE “Idle” which feels a bit dated and isn’t that good
PHPStorm lovers will be glad to know that jetbrains also has a python IDE called PyCharm
Community edition is free
But the web support isn’t in the free edition
But in reality every text editor will suffice
PyCharm CE
Running python• Through the interactive python shell
$ pythonPython 2.7.9 (default, Dec 19 2014, 06:00:59) [GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> print "hello world"hello world>>>
Running python• By running a .py file
hello.py
print "hello world"
$ python hello.pyhello world
command
2 very handy methodsdir
list attributes and methods
help
shows builtin help
dir (example)>>> dir("dx-solutions")['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
help (example)
>>> help(“dx-solutions”.upper)
Help on built-in function upper:
upper(...) S.upper() -> string Return a copy of the string S converted to uppercase.(END)
CommentsA comment in python start with a hash (#) symbol
No multiline comments
use multiple #
Comments (examples)// hello world
/** * hello * world **/
PHP
# hello world
# hello# world
Python
VariablesPython is a dynamically typed language. So you do not need to declare variables before using them or declare their type (like PHP)
Every variable in Python is an object…
…that has an id
…that is of a certain standard data type
…that has a mutable or immutable value
Mutable vs immutableMutable: you can change an object without changing its identity. So in other words when you alter an object its id will be the same.
Immutable: you can not change an object without changing its identity. So when you alter an object its id will change!
Mutable vs immutable (examples)
>>> myval = "dxsolutions">>> id(myval)4538483456>>> myval = "dx-solutions">>> id(myval)4538475888
Immutable
>>> mylist = []>>> id(mylist)4538197848>>> mylist.append("hello")>>> id(mylist)4538197848
Mutable
Standard data typesNumber
integer
float
long
complex
String
List
Tuple
Dictionary
Variables declarations (examples)
$var_1 = 1; // Integer $var_2 = 3.14; // Float$var_3 = "hello"; // String$var_4 = 'hello'; // String
PHP
var_1 = 1 # Integervar_2 = 3.14 # Floatvar_3 = "hello" # Stringvar_4 = 'hello' # Stringvar_1 = 'abc' # Is now a string
Python
Math operatorsArithmetic operators are the same as PHP
Notation Description
+ add
- subtract
* multiply
/ division
% modulo
** power operator** the ** operator is introduced in PHP 5.6
Assignment operatorsNotation Description
= simple assignment
+= add and assign
-= subtract and assign
*= multiply and assign
/= divide and assign
%= modulo and assign
**= exponent and assign*
//= floor division and assign** not available in PHP
Comparison operatorsNotation Description
== is equal*
!= not equal
<> not equal
> bigger than
< smaller than
>= bigger than or equal
<= smaller than or equal* doesn’t have the === operator
Logical operators
Notation Description
and and
or or
not not
Chained comparisons
# chainedif 5 < x < 7:
print 6
# same as if x > 5 and x < 7: print 6
Strings (examples)$var_1 = 'Thunderstruck';$var_2 = "Ain't no sunshine";$var_3 = 'Ain\'t no sunshine';$var_3 = "this hasmultiplelines";
PHP
Python
var_1 = 'Thunderstruck'var_2 = "Ain't no sunshine"var_3 = 'Ain\'t no sunshine'var_3 = """this hasmultiplelines"""
print ('Thunderstruck');echo 'Thunderstruck';
PHP
print ('Thunderstruck'); # python 3.xprint 'Thunderstruck'; # python 2.x
Python
String formatting (examples)
>>> "Hello %s %s" % ("Glenn", "De Backer")'Hello Glenn De Backer'
C syntax
>>> "Hello {0}, {1}".format("Glenn", "De Backer")'Hello Glenn, De Backer’
>>> "Hello {firstname}, {name}".format(firstname="Glenn", name="De Backer")'Hello Glenn, De Backer'
Advanced string formatting (PEP 3101) (PEP = Python Enhancement Proposals)
SlicesStrings are a sequence of characters
A subsequence of a sequence is called a slice
The operation that extracts a subsequence is called slicing
Notation Descriptiona[start:end] items start through end-1
a[start:] items start through the rest of the arraya[:end] items from the beginning through end-1
a[:] a copy of the whole arraya[start:end:step] start through not past end, by step
Slicesa[-1] # last item in the arraya[-2:] # last two items in the arraya[:-2] # everything except the last two items
FROM HTTP://WWW.NLTK.ORG/BOOK/CH03.HTML
NoneNone is the pythonic way of defining NULL.
Evaluates to False
Is an object (NoneType)
Because it is an object, we cannot use it to check if a variable exist.
None (example)
db_con = None # Try to connecttry: db_con = MysqlDB(db_host, db_user, db_password, db_database) db_con = database.connect()except DatabaseException: pass if db_con is None: print('Could not connect')else: # do dbase stuff
BooleansSimple same as in PHP but case sensitive!
True
False
1
0
Booleans (examples)$a = True;$b = FALSE;
if ($a === true) { echo "Party!"; }
PHP
a = Trueb = False
if a is True:print “party"
if a == True:print "party"
Python
SequencesDifficult to compare as PHP only has associative arrays ( hashmap )
List: is just a list of items
Tuples: are like lists but you cannot change their values.
months
blood types
…
Dictionary: hashmap / associative arrays
Also supports slices and slicing
List (example 1/2)>>> mylist = []
>>> mylist.append(123)>>> mylist.append('dxsolutions')>>> mylist.append(2)>>> print mylist[123, ‘dxsolutions’, 2]
>>> mylist.sort()>>> print mylist[2, 123, ‘dxsolutions']
>>> mylist.reverse()>>> print mylist['dxsolutions', 123, 2]
List (example 2/2)
>>> mylist.pop()2>>> print mylist['dxsolutions', 123]
>>> mylist.extend([1,2,3])>>> print mylist['dxsolutions', 123, 1, 2, 3]
>>> mylist.remove(2)>>> print mylist['dxsolutions', 123, 1, 3]
Tuples (example)>>> days = (‘monday’,'tuesday','wednesday','thursday','friday','saterday','sunday')
>>> days[2]'wednesday'
>>> days[2:]('wednesday', 'thursday', 'friday', 'saterday', 'sunday')
>>> days[:3]('monday', 'tuesday', ‘wednesday')
>>> days[0:2]('monday', 'tuesday')
Dictionaries
person = {'Name': 'Tom', 'Age': 27};
print person['Name']; # Tomprint person['Age']; # 27
Python
$person = array('Name' => 'Tom', 'Age' => 27);
print $person['Name']; print $person['Age'];
PHP
Membership operators
Notation Description
in Evaluates to true if in sequence
not in Evaluates to true if not in sequence
Python has membership operators, which test for membership in a sequence, such as strings, lists, or tuples
Membership operators (example)
>>> a = (1,2,4,8)>>> 1 in aTrue>>> 3 not in aTrue>>> 3 in aFalse
>>> word = "boat">>> 'e' in wordFalse>>> 'a' in wordTrue
Add / multiply operators and sequences>>> a = [ 1, 2 ]>>> b = [ 3, 4 ]
>>> a + b[1, 2, 3, 4]
>>> a * 4[1, 2, 1, 2, 1, 2, 1, 2] >>> a = "hello ">>> b = "world"
>>> a + b'hello world'
>>> a * 4'hello hello hello hello '
Whitespace - indentationInstead of using curly braces ( { ) to delimit program blocks, Python uses indentation
It is mandatory, no way around it
It is a very controversial feature that some really hate…
… but it does improve readability…
… and after a while you totally forget about it.
Conditional: if…else…el(se)if (example)
if (statement) { // do stuff} elseif (other_statement) {
// do other stuff} else { // do other stuff}
PHP
if (statement): # do stuffelif (other_statement): # do other stuffelse: # do other stuff
Python
Iterations: for loopPython for statement has a lot in common with PHP foreach
Supports break and continue which works more or less the same as in PHP
You can loop over strings, lists, dictionaries, … as they are sequences.
Iterations: for loop (example)$words = array('cat', 'window', 'door');
foreach ($words as $word) { echo $word;}
PHP
words = ['cat', 'window', 'door']
for word in words: print word>>> cat, window, door
for word in words[1:3]: print word>>> window, door
Python
Iterations: for loop (example)$persons = array('name' => 'glenn', 'job' => 'developer');
foreach ($persons as $key => $value) { // process person}
PHP
persons = {'name': 'glenn', 'job': 'developer'}
for key in persons.keys():# process key
for value in persons.values():# process value
for key, value in persons.items(): # process value
Python
Iterations: rangeIf you do need to iterate over a sequence of numbers, you can use the range() method.
You have also xrange:
if you do range(1, 10000) it will create a list of 10000 elements in memory
when using xrange you create a sequence which evaluates lazy. This is faster and uses less memory.
In Python 3.x range() -> xrange()
Iterations: range (example)// array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)$arr = range(1,10);
// array(1, 2, 3, 4, 5, 6,)foreach (range(1, 6) as $number) { echo $number;}
PHP
>>> range(10) # python 2.x>>> list(range(10)) # python 3.x[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for number in range(1,6): print number>>> 1, 2, 3, 4, 5
Python
Iterations: enumerate (example)
>>> # bad example!>>> words = ['Mary', 'had', 'a', 'little', 'lamb']>>> for i in range(len(words)): print i, words[i]
Bad
>>> # if you need indices use enumerate>>> words = ['Mary', 'had', 'a', 'little', 'lamb']>>> for index, value in enumerate(words): print index, value
Good
For example: when you want index -> value from a list.
FunctionsFunction blocks begin with the keyword def followed by the function name and parentheses (( ))
The code block within every function starts with a colon (:) and is indented.
Functions can have docstring. Accessible through function.__doc__ or help(function)
Functions (example)function hello() { echo "hello world";}
PHP
def hello():"Prints hello world" echo "hello world"
>>> help(hello)Help on function hello in module __main__:
hello() Prints hello world
Python
Function argumentsYou can call a function by using the following types of formal arguments:
Required arguments
Default arguments
Keyword arguments
Variable-length arguments (Variadic function)
PHP >= 5.6 splat operator (…)
Like PHP it doesn’t support function overloading
Required argument (example)
>>> def hello(name): print "hello" + name
>>> hello("glenn")glenn
Python
function hello($name) { echo "hello" . $name;}
hello("glenn");
PHP
Required argument (example)
>>> def hello(name): print "hello" + name
>>> hello()Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: hello() takes exactly 1 argument (0 given)
Default argument (example)
>>> def hello(name="glenn"): print "hello" + name
>>> hello()hello glenn
Python
function hello($name="glenn") { echo “hello” . $name;}
hello();>>> hello glenn
PHP
Keyword argument (example)
>>> def sum(a=1, b=2): print a + b >>> sum()3
>>> sum(a=5)7
>>> sum(b=4)5
>>> sum(a=2, b=4)6
Python
( There isn’t a PHP equivalent )
Variable length argument (example)
def manyArgs(*arg): print "I was called with", len(arg), "arguments:", arg
>>> manyArgs(1)I was called with 1 arguments: (1,)>>> manyArgs(1, 2, 3)I was called with 3 arguments: (1, 2, 3)
Python
function manyArgs(...$arg) { echo "I was called with " . count($arg) . " arguments: " \implode($arg);
}
hello(1); // I was called with 1 arguments: 1hello(1, 2, 3); // I was called with 3 arguments: 1,2,3
PHP >= 5.6 using the . . . (splat) operator
ClassesIn Python everything is an object (again)
Class blocks begin with the keyword class followed by the class name and a colon (:)
Doesn’t have private / public concept
There is a convention that is followed by most Python code: a name prefixed with an underscore (e.g. _spam) should be treated as a non-public…
…but it is still accessible
Classes can also have docstring.
Classes (example)
class Employee:
def __init__(self, name, salary): self.name = name self.salary = salary
e = Employee("mike", "1500")
Python
class Employee { function __construct($name, $salary) {
$this->name = $name;$this->salary = $salary;
}}
$e = new Employee("mike", "1500");
PHP
Classes: inheritanceSupports multiple inheritance (PHP lacks that)
Method overloading works the same as in PHP
You can (optionally) make your base class inherit from the class object. Matter of style.
Classes: inheritance (example)
class Vehicle {// vehicle methods and members
}
class Car extends Vehicle {// car methods and members
}
PHP
class Vehicle:# vehicle methods and members
class Car(Vehicle):# car methods and members
Python
Classes: overloading 1/2 (example)
class Parent(object): def __init__(self): self.value = 5
def get_value(self): return self.value
class Child(Parent): pass # is a null operation
>>> c = Child()>>> c.get_value()5
Classes: overloading 2/2 (example)
class Parent(object): def __init__(self):
self.value = 5
def get_value(self): return self.value
class Child(Parent):
def get_value(self): return self.value + 1
>>> c = Child()>>> c.get_value()6
__init__ /__keyword__The __keyword__ are also called dunder methods (thunder in West Flemish or double under)
They are also sometimes called “magic” methods
They are roughly the same as inheriting things
In the case of __init__ in the background Python will do automatically the calls to init and new
They also make it possible (but are not limited) to change how operators (for example +, / , ..) behave.
from __future__ import division (example)
# in python 2.x if you divide an integer you # will get an integer back>> 1 / 2 0
# In python 2.7 future = Python 3.xfrom __future__ import division
>> 1 / 2 0.5
>> 1 // 2 # you will need the special // division # operator to get an integer back
File I/O (example)
# Reading a filewith open('myfile.txt', 'r') as f: for line in f: print f
# Writing a filewith open('myfile.txt', 'w') as f: f.write('Hello')
Lambda functions# Simple lambda examplef = lambda x, y : x + y>> f(2,4)6
# Map -> lambda (divide by 2)>>> a = [2, 4, 8, 16]>>> map ( lambda x: x/2, a)[1, 2, 4, 8]
# Filter -> lambda (even numbers)>>> a = [1, 2, 3, 4, 5, 6 , 7, 8, 9, 10]>>> filter (lambda x: x % 2 == 0, a)[2, 4, 6, 8, 10]
The proof is in the pudding…
Minimal flask (example)from flask import Flaskapp = Flask(__name__)
@app.route("/") def hello(): return "Hello World!"
@app.route("/name/<name>") def hello(name=None): return “Hello “ + name
if __name__ == "__main__": app.run()
HTTP://FLASK.POCOO.ORG
Minimal scraper 1/2 (example)<div title="buyer-name">Carson Busses</div><span class="item-price">$29.95</span>
HTML
from lxml import htmlimport requests
page = requests.get('http://econpy.pythonanywhere.com/ex/001.html')tree = html.fromstring(page.text)
#This will create a list of buyers:buyers = tree.xpath('//div[@title="buyer-name"]/text()')
#This will create a list of pricesprices = tree.xpath('//span[@class="item-price"]/text()')
print 'Buyers: ', buyersprint 'Prices: ', prices
Python
Minimal scraper 2/2 (example)
Buyers: ['Carson Busses', 'Earl E. Byrd', 'Patty Cakes', 'Derri Anne Connecticut', 'Moe Dess', 'Leda Doggslife', 'Dan Druff', 'Al Fresco', 'Ido Hoe', 'Howie Kisses', 'Len Lease', 'Phil Meup', 'Ira Pent', 'Ben D. Rules', 'Ave Sectomy', 'Gary Shattire', 'Bobbi Soks', 'Sheila Takya', 'Rose Tattoo', 'Moe Tell']
Prices: ['$29.95', '$8.37', '$15.26', '$19.25', '$19.25', '$13.99', '$31.57', '$8.49', '$14.47', '$15.86', '$11.11', '$15.98', '$16.27', '$7.50', '$50.85', '$14.26', '$5.68', '$15.00', '$114.07', '$10.09']
Result
HTTP://DOCS.PYTHON-GUIDE.ORG/EN/LATEST/SCENARIOS/SCRAPE/
Bayesian text classifierfrom sklearn.feature_extraction.text import CountVectorizerfrom sklearn.pipeline import Pipelinefrom sklearn.naive_bayes import MultinomialNBimport numpy
# docsdocs = numpy.array(["Buy viagra", "Hello frank", "The servers are down", "Do you want a rolex", "Cheap airplane tickets"])
# labels 1: spam, 0: hamlabels = numpy.array([1,0,0,1,1])
# pipelinesteps = [('vectorizer', CountVectorizer()), ('clf', MultinomialNB())]
pipe = Pipeline(steps)pipe.fit(docs, labels)
# test datatest_data = numpy.array([ "Hello koen", "Cheap viagra"])
print pipe.predict(test_data)
HTTP://SCIKIT-LEARN.ORG/STABLE/
Automate with fabric# Import Fabric's API modulefrom fabric.api import *
env.hosts = [‘server.domain.tld’, ‘another_server.domain.tld’]
def update_upgrade(): """ Update the default OS installation's basic default tools. """ run("aptitude update") run("aptitude -y upgrade")
def install_memcached(): """ Download and install memcached. """ run("aptitude install -y memcached")
def update_install(): # Update update_upgrade()
# Install install_memcached()
HTTP://WWW.FABFILE.ORG/
Some interesting resourcesDive into python -http://www.diveintopython.net/
The standard python library - http://effbot.org/zone/librarybook-index.htm
How to think like a computer scientist with python - http://www.greenteapress.com/thinkpython/thinkCSpy.pdf
PyVideo (indexes a lot of python talks) - http://pyvideo.org/
80 best python resources - http://www.fromdev.com/2014/03/python-tutorials-resources.html
10 myths of enterprise python - https://www.paypal-engineering.com/2014/12/10/10-myths-of-enterprise-python/
Python success stories - https://www.python.org/about/success/
Thank you for listening…(any questions ?)