Python

The last language you'll need to learn


Justas Trimailovas
VilniusPy 2017-03-15

overview of python's stdlib

Goal

  • walk through quite big python's* stdlib with short stops on more interesting parts of it
  • no need to reinvent the wheel
  • no need for third party dependencies

This is not a comparisson against other programming languages

* python 3.6

Why python is great?


It's general purpose, batteries included, desert island programming language *

* David Beazley: Discovering Python - PyCon 2014

Built-in types


int, float, complex, str, int, tuple, dict, set...

set


collection of distinct hashable objects

set


              
# check if list is from the same elements
len(set(humongous_list)) == 1

# compare dicts.
# symmetric difference,
# if items are equal - returns empty set
set(foo_dict.items()) ^ set(bar_dict.items())
# there are more operations: subset, superset, union, etc.

# set comprehension
{user.profession for user in users}
# {'administrator', 'engineer', 'manager'}
              
            

Text processing services


string, re, difflib, textwrap, readline, rlcompleter, ...

string


              
import secrets
import string

# create string with random letters and digits
symbols = string.ascii_letters + string.digits
random_string = ''.join(secrets.choice(symbols) for i in range(50))
print(random_string)
# ugszGgIRBZ9TduZxtpBDyK0Odp6qHyAxDBmBU7s5xpUPGfHAt4
              
            

textwrap


              import textwrap

s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
textwrap.wrap(s, width=8)
# ['Lorem',
#  'ipsum',
#  'dolor',
#  'sit',
#  'amet, co',
#  'nsectetu',
#  'r adipis',
#  'cing',
#  'elit.']
textwrap.shorten("Hello  world!", width=10)
# 'Hello [...]'
              
            

Data types


datetime, calendar, collections, array, pprint, enum, ...

calendar


              
import calendar

calendar.monthrange(2017, 3)
# March starts on wednesday and has 31 days
# (2, 31)
calendar.day_name[calendar.weekday(2017, 3, 15)]
# 'Wednesday'
calendar.HTMLCalendar(2017, 3)
              
            

collections


namedtuple, OrderedDict, defaultdict, Counter, ...

collections.namedtuple


              
import collections

Point = collections.namedtuple("Point", ["x", "y"])
p = Point(3, 4)

import math

math.sqrt(p.x ** 2 + p.y ** 2)
# 5.0
              
            

collections.defaultdict


              
import collections

s = [('submit', 'create_instance'),
     ('delete', 'notify'),
     ('submit', 'send_email'),
     ('touch', 'scroll'),]
d = collections.defaultdict(list)
for k, v in s:
    d[k].append(v)

sorted(d.items())
# [('delete', ['notify']),
#  ('submit', ['create_instance', 'send_email']),
#  ('touch', ['scroll'])]
              
            

pprint


              
import calendar
import pprint

pprint.pprint(dir(calendar.HTMLCalendar()))
# ['__class__',
#  '__delattr__',
#  '__dict__',
#  '__dir__',
#  ....
#  'firstweekday',
#  'formatday',
#  'formatmonth',
#  ....
#  'yeardayscalendar']
              
            

Numeric and Mathematical modules


numbers, math, cmath, decimal, fractions, random, statistics

statistics


            
import statistics

salaries = [100, 114, 180, 200, 205, 240, 1000]
statistics.mean(salaries)
# 291.2857142857143

statistics.median(salaries)
# 200

statistics.stdev(salaries)
# 316.5147254529739
              
            

Functional programming modules


itertools, functools, operator

itertools


Infinite: count, cycle, repeat

Sequence: accumulate, chain, filterfalse, groupby, ...

Combinatorics: permutations, product, combinations, ...

itertools.cycle


              
import itertools

c = itertools.cycle('ABC')
next(c)
# 'A'
next(c)
# 'B'
next(c)
# 'C'
next(c)
# 'A'
              
            

itertools.filterfalse


              
import itertools

# leave uneven numbers
ff = itertools.filterfalse(lambda x: x % 2 == 0, range(10))
for i in ff:
    print(i)
# 1
# 3
# 5
# 7
# 9
              
            

itertools.groupby


              
from datetime import datetime as dt
import itertools

# work start and finish log
log = [(dt(2010, 1, 1, 8), 'arrive'),
       (dt(2010, 1, 1, 16), 'leave'),
       (dt(2010, 1, 2, 9), 'arrive'),
       (dt(2010, 1, 2, 16), 'leave')]

g =  itertools.groupby(sorted(log, key=lambda x: x[0].hour),
                       key=lambda x: x[0].hour):
for key, group in g:
    print(key, list(group))
# 8 [(datetime.datetime(2010, 1, 1, 8, 0), 'arrive')]
# 9 [(datetime.datetime(2010, 1, 2, 9, 0), 'arrive')]
# 16 [(datetime.datetime(2010, 1, 1, 16, 0), 'leave'),
#     (datetime.datetime(2010, 1, 2, 16, 0), 'leave')]
              
            

itertools.product


              
import itertools

for i in itertools.product(['a', 'b'], [1, 2]):
     print(i)
# ('a', 1)
# ('a', 2)
# ('b', 1)
# ('b', 2)
              
            

functools


              
import functools

quinary = functools.partial(int, base=5)
quinary('10')
# 5

Engineer = functools.partial(User, profession="engineer")
              
            

File and Directory access


pathlib, os.path, tempfile, fnmatch...

pathlib


              
import pathlib

p = pathlib.Path(__file__)
scripts = p / "scripts"
python_scripts = scripts.glob("*.py")

p.parts()
# ('/', 'opt', 'my_app')
              
            

Data persistence


pickle, sqlite3, ...

Data compression and archiving


zlib, gzip, bz2, lzma, zipfile, tarfile

File formats


csv, configparser, ...

configparser


INI like config file parsing

configparser


              
# config.ini
[network]
port = 8080

[secrets]
pub_key = very_secret
priv_key = supah_secret
              
            

configparser


              
import configparser

config = configparser.ConfigParser()
config.read('config.ini')
config['network']['port']
# '8080'
config['network']['port'] = '1337'
with open('config.ini', 'w') as configfile:
    config.write(configfile)
              
            

Cryptographic services


hashlib, hmac, secrets

secrets


              
import secrets

secrets.token_urlsafe(nbytes=8)
# 'Ca8rdNzYQmY'
              
            

Generic OS services


os, io, time, argparse, logging, getpass, curses, ...

Concurrency


threading, multiprocessing, subprocess, concurrent.futures, ...

Inter process communication


socket, asyncio, ...

Internet data handling


email, json, mimetypes, ...

Structured markup processing tools


html, xml

Internet protocols and support


cgi, wsgiref, urllib, http, smptlib, ...

wsgiref


              # https://docs.python.org/3.6/library/wsgiref.html#examples
from wsgiref.simple_server import make_server

def hello_world_app(environ, start_response):
    status = '200 OK'  # HTTP Status
    headers = [('Content-type', 'text/plain; charset=utf-8')]
    start_response(status, headers)

    # The returned object is going to be printed
    return [b"Hello World"]

with make_server('', 8000, hello_world_app) as httpd:
    print("Serving on port 8000...")

    # Serve until process is killed
    httpd.serve_forever()
              
            

urllib


              
import urllib.request

r = urllib.request.urlopen("http://vilniuspy.lt")
r.status
# 200
              
            

http


              
$ python3 -m http.server
              
            

Multimedia


audioop, wave, colorsys

Internationalization


gettext, locale

Frameworks


turtle, ...

turtle


            
from turtle import *

color("red", "yellow")
begin_fill()
while True:
    forward(200)
    left(170)
    if abs(pos()) < 1:
        break
end_fill()
done()
              
            

turtle


GUI with Tkinter


tkinter

tkinter


              
import tkinter as tk

root = tk.Tk()
root.mainloop()
              
            

Dev tools


typing, pydoc, doctest, unittest, unittest.mock

pydoc


              
$ ls
my_file.py

$ pydoc -w my_file
wrote my_file.html
              
            

doctest


              
# times.py
def times2(number):
    """
    >>> times2(5)
    10
    """
    return number * 2

$ python -m doctest times.py
              
            

Debugging and profiling


pdb, timeit, ...

pdb


              
# times.py
def times2(number):
    """
    >>> times2(5)
    10
    """
    import pdb; pdb.set_trace()
    return number * 2
              
            

timeit


              
import time

timeit(time.sleep(1))
# 1 loop, best of 3: 1 s per loop
              
            

Software packaging and distribution


distutils, venv, ...

Conclusions

Good


  • extensive
  • general purpose indeed
  • check stdlib first before searching for third party libs
  • do data processing with collections, itertools, etc
  • do CLI, TUI, GUI development

Bad


  • unpythonic ¯\_(ツ)_/¯
  • hard and cumbersome to use
  • third party libraries may be better:
    • python ⇨ ipython
    • pdb ⇨ ipdb
    • urllib ⇨ requests
    • argparse ⇨ click
    • webdev ⇨ django, pyramid, flask

pycon.lt

May 13th, Kaunas