Busy Developer's Guide to Python

Objectives

In this talk, we shall...

Python

An Overview

Python

What is Python?

"Python is a programming language that lets you work quickly and integrate systems more effectively."- http://www.python.org

Python

What is Python?

"Python is an easy to learn, powerful programming language. It has efficient high-level data structures and a simple but effective approach to object-oriented programming. Python's elegant syntax and dynamic typing, together with its interpreted nature, make it an ideal language for scripting and rapid application development in many areas on most platforms."

Python

What is Python?

Getting Started

Getting the bits and stuff

Getting Started

Python is an open-source language

Getting Started

Package managers

Getting Started

Python direct

Getting Started

Build from source

Getting Started

Python command line

Getting Started

Python environment variables

Getting Started

Python REPL

Getting Started

Hello, Python

Getting Started

Greetings at the the terminal

tedneward@Teds-MBP-16 External % python3
Python 3.12.5 (main, Aug  6 2024, 19:08:49) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print('Hello world!')
Hello world!
>>> 

Python Language

An Overview

Python Language

At a high level

Python Language

"The Zen of Python" (PEP 20)

Python Language

"The Zen of Python"

Python Language

When in doubt....

import this

Basics

Syntax, comments, types, oh my!

Basics

Source execution model

Basics

Hello, Python

#!/usr/bin/env python
# Say hello, Python
msg = "Hello, Python!"
    
print(msg)

Basics

Comments

Basics

Variables

Basics

Variables

num = 5
message = "This is a string"
this_is_a_really_long_variable = 0
x,y = 0,0
#uninitialized_variable  # error!

Basics

Stylistic/Idiomatic

Basics

Walrus assignment

assignment = (truth := True)
print(assignment)

Basics

Variable types

Basics

Variable types

Basics

Numbers

Basics

Numbers

div1 = 5 / 2      # 2.5
div2 = 5 // 2     # 2
square = 2 ** 2   # 4

Basics

Strings

Basics

Strings

Basics

Strings

str1 = "hello"
str2 = 'hello'
    
str3 = r"Long live metal \m/"
    
str4 = f"{str1}. I would like to say {str3}"
    
str5 = """
This is a here-doc. It can span lines.
It will continue going until we run into
the triple-quote again. It is often used
for documentation and simple formatting
purposes.
"""
    
str6 = "This" "is" "several" "strings"
    
str7 = str4[6:8]  # "is"

Basics

Tuples

Basics

Tuples

ted = "Ted", "Neward", 46
print(ted)                 # ("Ted", "Neward", 46)
charlotte = ("Charlotte", "Neward", 39)
first, last, age = ted
print(first)               # "Ted"

Basics

Lists

Basics

Lists

list1 = [1, 2, 3, 4, 5]
list2 = [1, "two", 3.0]
list3 = list1 + list2       # [1, 2, 3, 4, 5, 1, "two", 3.0]
firstlistelement = list1[0] # 1
lastlistelement = list1[-1] # 5

Basics

Sets

Basics

Sets

set1 = {1, 2, 3, 4, 5}
set2 = {1, 1, 2, 2, 3, 3, 4, 4}
print(set2)                 # "{1, 2, 3, 4}"
    
set3 = {2, 4, 6}
set4 = {1, 4, 9, 16}
print(set3 & set4)          # "{4}" 
print(set3 - set4)          # "{2, 6}"
print(set3 | set4)          # "{16, 1, 2, 4, 6, 9}"

Basics

Dictionaries (Hashes)

Basics

Dictionaries (Hashes)

Basics

Dictionaries (Hashes)

dict1 = { "captain":"Antilles" }
dict1["admiral"] = "Ackbar"
k = dict1.keys()
v = dict1.values()
kv = dict1.items()
    
another_dict = dict(name="Ted",age=47)
print(another_dict)   # {'name':'Ted','age':47}

Basics

Python and types

Basics

Python type conversion

Flow Control

Branching, jumping, iterating, oh my!

Flow Control

Branching (If)

Flow Control

If

age = 45
if age > 50:
    print("You old!")
elif age < 18:
    print("Juvie!")
else:
    print("You not old!")
    
insult = "Boomer!" if age > 50 else "Millennial!"

Flow Control

Stylistic/Idiomatic

Flow Control

Pattern-matching (Match) (3.10+)

Flow Control

Match

http_message = ""
match status:
    case 400:
        http_message = "Bad request"
    case 404:
        http_message = "Not found"
    case 418:
        http_message = "I'm a teapot"
    case _:
        http_message = "Something's wrong with the internet"

Flow Control

More Match

point = (0, 0)
match point:
    case (0, 0):
        print("Origin")
    case (0, y):
        print(f"Y={y}")
    case (x, 0):
        print(f"X={x}")
    case (x, y) if x == y:
        print(f"Y=X at {x}")
    case (x, y):
        print(f"X={x}, Y={y}")
    case _:
        raise ValueError("Not a point")

Flow Control

Iteration (While)

Flow Control

While

x = 3
while x > 0:
    print("x is still more than 0")
    x = x -1
else:
    print("x is now " + str(x))

Flow Control

Iteration (For)

Flow Control

For

for c in range(10):
    print(c)
else:
    print("Can we see c?", c)
print("Can we still see c?", c)
    
message = "Python is interesting"
for ch in message:
    print(ch)
    
attendees = ["Marcel", "Roy", "Jeremy"]
for at in attendees:
    print(at)
    
my_first_tuple = "Ted", "Neward", 47
for t in my_first_tuple:
    print(t)

Flow Control

Stylistic/Idiomatic

Flow Control

Exception handling

Flow Control

Exception handling

Flow Control

Exception handling

Flow Control

Exceptions

try:
    bad_div = 1/0
except ZeroDivisionError:
    print("Silly boy; you can't do that")
else:
    print("Else!")
finally:
    print("Finally!")
    
try:
    print("In a new try block")
    raise Exception()
except Exception:
    print("We just raised this!")
print("Onwards we execute...")

Flow Control

Stylistic/Idiomatic

Flow Control

With

Flow Control

Exceptions

with open("data.dat", "w") as datafile:
    datafile.write("Pretend this is data")
# datafile is implicitly close()d after the above block completes
## {{## END with}}

Functions

Reusable named behavior

Functions

Python comes with many functions

Functions

Some useful builtin functions

Functions

Some useful builtin functions

Functions

Built-in Functions

print("Hello, Python!")
print(dir(__builtins__))

Functions

User-defined functions

Functions

Defining functions

def sayHowdy():
    """This function says howdy and returns the same"""
    print("Howdy!")
    return "I said howdy"
    
response = sayHowdy()
print(response)             # "I said howdy"
print(sayHowdy.__doc__)     # "This function says..."

Functions

Type Hints

Functions

Type-hinting functions

def add(lhs : int, rhs : int) -> int:
    return lhs + rhs
def concat(str1 : str, str2 : str) -> str:
    return str1 + str2
    
print(add(2, 3))            # 5
print(add('1', '2'))        # 12
print(concat(1, 2))         # 3
print(concat('1', '2'))     # 12

Functions

Default argument values

Functions

Default argument values

def sayGoodMorning(language="english"):
    if (language == "english"):
        return "Good morning!"
    else:
        return f"Sorry, I don't speak {language}"
    
print(sayGoodMorning())
print(sayGoodMorning("french"))

Functions

Keyword arguments

Functions

Keyword arguments

def saySomething(message="Hello", language="English", times=1):
    """Prints a message in a language a number of times"""
    for x in range(times):
        print(message + " (in " + language + ")")
    
saySomething(language="German", times=3, message="Good Morning")

Functions

Formal parameter collection

Functions

Formal parameters

def speak(**args):
    print(args)
    for key, value in args.items():
        print("argument " + str(key) + " = " + str(value))
    
speak(one="1", two="2", three="3")

Functions

Arbitrary argument list

Functions

Aribtrary argument lists

def myPrint(prefix, *rest):
    message = prefix
    for r in rest:
        message += " " + r
    print(message)
    
myPrint("Salutations")
myPrint("Salutations", "planet")

Functions

Functions are first-class citizens

Functions

Function literals

fn_lit = saySomething
fn_lit("Hello", "English", 2)

Functions

Lambda expressions (function literals)

Functions

Lambdas (aka closures)

messages = ["Hello", "Guten morgen", "Bonjour"]
def capIt(x):
    return x.upper()
print(capIt("hello"))   # "HELLO"
up_messages = map(capIt, messages)    # "HELLO", "GUTEN MORGEN", "BONJOUR"
up_messages2 = map(lambda x: x.upper, messages) # same as previous
    
add_one = lambda x: x+1     # same as def add_one(x): return x+1
result = (lambda x: x+1)(2) # 3

Functions

List comprehensions

Functions

Three ways to initialize a list of squares

squares1 = []
for x in range(10):
    squares1.append(x**2)
# or...    
squares2 = list(map(lambda x: x**2, range(10)))
# or...
squares3 = [x**2 for x in range(10)]

Functions

More Comprehensions

x = [2, 3, 4, 5, 6]
y = []
for v in x :
    y += [v * 5]        # y == [10, 15, 20, 25, 30]
    
y2 = map(lambda v : v * 5, x)
    
y3 = [v * 5 for v in x] # y3 == [10, 15, 20, 25, 30]

Functions

More Comprehensions

for v in x :
        if v % 2 :
            y += [v * 5]
    
y2 = map(lambda v : v * 5, filter(lambda u : u % 2, x))
    
y3 = [v * 5 for v in x if v % 2]

Functions

Generators

Functions

Generators

def generator_function():
    for i in range(10):
        yield i
for i in generator_function():
    print(i)
    
def fibonacci(n):
    a = b = 1
    for i in range(n):
        yield a
        a,b = b, a+b

Functions

Global references and keyword

Functions

Globals

player = "Fred"
    
def doSomething():
    #global player  # without this, it's an error
        # "UnboundLocalError: local variable 'player' referenced before assignment"
    player = player + " and Jed"
    print(player)
    
doSomething()

Namespaces

Mapping names to objects

Namespaces

"Let's do more of those!"

Namespaces

Examples

Namespaces

A namespaces example

def scope_test():
    def do_local():
        spam = "local spam"

    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"

    def do_global():
        global spam
        spam = "global spam"

    spam = "test spam"
    do_local()
    print("After local assignment:", spam)
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    do_global()
    print("After global assignment:", spam)

scope_test()
print("In global scope:", spam)

Classes

Combining state and behavior, oh my!

Classes

Pythonic classes

Classes

Definition

Classes

Basic syntax

class Person:
    """Someday this class will represent a human being"""
    
    # count is a "class variable" (static)
    count = 0
    
    # sayHello is a "class method" (static)    
    def sayHello():
        print("Hello, world!")
    
print(Person.count)
Person.sayHello()

Classes

Instantiation

Classes

Manipulation

Classes

Class manipulation

intern = Person("Joe", "Intern", 20)
intern.code()
    # "Joe is coding, coding, coding..."
    
print(dir(intern))
    # (Prints out a lot of methods, most of which we didn't define)
    
internCodeFunction = intern.code
internCodeFunction()
    # "Joe is coding, coding, coding..."

Classes

"Static" vs "instance"

Classes

__init__

class Person:
    def __init__(self, fn, ln, a):
        self.firstName = fn
        self.lastName = ln
        self.age = a
    
    def code(self):
        print(self.firstName + " is coding, coding, coding...")
    
ted = Person("Ted", "Neward", 48)
ted.code()

Classes

Property members

Classes

Using property()

class Monster:
    def __init__(self, name):
        self._name = name
    
    def getname(self):
        return self._name
    
    def setname(self, value):
        self._name = value
    
    def delname(self):
        del self._name
    
    name = property(getname, setname, delname, "The Monster's name")
    
orc = Monster("Orc")
print("The " + orc.name + " attacks you!")

Classes

The property decorator

class Item:
    def __init__(self, name):
        self._name = name
    
    @property
    def name(self):
        return self._name
    
    @name.setter
    def name(self, value):
        self._name = value
    
    @name.deleter
    def name(self):
        del self._name
    
magicSword = Item("Sword +1")
print(magicSword.name + " is such a boring name")
magicSword.name = "Sting"  # Much better

Classes

Stylistic/Idiomatic

Classes

Inheritance

Classes

Inheritance

class Student(Person):
    def study(self, subject):
        print(self.firstName + " is studying " + subject)

Classes

Access Control

Magic Methods

Python's subtle convention for... everything?

Magic Methods

Names can be awkward

Magic Methods

Method conventions

Magic Methods

Object initialization/deinitialization

Magic Methods

Object comparison operations

Magic Methods

Magic methods can also add interesting behavior

Magic Methods

A sample reversing iterator

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)

    def __iter__(self):
        return self

    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]

Resources

Where to go for more

Online

Websites

Online

Deeper Python language

Credentials

Who is this guy?