Skip to content

Latest commit

 

History

History
880 lines (596 loc) · 13.2 KB

slides.md

File metadata and controls

880 lines (596 loc) · 13.2 KB

Hello, Python!

🎬 Santhosh Srinivasan


What?

  • Rapid Prototyping Language
  • Easy to learn, read and use
  • An interpreted language

Why?

  • Productivity and Readable Code
    • reads like "pseudo-code"
  • "Life's better without braces" (Bruce Eckel)
    • and semicolons (me!)

If you're still not convinced

What makes Python Awesome?

By Raymond Hettinger (@raymondh)

Comparing to other Languages

typically 3-5 times shorter than equivalent Java programs.

often 5-10 times shorter than equivalent C++ code!

Python has an applicability well beyond Perl's niche

Properties

  • Open Source
  • Mature (Almost as old as me!)
  • Portable
  • Automatic Memory Management
  • No core dumps

Where is it used?

  • Web Development
  • Data Analytics and Data Science
  • Machine Learning
  • GUI Apps
  • and many more...

Who's using it?

  • Google
  • NASA
  • NYSE
  • Yahoo
  • Redhat
  • and many more...

Class Outline 📃

  • interactive "shell"
  • basic types: numbers, strings
  • container types: lists, tuples, sets, dictionaries
  • variables
  • control structures
  • functions
  • classes
  • modules & packages
  • exceptions
  • files & standard library

Interactive Shell

Demo

  • Python Shell
  • IDLE

Variables

msg = "hello"
print(msg)

A bit advanced

# with type hinting
msg: str = "hello"
print(msg)

High-level data types

  • Numbers
  • Strings
  • Lists
  • Tuples
  • Sets
  • Dictionaries

Numbers

>>> 2 + 2
4
>>> 50 - 5*6
20
>>> (50 - 5*6) / 4
5.0
>>> 8 / 5  # division always returns a floating point number
1.6
>>> 17 / 3  # classic division returns a float
5.666666666666667
>>>
>>> 17 // 3  # floor division discards the fractional part
5
>>> 17 % 3  # the % operator returns the remainder of the division
2
>>> 5 * 3 + 2  # result * divisor + remainder
17

Strings

code output
"hi" + " san!" "hi san!"
"hello" * 3 "hellohellohello"
"hello"[0] "h"
"hello"[-1] "o"
"hello"[1:4] "ell"
len("hello") 5

More Strings

code output
"hello" < "jello" True
"e" in "hello" True
"x" not in "hello" True
"python" 'python'
'python' 'python'
r'python' 'python'

Moore Strings

code output
"python".upper() PYTHON
"python".capitalize() Python
"PYTHON".lower() python
"hello".count("l") 2
"hello".find("l") 2
"hello".index("el") 1

Lists

Flexible Arrays

a = [99, "bottles of beer", ["on", "the", "wall"]]

Same operators as strings

a+b, a*3, a[0], a[-1], a[1:], len(a)

lists vs strings; strings are immutable

Item and Slice Assignment

a = [99, "bottles of beer", ["on", "the", "wall"]]

a[0] = 98 # [98, "bottles of beer", ["on", "the", "wall"]]

a[1:2] = ["bottles", "of", "beer"]
    # [98, "bottles", "of", "beer", ["on", "the", "wall"]]

del a[-1]	# [98, "bottles", "of", "beer"]

More List Operations

>>> a = list(range(5))  # [0, 1, 2, 3, 4]
>>> a.append(5)         # [0, 1, 2, 3, 4, 5]
>>> a.pop()             # [0, 1, 2, 3, 4]
5
>>> a.insert(0, 42)     # [42, 0, 1, 2, 3, 4]
>>> a.pop(0)            # [0, 1, 2, 3, 4]
42
>>> a.reverse()         # [4, 3, 2, 1, 0]
>>> a.sort()            # [0, 1, 2, 3, 4]

More List Operations

>>> a
[0, 1, 2, 3, 4]
>>> min(a)
0
>>> max(a)
4
>>> sum(a)
10
>>> a.count(2)
1

Tuples

key = (lastname, firstname)
point = x, y, z   # parentheses optional
x, y, z = point   # unpack
lastname = key[0]
singleton = (1,)  # trailing comma!!!
empty = ()        # parentheses!

More Tuples

>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # Tuples may be nested:
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))

Tuples are Immutable

>>> # Tuples are immutable:
... t[0] = 88888
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> # but they can contain mutable objects:
... v = ([1, 2, 3], [3, 2, 1])
>>> v
([1, 2, 3], [3, 2, 1])

Sets

Unique Values

files = {'py', 'java', 'c', 'py', 'sh', 'java'}
print(files) # {'sh', 'c', 'java', 'py'}

Faster Membership Testing

'py' in files # True
'go' in files # False

Use set() to create sets

a = set('abracadabra')  # {'d', 'c', 'r', 'a', 'b'}
b = set('alacazam')     # {'c', 'z', 'l', 'a', 'm'}

More Set operations

>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                       # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b                   # letters in a but not in b
{'r', 'd', 'b'}
>>> a | b                   # letters in a or b or both
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b                   # letters in both a and b
{'a', 'c'}
>>> a ^ b                   # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}

Dictionaries

Hash tables, "associative arrays"

d = {"make": "Honda", "model": "CR-V"}

Lookup:

d["make"] # "Honda"
d["brand"] # raises KeyError exception

Delete, insert, overwrite:

del d["model"]      # {"make": "Honda"}
d["make"] = "Toyota"   # {"make": "Toyota"}
d["model"] = "Corolla"  # {"make": "Toyota", "model": "Corolla"}

More Dict Ops

Keys, values, items:

d.keys()   # dict_keys(['make', 'model'])
d.values() # dict_values(['Toyota', 'Corolla'])
d.items()  # dict_items([('make', 'Honda'), ('model', 'Corolla')])

Presence check:

"make" in d       # True
"brand" in d      # False
"brand" not in d  # True

Values of any type; keys almost any

{
    "name":"Guido",
    "age":43,
    ("hello","world"):1,
    42:"yes",
    "flag": ["red","white","blue"]
}

Dict Details

  • Keys must be immutable:
    • numbers, strings, tuples of immutables
      • these cannot be changed after creation
    • reason is hashing (fast lookup technique)
    • not lists or other dictionaries -these types of objects can be changed "in place"
    • no restrictions on values

Control Structures - If

if condition:
  statements
[elif condition:
  statements]...
else:
  statements
x = int(input("Please enter an integer: "))

if x < 0:
    x = 0
    print('Negative changed to zero')
elif x == 0:
    print('Zero')
elif x == 1:
    print('Single')
else:
    print('More')

Control Strucures - For

for var in sequence:
    statements
# Measure some strings:
words = ['cat', 'window', 'defenestrate']
for w in words:
    print(w, len(w))

# prints as below
# cat 3
# window 6
# defenestrate 12

Control Structures

while condition:
    statements
break
continue

Indentation

In C:

for (i = 0; i < 20; i++) {
    if (i%3 == 0) {
        printf("%d\n", i);
        if (i%5 == 0) {
            printf("Bingo!\n");
        }
    }
    printf("---\n");
}

In Python:

for i in range(20):
    if i%3 == 0:
        print(i)
        if i%5 == 0:
            print("Bingo!")
    print("---")

Looping ➰

for c in "python": # over a string

for item in [1, 2, 3]: # over a list

for key in {"a": 1, "b": 2}: # over a dict

for item in (1, 2, 3): # over a tuple

Functions

def name(arg1, arg2):
    """documentation""" # optional doc string

    statements
    return expression

Example Function

def gcd(a, b):
    """greatest common divisor"""

    while a != 0:
        a, b = b%a, a    # parallel assignment
    return b

>>> gcd.__doc__
'greatest common divisor'
>>> gcd(12, 20)
4

Function with Type Hints

def gcd(a: int, b: int) -> int:
    """greatest common divisor"""

    while a != 0:
        a, b = b%a, a    # parallel assignment
    return b

Function with default arg

def say_hello(name="there"):
    """prints hello with a given or a default name"""

    print(f"Hello, {name}!")

say_hello()         # Hello, there!
say_hello("San")    # Hello, San!

Function with keyword args

def average(total, count):
    """returns average by dividing total by count"""

    return total/count

average(5, 2) # 2.5
average(total=5, count=2) # 2.5
average(count=2, total=5) # 2.5

Classes

class name:
    """documentation"""

    statements

or

class name(base1, base2, ...):
    ...

Most statements are method defnitions:

    def name(self, arg1, arg2, ...):
        ...

Example Class:

class Stack:
    """A well-known data structure…"""

    def __init__(self):		# constructor
        self.items = []

    def push(self, x):
        self.items.append(x)	# the sky is the limit

    def pop(self):
        x = self.items[-1]		# what happens if it’s empty?
        del self.items[-1]
        return x

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

Using Classes:

To create an instance, simply call the class object:

x = Stack()	# no 'new' operator!

To use methods, use dot notation:

x.empty()   # -> True
x.push(1)   # [1]
x.empty()   # -> False
x.push("hello")   # [1, "hello"]
x.pop()     # -> "hello"	# [1]

To inspect instance variables, use dot notation:

x.items     # -> [1]

Subclassing

class FancyStack(Stack):
    """stack with added ability to inspect inferior stack items"""

    def peek(self, n):
        """peek(0) returns top; peek(-1) returns item below that; etc."""
        size = len(self.items)
        assert 0 <= n < size	# test precondition
        return self.items[size-1-n]

Subclassing (2)

class LimitedStack(FancyStack):
    """fancy stack with limit on stack size"""

    def __init__(self, limit):
        self.limit = limit
        FancyStack.__init__(self)   # base class constructor

    def push(self, x):
        assert len(self.items) < self.limit
        FancyStack.push(self, x)    # "super" method call

Modules

  • Collection of stuff in foo.py file
    • functions
    • classes
    • variables

Importing modules:

import re;
print(re.match("[a-z]+", s))

# or

from re import match;
print(match("[a-z]+", s))

Import with rename:

import re as regex

# or

from re import match as m

Packages 📦

  • Collection of modules in directory
  • Must have __init__.py file
  • May contain subpackages

Import syntax:

from P.Q.M import foo;
print(foo())

from P.Q import M;
print(M.foo())

import P.Q.M;
print(P.Q.M.foo())

import P.Q.M as M;
print(M.foo()) # new

Catching Exceptions

def foo(x):
    return 1/x

def bar(x):
    try:
        print(foo(x))
    except ZeroDivisionError as err:
        print("Can't divide by zero:", err)

bar(0)

try-finally cleanup

f = open(file)

try:
    process_file(f)
finally:
    f.close()   # always executed

print("OK") # executed on success only

Raising Exceptions

raise IndexError  # shorthand for 'raise IndexError()'

raise IndexError("k out of range")

try:
    something
except:
    print("Oops!")
    raise # reraise

File Objects

f = open(filename, mode)
  • mode can be r, w, a (like C stdio); default r
  • append b for text translation mode
  • append + for read/write open

Reading Files

with open('file.txt') as f:
    for line in f:
        print(line)

Standard Library 🗃️

  • Operating System Interface (import os)
  • System (import sys)
  • RegEx (import re)
  • Testing (import unittest)

More standard library 🗃️

  • Pretty Print (import pprint)
  • Logging (import logging)
  • Collections (import collections)
  • itertools (import itertools)

Beyond Basics 🎟️

  • Third Party Packages (pip, PyPI)
  • Comprehensions
  • Iterators
  • Generators
  • Magic Methods
  • Decorators

Questions?


Resources 🔖


References 📚


Feedback 🗣️

  • This deck is on Github. Issues/PRs are appreciated!
  • Reach out to me.