Python

A Short and Incomplete Introduction

David Dalpiaz

January 29, 2024

The Way of The Program

Think Python

Whether you’re new to Python, or need a quick refresher:

In these slides, we’ll draw heavily from the examples in this book, as well as the structure of the coverage.

What is Program?

  • Input / Output
  • Math
  • Conditional Execution
  • Repetition

That’s pretty much it!

The First Program

As is tradition…

print("Hello, World!")
Hello, World!

Operations, Values, and Types

2 + 1
3
type(2 + 1)
int
0.1 + 0.2
0.30000000000000004
type(42.0)
float
"Na" * 16 + " Batman!"
'NaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNa Batman!'
type("Hello")
str
True | False
True
type(True)
bool

Wait A Minute!

0.1 + 0.2
0.30000000000000004

What’s going on here?

Variables, Expressions, and Statements

Assignment

message = 'And now for something completely different.'
n = 17
pi = 3.1415926535897932

Assignment State Diagram

flowchart LR
  A[message] --> B(And now for something completely different.)
  C[n] --> D(17)
  E[pi] --> F(3.1415926535897932)

Expressions and Statements

An expression is a combination of values, variables, and operators.

print(42)
print(n)
print(n + 25)
42
17
42

Expressions are evaluated by the interpreter.

Order of Operations

Order of Operations

Order of Operations

Hot Take: Just use parenthesis and make your intention clear!

Functions

Function Calls

import math
import numpy as np

math.log(math.exp(1))
1.0
  • The value 1 is the argument to math.exp()
  • After math.exp(1) is evaluated, it is the argument to math.log().

Creating Functions

def my_new_function(x, y, z=1):
  r = x / y
  s = r ** z
  return s
  • x, y, and z are parameters.
    • z has a default value of 10.
  • The value of s is returned by the function.
my_new_function(1, 2)
0.5
my_new_function(1, 2, 3)
0.125
my_new_function(x=2, y=3, z=4)
0.19753086419753083
  • With many parameters, sometimes it is useful to include their names. When doing so, you are using keyword arguments.

Conditional Execution

Boolean Expressions

Booleans can be true and false, both of which are defined in Python as keywords with type bool.

True
True
False
False

There are several relational operators. These compare to objects and return a boolean.

x != y          # x is not equal to y
x > y           # x is greater than y
x < y           # x is less than y
x >= y          # x is greater than or equal to y
x <= y          # x is less than or equal to y

Logical Operators

Relational operators make comparisons and return a boolean. Logical operators act on one or more booleans.

  • and
  • or
  • not
True and False
False
True or False
True
not True
False
x = 42
not (x > 40) or (True)
True

Conditional Execution

Python of course has the ability to use a if-else structure.

x = 42
if x > 0:
  print("Hello!")
Hello!
if x < 0:
  print("Negative!")
else:
  print("Positive")
Positive
if x < 0:
  print("Negative!")
elif x == 0:
  print("Zero!")
else:
  print("Positive")
Positive

Iteration

Types of Iteration

  • while
    • break
  • Recursion
  • for

For Loops

fruit = 'banana'
for char in fruit:
    print(char)
b
a
n
a
n
a

In Python, you can loop over all sorts of things!

Data Structures

Strings

Strings are sequences of characters. They are a sequence thus they are ordered and can be indexed.

greeting = "Hello, World!"
greeting[1:5]
'ello'
greeting.lower()
'hello, world!'
len(greeting)
13

Slicing

Membership Checks

greeting = "Hello, World!"
"Hello" in greeting
True
"Goodbye" not in greeting
True

Lists

Lists are are ordered, mutable, heterogeneous collections of elements.

z = [1, 2.0, "Hello!", [True, False]] + ["a", "b", "c"]
z
[1, 2.0, 'Hello!', [True, False], 'a', 'b', 'c']
z[1:3] = [42, 42]
z
[1, 42, 42, [True, False], 'a', 'b', 'c']
z.append([1, 2, 3])
z
[1, 42, 42, [True, False], 'a', 'b', 'c', [1, 2, 3]]
for i, elem in enumerate(z):
  if isinstance(elem, list):
    print(f"Found a list in a list at position {i}.")
Found a list in a list at position 3.
Found a list in a list at position 7.

Dictionaries

Dictionaries are are ordered, mutable, heterogeneous collections of key-value pairs, with some restrictions on the keys.

  • In a list, the indices have to be integers; in a dictionary they can be (almost) any type, and are called keys, which must be hashable and cannot be duplicated.
  • Each key is associated with a single value. The association of a key and a value is called a key-value pair or sometimes an item.
  • Python dictionaries use a data structure called a hashtable that has a remarkable property: the in operator takes about the same amount of time no matter how many items are in the dictionary.

Dictionary Usage

# Creating a dictionary
person = {
    "name": "John Doe",
    "age": 30,
    "city": "New York"
}

# Accessing a value
print(person["name"])

# Getting the number of key-value pairs
print(len(person))
John Doe
3
# Changing a value
person["age"] = 31

# Adding a new key-value pair
person["profession"] = "Software Developer"

# Removing a key-value pair
del person["city"]

# Iterating over a dictionary
for key, value in person.items():
    print(f"{key}: {value}")

# Checking if a key exists
if "name" in person:
    print("Name is present in the dictionary")
name: John Doe
age: 31
profession: Software Developer
Name is present in the dictionary

Tuples

Tuples are are ordered, immutable, heterogeneous collections of elements.

# Creating a tuple (two ways)
fruits = ("apple", "banana", "cherry")
fruits = "apple", "banana", "cherry"

# Accessing a value
print(fruits[1])

# Checking if a value exists
if "banana" in fruits:
    print("Banana is present in the tuple")
banana
Banana is present in the tuple

Tuple Unpacking

It is very common to return objects from a function using a tuple. It is equally common to “unpack” them and give each item a name.

import numpy as np

def mean_and_std(x):
  return np.mean(x), np.std(x)

x_mean, x_std = mean_and_std([1, 2, 3, 4, 5, 6, 7])
print(x_mean)
print(x_std)
4.0
2.0

Input / Output

Read

Use with for auto-magic, like automatic file closing.

with open('myfile.txt', 'r') as file:
    content = file.read()

Write

Use with for auto-magic, like automatic file closing.

with open('myfile.txt', 'w') as file:
    file.write('Hello, World!')

Object-Oriented Programming (OOP)

Class Definition

class Circle:
    def __init__(self, radius, color):
        self.radius = radius
        self.color = color

    def display_details(self):
        print(f"The circle has a radius of {self.radius} and color {self.color}")

    def change_radius(self, new_radius):
        self.radius = new_radius
        print(f"The circle's radius has been changed to: {self.radius}")

    def change_color(self, new_color):
        self.color = new_color
        print(f"The circle's color has been changed to: {self.color}")

Instantiation and Using Methods

# Create a Circle object with radius 5 and color red
circle = Circle(5, "red")

# Display the circle's details
circle.display_details()

# Change the circle's radius to 10
circle.change_radius(10)

# Change the circle's color to blue
circle.change_color("blue")

# Display the circle's details again
circle.display_details()
The circle has a radius of 5 and color red
The circle's radius has been changed to: 10
The circle's color has been changed to: blue
The circle has a radius of 10 and color blue

Goodies

Conditional Expressions

import math

# standard if-else
if x > 0:
    y = math.log(x)
else:
    y = float('nan')

# conditional expression
y = math.log(x) if x > 0 else float('nan')

List Comprehensions

# standard function
def capitalize_all(t):
    res = []
    for s in t:
        res.append(s.capitalize())
    return res

# using a comprehension
def capitalize_all(t):
    return [s.capitalize() for s in t]

any and all

any([False, False, True])
True
all([True, True, False])
False

Counters

from collections import Counter
count = Counter('parrot')
count
Counter({'r': 2, 'p': 1, 'a': 1, 'o': 1, 't': 1})

Gathering Keyword Arguments

def print_all_args(*args, **kwargs):
    print(args, kwargs)

print_all_args(1, 2.0, third='3')
(1, 2.0) {'third': '3'}
d = dict(x=1, y=2)
print_all_args(**d)
print_all_args(d)
() {'x': 1, 'y': 2}
({'x': 1, 'y': 2},) {}

Formatted String Literals (f-strings)

a = 5
b = 10
print(f"{a} plus {b} is {a + b}, and not {2 * (a + b)}.")
5 plus 10 is 15, and not 30.

That’s All Folks!