python basics




quick introduction to the python language



© Copyright 2013

Rafael L Martins <rafael84@gmail.com>

data types


  • int, long, float
  • str, unicode
  • lists
  • tuples
  • dictionaries

INT, LONG, FLOAT


# integer division
>>> x = 144
>>> y = 7
>>> x / y
20

# float division
>>> w = 124.5
>>> t = 3
>>> w / t
41.5
# float division (truncate)
>>> w = 124.5
>>> t = 3
>>> w // t
41.0

# type casting
>>> w = 124.5
>>> t = 3
>>> int(w / t)
41

INT, LONG, FLOAT


# long division
>>> k = 23L
>>> j = 7
>>> k / j
3L

# long modulus
>>> b = 15L
>>> m = 5L
>>> b % m
0L
# long exponentiation
>>> p = 2L
>>> q = 3L
>>> p ** q
8L

str, unicode


# str
>>> s = 'João'
>>> type(s)
str
>>> print(s)
João
>>> repr(s)
"'Jo\\xc3\\xa3o'"     
# unicode
>>> s = u'João'
>>> type(s)
unicode
>>> print(s)
João
>>> repr(s)
"u'Jo\\xe3o'"

>>> s = unicode('João')     
>>> type(s)
unicode
# raw
>>> s = '\nA\n'
>>> print(s)

A

>>> s = r'\nA\n'
>>> print(s)
\nA\n

lists


>>> e = []
>>> type(e)
list

>>> f = [2,3] + [4+5]     
>>> print(f)
[2, 3, 9]

>>> f[0] = 1
>>> print(f)
[1, 3, 9]
>>> h = [0, 1] * 3
[0, 1, 0, 1, 0, 1]

>>> h.count(0)               
3

>>> h.sort()
>>> print(h)
[0, 0, 0, 1, 1, 1]   
>>> h = range(5)
>>> print(h)
[0, 1, 2, 3, 4]

>>> h = range(3)
>>> h.reverse()
>>> print(h)
[2, 1, 0]

>>> h.index(0)
2

tUples


>>> r = ('a', 1, 3.14, None)
print r[0]
'a'

>>> type(r[1])
int

>>> r[2] = 'x'
TypeError: 'tuple' object does not support item assignment

tuples


>>> d = tuple([1, 2, 3])
>>> print(d)
(1, 2, 3)

>>> d.index(9)
ValueError: tuple.index(x): x not in tuple

>>> char, number, pi, null = r
>>> print(pi, null)
(3.14, None)

dictionaries


>>> v = {}
>>> v['w'] = 'R'
>>> v[0] = 100
>>> v[None] = 1.99
>>> print(v)
{0: 100, None: 1.99, 'w': 'R'}

>>> o = dict(a=123, b='456', c=99L)
>>> print(o)
{'a': 123, 'b': '456', 'c': 99L}

dictionaries


>>> o = {'a': 123, 'b': '456', 'c': 99L}
>>> o.items()
[('a', 123), ('c', 99L), ('b', '456')]

>>> o.keys()
['a', 'c', 'b']

>>> o.values()
[123, 99L, '456']

>>> print(o.get(555, 'not found'))
not found

dictionaries


>>> o = dict(a=1, b=2, c=3)
>>> o.has_key(a)
NameError: name 'a' is not defined

>>> o.has_key('a')
True

>>> da = dict(a=1)
>>> db = dict(b=2)
>>> dc = dict(da.items() + db.items())
>>> print(dc)
{'a': 1, 'b': 2}

BASIC commands


  • if ... elif ... else
  • while, break, continue
  • for ... in ... else
  • pass
  • TRY ... EXCEPT ... ELSE ... FINALLY
  • DEF

IF ... ELIF ... ELSE


# basic_commands/001_if_elif_else.py

import datetime                                                                

today = datetime.date.today()

day = today.day

if day in range(1, 10):
    print('give me my payment!')

elif day == 11:
    print('out of money')

else:
    print('oh my God!')

WHILE, break, continue

# basic_commands/002_while_break_continue.py

import random

places_to_eat = [
    'eskilos', 'cristovao', 'japanese', 'sativa', 'portuguese',
]

option = None

counter = 0
while option != 'eskilos':
    option = random.choice(places_to_eat)
    if option == 'eskilos':
        break
    counter += 1
    if option == 'portuguese':
        print 'Are you crazy? "Portuguese" is not a valid option!'
        continue
    print('Thinking of %s...' % option)

print('After {0} tries, you chose {1}.'.format(counter, option))
print('Good choice!')

FOR ... IN ... ELSE


# basic_commands/003_for_in_else.py

import random

numbers = []
for x in range(10):
    numbers.append(random.randint(-3, 20))

for number in numbers:
    print 'Checking number: %d' % number
    if number < 0:
        break
else:
    print 'You are lucky. All numbers are positive.'

PASS


# basic_commands/004_pass.py

def work_less_more_money():
    return 'OF COURSE!'


def borrow_some_money():
    pass


print 'Q: Less work, more money?'
print 'A: %s' % work_less_more_money()

print

print 'Q: I have no money, could you borrow me some?'
print 'A: %s' % borrow_some_money()

TRY ... EXCEPT ... ELSE ... FINALLY


# basic_commands/005_try_except_else_finally.py

import sys


def cat(filename):
    f = None
    try:
        f = open(filename)
    except IOError:
        print "could not open the file"
    else:
        for line in f:
            print line,
    finally:
        if f:
            f.close()


if len(sys.argv) == 2:
    cat(sys.argv[1])

DEF


# basic_commands/006_def.py

def sum(x, y):
    '''Returns the sum of two numbers'''
    return x + y


print help(sum)
print sum.__doc__

print sum(1, 2)


def welcome(name, greeting='hello'):
    print '%s %s, welcome!' % (greeting, name)


welcome('Peter')
welcome('Maria', 'hi there')

CLASSES


  • CLASS AND INHERITANCE
  • METHOD, SELF, SUPER
  • SPECIAL METHODS and attributes
  • PROPERTIES

CLASS AND INHERITANCE

# classes/007_class.py

class Stack:
    def __init__(self):
        self.items = []

    def push(self, item):
        self.items.append(item)

    def pop(self):
        x = self.items[-1]
        del self.items[-1]
        return x

    def empty(self):
        return len(self.items) == 0

stack = Stack()
for element in range(1, 10):
    stack.push(element)

while not stack.empty():
    print stack.pop()

class and inheritance

# classes/008_inheritance.py

class Hero:
    def __init__(self, name):
        self.name = name

class Cyclops(Hero):
    def optic_blast(self):
        print '%s is using optic blast...' % self.name

class Flash(Hero):
    def move_super_fast(self):
        print '%s is moving super fast...' % self.name

class SuperMan(Cyclops, Flash):
    def fly(self):
        print '%s is flying like a bird...' % self.name

hero = SuperMan('Clark Kent')
hero.optic_blast()
hero.move_super_fast()
hero.fly()

METHOD, SELF, SUPER

# classes/009_method_self_super.py

class Todo(object):
    def __init__(self, description, completed):
        self.description = description
        self.completed = completed
    def __str__(self):
        done = 'X' if self.completed else ' '
        return '[%s] %s' % (done, self.description)

class FancyTodo(Todo):
    def __str__(self):
        s = super(FancyTodo, self).__str__()
        return '%s\n%s\n%s' % ('=' * len(s), s, '-' * len(s))

todoList = []
todoList.append(Todo('Buy some coffee', True))
todoList.append(Todo('Make a lot of coffee', False))
todoList.append(Todo('Drink much more coffee', False))
todoList.append(FancyTodo('Lose weight', True))
todoList.append(FancyTodo('Eat less bacon', False))

for todo in todoList: print todo

SPECIAL METHODS and attributes

# classes/010_special_methods.py

def explore(obj):
    cls = obj.__class__
    name = cls.__name__
    members = cls.__dict__.items()

    print 'class %s(object):' % name
    for name, value in members:
        if not name.startswith('__'):
            if hasattr(value, '__call__'):
                print '\tdef %s(): pass' % name
            else:
                print '\t%s = %s' % (name, value)

class Foo(object):
    bar = 123
    xpto = 'abc'

    def baz(self):
        pass

explore(Foo())

PROPERTIES

# classes/011_properties.py

class Person(object):
    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name

    @property
    def name(self):
        return '%s %s' % (self.first_name, self.last_name)

    @name.setter
    def name(self, value):
        s = value.split()
        self.first_name = s[0]
        self.last_name = ' '.join(s[1:])


john = Person('John', 'Smith')
print john.name

john.name = 'John Brown Smith'
print john.name

MODULES


  • PACKAGEs and modules
  • IMPORT AND FROM ... IMPORT
  • python path

PACKAGEs and modules


Sample structure

├── pkg1
│   ├── __init__.py       # special module that makes pkg1 a package
│   └── subpkg1
│       └── __init__.py   # special module that makes subpkg1 a package
└── pkg2
    ├── __init__.py       # special module that makes pkg2 a package
    ├── subpkg1
    │   ├── __init__.py   # special module that makes subpkg1 a package
    │   ├── module1.py    # a normal module
    │   └── module2.py    # another normal module
    └── subpkg2
        └── __init__.py   # makes subpkg2 a package


Each module contains

print "module: %s" % __name__

import and FROM ... IMPORT


SAMPLE IMPORTS USING THE PREVIOUS STRUCTURE

$ python -c 'import pkg1'
module: pkg1


$ python -c 'import pkg1.subpkg1'
module: pkg1
module: pkg1.subpkg1


$ python -c 'import pkg2.subpkg1.module2'
module: pkg2
module: pkg2.subpkg1
module: pkg2.subpkg1.module2


$ python -c 'from pkg2.subpkg1 import module2'
module: pkg2
module: pkg2.subpkg1
module: pkg2.subpkg2.module2

PYTHON PATH


CHECKING THE PYTHONPATH

$ python -c 'import sys; from pprint import pprint; pprint(sys.path)'

['',
 '/home/you/.virtualenvs/pyintro/local/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg',
 '/home/you/.virtualenvs/pyintro/local/lib/python2.7/site-packages/pip-1.2.1-py2.7.egg',
 '/home/you/.virtualenvs/pyintro/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg',
 '/home/you/.virtualenvs/pyintro/lib/python2.7/site-packages/pip-1.2.1-py2.7.egg',
 '/home/you/.virtualenvs/pyintro/lib/python2.7',
 '/home/you/.virtualenvs/pyintro/lib/python2.7/plat-linux2',
 '/home/you/.virtualenvs/pyintro/lib/python2.7/lib-tk',
 '/home/you/.virtualenvs/pyintro/lib/python2.7/lib-old',
 '/home/you/.virtualenvs/pyintro/lib/python2.7/lib-dynload',
 '/usr/lib/python2.7',
 '/usr/lib/python2.7/plat-linux2',
 '/usr/lib/python2.7/lib-tk',
 '/home/you/.virtualenvs/pyintro/local/lib/python2.7/site-packages',
 '/home/you/.virtualenvs/pyintro/lib/python2.7/site-packages']

PYTHONPATH

Sample project struture

├── admin
│   ├── __init__.py
│   ├── models.py
│   └── views.py
└── main.py

main.py

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import sys
import os

from admin.models import MyModel
from admin.views import MyView

extra topics


  • slice notation
  • list comprehension
  • PACKING AND UNPACKING
  • with statement
  • iterators and generators
  • UNIT TESTING

SLICE notation


# extra_topics/012_slice_notation.py

#  +---+---+---+---+---+---+---+---+---+---+---+
#  | H | e | l | l | o |   | W | o | r | l | d |
#  +---+---+---+---+---+---+---+---+---+---+---+
#    0   1   2   3   4   5   6   7   8   9  10   # offset from start
#  -11 -10  -9  -8  -7  -6  -5  -4  -3  -2  -1   # offset from end

s = 'Hello World'

print s[0]          # H
print s[-11]        # H
print s[1]          # e

print s[-1]         # d
print s[-2]         # l

print s[0:5]        # Hello
print s[6:]         # World
print s[:-6]        # Hello

print s[::-1]       # dlroW olleH

LIST COMPREHENSION

# extra_topics/013_list_comprehension.py

squares = []
for x in range(10):
    squares.append(x ** 2)
print squares

# OR

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

# extra_topics/014_list_comprehension_if.py

numbers = [-3, 8, 56, -77, 100, -1, 5]
print 'All: %s' % numbers

positive = [number for number in numbers if number > 0]
print 'Positive: %s' % positive

negative = [number for number in numbers if number < 0]
print 'Negative: %s' % negative

PACKING AND UNPACKING

# extra_topics/015_packing_and_unpacking_args.py

def extract_positive(*numbers):
    return [number for number in numbers if number > 0]

def sum_all(*numbers):
    total = 0
    for number in numbers: total += number
    return total

def sum_all_positive(*numbers):
    positive = extract_positive(*numbers)
    return sum_all(*positive)

print extract_positive(-1, -2, -3, 10, 20, 30)
print sum_all(-1, -2, -3, 10, 20, 30)
print sum_all_positive(-1, -2, -3, 10, 20, 30)
# extra_topics/016_packing_and_unpacking_kwargs.py

def print_params(*args, **kwargs):
    print '%s: %s' % (type(args), args)
    print '%s: %s' % (type(kwargs), kwargs)

print_params(1, 2, 3, foo='a', bar='2')

WITH STATEMENT


# extra_topics/017_with_statement.py

import time


class Timer:
    def __enter__(self):
        self.time = time.time()
        print 'Processing...'

    def __exit__(self, type, value, traceback):
        ellapsed = time.time() - self.time
        print 'Done in %s' % ellapsed

with Timer():
    for x in range(100000000L):
        pass

iterators and GENERATORs

# extra_topics/018_iterator.py

a = iter(range(10))
print 'iterator has next: %s' % hasattr(a, 'next')

print a.next()  # 0
print a.next()  # 1
print a.next()  # 2

for n in a:
    print n  # calls a.next(), from 3 to 9

b = [100, 200, 300, 400, 500]
print 'list has an iterator: %s' % hasattr(b, '__iter__')

b_iter = b.__iter__()
print 'type of list iterator: %s' % type(b_iter)

print 'list iterator has next: %s' % hasattr(b_iter, 'next')

print b_iter.next()  # 100
print b_iter.next()  # 200
print b_iter.next()  # 300
print b_iter.next()  # 400

iterators and generators

# extra_topics/019_generator_expression.py

g = (x ** x for x in range(5))

print 'type of g: %s' % type(g)

print 'g has next: %s' % hasattr(g, 'next')

print g.next()  # 0**0 = 1
print g.next()  # 1**1 = 1
print g.next()  # 2**2 = 4
print g.next()  # 3**3 = 9

print 'generator has an iterator: %s' % hasattr(g, '__iter__')

g_iter = g.__iter__()
print 'type of generator iterator: %s' % type(g_iter)

print 'generator iterator has next: %s' % hasattr(g_iter, 'next')

print g_iter.next()  # 4**4 = 256

iterators and generators

# extra_topics/020_yield.py

import random


def random_generator(n):
    c = 0
    print 'before while'
    while c < n:
        print '\tbefore yield'
        yield random.randint(1, 1000)
        print '\tafter yield'
        c += 1
    print 'after while'

print 'type of random_generator: %s' % type(random_generator)

rg3 = random_generator(3)
print 'type of random_generator(3): %s' % type(rg3)

for r in rg3:
    print '\t\tinside for-loop: %s' % r

UNIT TESTING

# extra_topics/unit_testing/calc.py
    
class Calculator(object):
    def sum(self, x, y):
        return x + y


# extra_topics/unit_testing/test_calc.py

import unittest
import calc


class TestCalc(unittest.TestCase):

    def setUp(self):
        self.calc = calc.Calculator()

    def test_sum(self):
        expected = 7
        got = self.calc.sum(2, 5)
        self.assertEqual(expected, got, '2 + 5 should be equal to 7')

unit testing

$ python -m unittest test_calc

.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
$ python -m unittest -v test_calc
    
test_sum (test_calc.TestCalc) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
$ python -m unittest -v test_calc.TestCalc.test_sum

test_sum (test_calc.TestCalc) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK





THANK YOU!

python basics

By Rafael L Martins

python basics

  • 1,005