Python Cookbook

Download as pdf or txt
Download as pdf or txt
You are on page 1of 15

Python Programming Cookbook i

Python Programming Cookbook


Python Programming Cookbook ii

Contents

1 CSV Reader / Writer Example 1


1.1 The Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Reading and writing dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3 Download the Code Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2 Decorator Tutorial 7
2.1 Understanding Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2 Jumping into decorators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.3 The Practice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4 Download the Code Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3 Threading / Concurrency Example 15


3.1 Python _thread module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.2 Python threading module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2.1 Extending Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2.2 Getting Current Thread Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.2.3 Daemon Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.2.4 Joining Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.2.5 Time Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.2.6 Events: Communication Between Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.2.7 Locking Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.2.8 Limiting Concurrent Access to Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.2.9 Thread-Specific Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

4 Logging Example 31
4.1 The Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.1.1 Log Levels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.1.2 Handlers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.1.3 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.2 The Practice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.3 Download the Code Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Python Programming Cookbook iii

5 Django Tutorial 40
5.1 Creating the project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.2 Creating our application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.3 Database Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.4 The Public Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5.5 Style Sheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.6 Download the Code Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

6 Dictionary Example 50
6.1 Define . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
6.2 Read . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
6.3 Write . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
6.4 Useful operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
6.4.1 In (keyword) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.4.2 Len (built-in function) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.4.3 keys() and values() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
6.4.4 items() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.4.5 update() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
6.4.6 copy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
6.5 Download the Code Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

7 Sockets Example 58
7.1 Creating a Socket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
7.2 Using a Socket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
7.3 Disconnecting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
7.4 A Little Example Here . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
7.5 Non-blocking Sockets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
7.6 Download the Code Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

8 Map Example 64
8.1 Map Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
8.2 Pythons Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
8.3 Map Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
8.4 Download the Code Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

9 Subprocess Example 70
9.1 Convenience Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
9.1.1 subprocess.call . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
9.1.2 subprocess.check_call . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
9.1.3 subprocess.check_output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
9.2 Popen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
9.3 Download the Code Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Python Programming Cookbook iv

10 Send Email Example 75


10.1 The Basics of smtplib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
10.2 SSL and Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
10.3 Sending HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
10.4 Sending Attachments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
10.5 Download the Code Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Python Programming Cookbook v

Copyright (c) Exelixis Media P.C., 2016

All rights reserved. Without limiting the rights under


copyright reserved above, no part of this publication
may be reproduced, stored or introduced into a retrieval system, or
transmitted, in any form or by any means (electronic, mechanical,
photocopying, recording or otherwise), without the prior written
permission of the copyright owner.
Python Programming Cookbook vi

Preface

Python is a widely used high-level, general-purpose, interpreted, dynamic programming language. Its design philosophy empha-
sizes code readability, and its syntax allows programmers to express concepts in fewer lines of code than would be possible in
languages such as C++ or Java. The language provides constructs intended to enable clear programs on both a small and large
scale.
Python supports multiple programming paradigms, including object-oriented, imperative and functional programming or proce-
dural styles. It features a dynamic type system and automatic memory management and has a large and comprehensive standard
library. (Source: https://en.wikipedia.org/wiki/Python_%28programming_language%29)
In this ebook, we provide a compilation of Python examples that will help you kick-start your own projects. We cover a wide
range of topics, from multi-threaded programming to web development with Django. With our straightforward tutorials, you will
be able to get your own projects up and running in minimum time.
Python Programming Cookbook vii

About the Author

Sebastian is a full stack programmer, who has strong experience in Java and Scala enterprise web applications.
He is currently studying Computers Science in UBA (University of Buenos Aires) and working a full time job at a .com company
as a Semi-Senior developer, involving architectural design, implementation and monitoring.
He also worked in automating processes (such as data base backups, building, deploying and monitoring applications).
Python Programming Cookbook 1 / 80

Chapter 1

CSV Reader / Writer Example

CSV (comma-separated values) is a standard for exporting and importing data across multiple formats, such as MySQL and
excel.
It stores numbers and text in plain text. Each row of the file is a data record and every record consists of one or more fields which
values are separated by commas. The use of the comma to separate every records fields is the source of the name given to this
standard.
Even with this very explicit name, there is no official standard CSVs, and it may denote some very similar delimiter-separated
values, which use a variety of field delimiters (such as spaces and tabs, which are both very popular), and are given the .csv
extension anyway. Such lack of strict terminology makes data exchange very difficult some times.
RFC 4180 provides some rules to this format:

Its plain text


Consists of records
Every record consists of fields separated by a single character delimiter
Every record has the same sequence of fields

But unless there is additional information about the provided file (such as if the rules provided by RFC were followed), data
exchange through this format can be pretty annoying.

1.1 The Basics

Python has native support for CSV readers, and its configurable (which, as weve seen, is necessary). There is a module csv
which holds everything you need to make a CSV reader/writer, and it follows RFC standards (unless your configuration overrides
them), so by default it should read and write valid CSV files. So, lets see how it works:
csv-reader.py
import csv
with open(my.csv, r+, newline=) as csv_file:
reader = csv.reader(csv_file)
for row in reader:
print(str(row))

Here, we are importing csv and opening a file called my.csv, then we call csv.reader passing our file as a parameter and then we
print each row in our reader.
If my.csv looks like this:
my.csv
Python Programming Cookbook 2 / 80

my first column,my second column,my third column


my first column 2,my second column 2,my third column 2

Then, when you run this script, you will see the following output:
[my first column, my second column, my third column]
[my first column 2, my second column 2, my third column 2]

And writing is just as simple as reading:


csv-reader.py
import csv
rows = [[1, 2, 3], [4, 5, 6]]
with open(my.csv, w+, newline=) as csv_file:
writer = csv.writer(csv_file)
for row in rows:
writer.writerow(row)

with open(my.csv, r+, newline=) as csv_file:


reader = csv.reader(csv_file)
for row in reader:
print(str(row))

Then, in your csv file youll see:


my.csv
1,2,3
4,5,6

And in your output:


[1, 2, 3]
[4, 5, 6]

Its pretty easy to see what is going on in here. We are opening a file in write mode, getting our writer from csv giving our file to
it, and writing each row with it. Making it a little smarter:
csv-reader.py
import csv

def read(file_location):
with open(file_location, r+, newline=) as csv_file:
reader = csv.reader(csv_file)
return [row for row in reader]

def write(file_location, rows):


with open(file_location, w+, newline=) as csv_file:
writer = csv.writer(csv_file)
for row in rows:
writer.writerow(row)

def raw_test():
columns = int(input("How many columns do you want to write? "))
input_rows = []
keep_going = True
while keep_going:
Python Programming Cookbook 3 / 80

input_rows.append([input("column {}: ".format(i + 1)) for i in range(0, columns)])


ui_keep_going = input("continue? (y/N): ")
if ui_keep_going != "y":
keep_going = False

print(str(input_rows))

write(raw.csv, input_rows)
written_value = read(raw.csv)
print(str(written_value))

raw_test()

We ask the user how many columns does he want to write for each row and then ask him for a row as long as he wants to continue,
then we print our raw input and write it to a file called raw.csv, then we read it again and print the data. When we run our script,
the output will look like this:
How many columns do you want to write? 3
column 1: row 1, column 1
column 2: row 1, column 2
column 3: row 1, column 3
continue? (y/N): y
column 1: row 2, column 1
column 2: row 2, column 2
column 3: row 3, column 3
continue? (y/N):
[[row 1, column 1, row 1, column 2, row 1, column 3], [row 2, column 1, row 2, -
column 2, row 3, column 3]]
[[row 1, column 1, row 1, column 2, row 1, column 3], [row 2, column 1, row 2, -
column 2, row 3, column 3]]

Process finished with exit code 0

And, of course, our raw.csv looks like this:


raw.csv
"row 1, column 1","row 1, column 2","row 1, column 3"
"row 2, column 1","row 2, column 2","row 3, column 3"

Another rule the CSV format has, is the quote character. As you see, every input has a comma, which is our separator character, so
the writer puts them between quoting marks (the default of the standard) to know that commas between them are not separators,
but part of the column instead.
Now, although I would recommend leaving the configuration with its defaults, there are some cases where you need to change
them, as you dont always have control over the csvs your data providers give you. So, I have to teach you how to do it (beware,
great powers come with great responsibilities).
You can configure the delimiter and the quote character through delimiter and quotechar parameters, like this:
csv-reader.py
import csv

def read(file_location):
with open(file_location, r+, newline=) as csv_file:
reader = csv.reader(csv_file, delimiter= , quotechar=|)
return [row for row in reader]

def write(file_location, rows):


with open(file_location, w+, newline=) as csv_file:
Python Programming Cookbook 4 / 80

writer = csv.writer(csv_file, delimiter= , quotechar=|)


for row in rows:
writer.writerow(row)

def raw_test():
columns = int(input("How many columns do you want to write? "))
input_rows = []
keep_going = True
while keep_going:
input_rows.append([input("column {}: ".format(i + 1)) for i in range(0, columns)])
ui_keep_going = input("continue? (y/N): ")
if ui_keep_going != "y":
keep_going = False

print(str(input_rows))

write(raw.csv, input_rows)
written_value = read(raw.csv)
print(str(written_value))

raw_test()

So, now, having this console output:


How many columns do you want to write? 3
column 1: row 1 column 1
column 2: row 1 column 2
column 3: row 1 column 3
continue? (y/N): y
column 1: row 2 column 1
column 2: row 2 column 2
column 3: row 2 column 3
continue? (y/N):
[[row 1 column 1, row 1 column 2, row 1 column 3], [row 2 column 1, row 2 column 2 -
, row 2 column 3]]
[[row 1 column 1, row 1 column 2, row 1 column 3], [row 2 column 1, row 2 column 2 -
, row 2 column 3]]

Our raw.csv will like like this:


raw.csv
|row 1 column 1| |row 1 column 2| |row 1 column 3|
|row 2 column 1| |row 2 column 2| |row 2 column 3|

As you see, our new separator is the space character, and our quote character is pipe, which our writer is forced to use always as
the space character is pretty common in almost every text data.
The writers quoting strategy is also configurable, the values available are:

csv.QUOTE_ALL: quotes every column, it doesnt matter if they contain a delimiter character or not.
csv.QUOTE_MINIMAL: quotes only the columns which contains a delimiter character.

csv.QUOTE_NONNUMERIC: quotes all non numeric columns.


csv.QUOTE_NONE: quotes nothing. It forces you to check whether or not the user inputs a delimiter character in a column,
if you dont, you will read an unexpected number of columns.
Python Programming Cookbook 5 / 80

1.2 Reading and writing dictionaries

Weve seen a very basic example of how to read and write data from a CSV file, but in real life, we dont want our CSVs to be
so chaotic, we need them to give us information about what meaning has each of the columns.
Also, en real life we dont usually have our data in arrays, we have business models and we need them to be very descriptive. We
usually use dictionaries for this purpose, and python gives us the tools to write and read dictionaries from CSV files.
It looks like this:
import csv

dictionaries = [{age: 30, name: John, last_name: Doe}, {age: 30, name: -
Jane, last_name: Doe}]
with open(my.csv, w+) as csv_file:
headers = [k for k in dictionaries[0]]
writer = csv.DictWriter(csv_file, fieldnames=headers)
writer.writeheader()
for dictionary in dictionaries:
writer.writerow(dictionary)

with open(my.csv, r+) as csv_file:


reader = csv.DictReader(csv_file)
print(str([row for row in reader]))

We are initializing a variable called dictionaries with an array of test data, then we open a file in write mode, we collect
the keys of our dictionary and get a writer of our file with the headers. The first thing we do is write our headers, and then write
a row for every dictionary in our array.
Then we open the same file in read mode, get a reader of that file and print the array of data. You will see an output like:
[{name: John, age: 30, last_name: Doe}, {name: Jane, age: 30, -
last_name: Doe}]

And our csv file will look like:


my.csv
name,last_name,age
John,Doe,30
Jane,Doe,30

Now it looks better. The CSV file has our headers information, and each row has the ordered sequence of our data. Notice that
we give the file names to our writer, as dictionaries in python are not ordered so the writer needs that information to write each
row with the same order.
The same parameters apply for the delimiter and the quote character as the default reader and writer.
So, then again, we make it a little smarter:
csv-reader.py
import csv

def read_dict(file_location):
with open(file_location, r+) as csv_file:
reader = csv.DictReader(csv_file)
print(str([row for row in reader]))
return [row for row in reader]

def write_dict(file_location, dictionaries):


with open(file_location, w+) as csv_file:
Python Programming Cookbook 6 / 80

headers = [k for k in dictionaries[0]]


writer = csv.DictWriter(csv_file, fieldnames=headers)
writer.writeheader()
for dictionary in dictionaries:
writer.writerow(dictionary)

def dict_test():
input_rows = []
keep_going = True
while keep_going:
name = input("Name: ")
last_name = input("Last Name: ")
age = input("Age: ")
input_rows.append({"name": name, "last_name": last_name, "age": age})
ui_keep_going = input("continue? (y/N): ")
if ui_keep_going != "y":
keep_going = False

print(str(input_rows))

write_dict(dict.csv, input_rows)
written_value = read_dict(dict.csv)
print(str(written_value))

dict_test()

And now when we run this script, well see the output:
Name: John
Last Name: Doe
Age: 30
continue? (y/N): y
Name: Jane
Last Name: Doe
Age: 40
continue? (y/N):
[{age: 30, last_name: Doe, name: John}, {age: 40, last_name: Doe, name -
: Jane}]
[{age: 30, last_name: Doe, name: John}, {age: 40, last_name: Doe, name -
: Jane}]

And our dict.csv will look like:


csv-reader.py
age,last_name,name
30,Doe,John
40,Doe,Jane

A little side note: As I said before, dictionaries in python are not ordered, so when you extract the keys from one to write its data
to a CSV file you should order them to have your columns ordered always the same way, as you do not know which technology
will your client use to read them, and, of course, in real life CSV files are incremental, so you are always adding lines to them,
not overriding them. Avoid any trouble making sure your CSV will always look the same.

1.3 Download the Code Project

This was an example on how to read and write data from/to a CSV file.
Download You can download the full source code of this example here: python-csv-reader
Python Programming Cookbook 7 / 80

Chapter 2

Decorator Tutorial

Sometimes, we encounter problems that require us to extend the behavior of a function, but we dont want to change its im-
plementation.Some of those problems could be: logging spent time, caching, validating parameters, etc. All these solutions are
often needed in more than one function: you often need to log the spent time of every http connection; you often need to cache
more than one data base entity; you often need validation in more than one function. Today we will solve these 3 mentioned
problems with Python decorators:

Spent Time Logging: Well decorate a couple functions to tell us how much time do they take to execute.
Caching: Well add cache to prevent a function from executing when its called several times with the same parameters.
Validating: Well validate a functions input to prevent run time errors.

2.1 Understanding Functions

Before we can jump into decorators, we need to understand how functions actually work. In essence, functions are procedures
that return a value based on some given arguments.
def my_function(my_arg):
return my_arg + 1

In Python, functions are first-class objects. This means that functions can be assigned to a variable:
def my_function(foo):
return foo + 1
my_var = my_function
print(str(my_var(1))) # prints "2"

They can be defined inside another functions:


def my_function(foo):
def my_inner_function():
return 1
return foo + my_inner_function()
print(str(my_function(1))) # still prints "2"

They can be passed as parameters (higher-order functions):


def my_function(foo, my_parameter_function):
return foo + my_parameter_function()
def parameter_function(): return 1
print(str(my_function(1, parameter_function))) # still prints "2"

You might also like