Python Notes¶
Print¶
print("Hello World")
Can also print a variable:
print(name)Or print words and a variable:
print("Hello " + name)Can be used to figure out a type:
print(type(name))To print a string with an int you must type cast:
print("Your age is: " + str(age))An easy way to print a string with variables is an f-string:
print(f"Hello {name} it's {day}")When printing a boolean variable it will return
TrueorFalseFor a print in a loop when you don’t want a new line each time, use:
print(x, end=" ")For a new line use
\n
Variables¶
A variable is a container for a value. It behaves as the value that it contains.
Types
String: a series of characters. Ex:
name = "Greyson"Int: a whole number. Ex:
age = 20Float: a decimal number. Ex:
height = 6.5Boolean:
TrueorFalse. Ex:on = False
Variables can be added together:
first_name = "Greyson"
last_name = "Trubia"
full_name = first_name + last_name
Multiple Assignment¶
Assign multiple variables at the same time in one line of code.
name, age, alive = "Greyson", 20, True
# Sets them all to 30
spongebob = patrick = sandy = squidward = 30
String Methods¶
print(len(name)) # length of a string
print(name.find("r")) # position of a character within a string
print(name.capitalize()) # capitalize the first letter
print(name.upper()) # make string all uppercase
print(name.lower()) # make string all lowercase
print(name.isdigit()) # True/False - is the string a digit
print(name.isalpha()) # True/False - is the string alphabetical characters
print(name.count("e")) # count how many times "e" appears in the string
print(name.replace("e", "a")) # replace "e" with "a"
print(name * 3) # print a string multiple times
Note
Correction: count() needs an argument — the character (or substring) you
want to count occurrences of, e.g. name.count("e"). It does not count total
characters (that’s what len() is for).
Type Casting¶
Converts the data type of a value to another data type.
# Temporary change
number = "5" # string
print(int(number)) # prints the string as an int
# Permanent change
y = 2.0 # float
y = int(y)
Useful to perform mathematical operations on numbers contained in a string, or to print a number together with a string.
User Input¶
To ask for user input use input().
input("What is your name?")
This will ask the user for an input and wait for an entry in the console window, but doesn’t store it.
name = input("What is your name?: ")
print("Hello " + name)
User input will always be recorded as a string unless you change that:
age = int(input("How old are you?: ")) # records the input as an int
Math Functions¶
Use import math to access math functions. Tip: type math. to see all
possible functions.
import math
round(x) # nearest whole number
math.ceil(x) # round up
math.floor(x) # round down
abs(x) # how far the number is from 0
pow(var, n) # raise number to a power
math.sqrt(x) # square root of a number
max(a, b, c) # find the largest value of variables or numbers
min(a, b, c) # find the smallest value of variables or numbers
pi = 3.14
print(math.ceil(pi))
Note
Correction: the round-up function is math.ceil(), not math.ciel().
String Slicing¶
Creating a substring by extracting elements from another string, using indexing
[ ] or slice().
Indexing — [start:stop:step]
name = "Joe Smith"
J o e S m i t h
0 1 2 3 4 5 6 7 8
name = "Joe Smith"
first_name = name[0:3] # "Joe"
You can also do
name[:3]to start from the beginning without typing the start index. The same works in reverse — leave the stop field empty and give a start index to slice to the end.stepis used to display every 2+ letters, starting from the first.Always include the colons, even if leaving a field blank.
To reverse a string, set the step to
-1.
Slice object — similar to indexing:
website = "https://google.com"
s = slice(8, -4)
print(website[s]) # "google"
Note
Correction: the original example used slice(7, -4), which actually
includes the leading / and prints "/google". To get just "google"
the start index should be 8.
If Statements¶
Do something only if something is true, else do something else.
age = int(input("Enter your age: "))
if age >= 18:
print("You are now signed up")
elif age < 0:
print("You haven't been born yet")
else:
print("You must be 18+ to sign up")
Boolean in an if statement
for_sale = True
if for_sale:
print("It is for sale")
No need to write a comparison — the variable itself acts as the condition.
Note
Correction: in Python, booleans are capitalized — True / False,
not true / false.
Example programs referenced: calculator.py, converter.py (lbs to kg),
tempconverter.py (F to C).
Logical Operators¶
Evaluate multiple conditions (or, and, not).
or— at least one condition must be trueand— both conditions must be truenot— inverts the condition
if temp > 30 or is_raining:
print("Event is cancelled")
elif temp > 30 and is_sunny:
print("Event is active")
elif temp > 30 and not is_sunny:
print("It's cloudy")
Conditional Expressions¶
A one-line shortcut for the if/else statement. Print or assign one of two values
based on a condition: X if condition else Y.
grade = 85
print("Passed" if grade > 65 else "Failed")
a = 6
b = 7
max_num = a if a > b else b
min_num = a if a < b else b
Example programs referenced: gradecheck.py.
String Methods Reference¶
Use print(help(str)) to list all string methods.
len(variable)— number of characters in a stringvariable.find(" ")— finds the character (e.g. a space) and returns its positionvariable.rfind("o")— finds the last occurrence of a character and returns its position; returns-1if not foundvariable.capitalize()— capitalizes the first lettervariable.upper()— makes all characters uppercasevariable.lower()— makes all characters lowercasevariable.isdigit()—True/Falsebased on whether there are only numbersvariable.isalpha()—True/Falsebased on whether there are only letters (a space does not count as a letter)variable.count("e")— counts how many times that character appearsvariable.replace("-", " ")— replaces all of the first character/string with the second
String Indexing¶
Indexing = accessing elements of a sequence using [ ] — [start:end:step].
The start field is inclusive, the end field is exclusive. Leave start blank to
begin at the start, leave end blank to go to the end. Negative indexes count
from the end.
credit_number = "1234-5678-9012-3456"
print(credit_number[0]) # "1" - first number of the sequence
print(credit_number[0:4]) # "1234" - first 4 numbers, not the dash
print(credit_number[-1]) # "6" - starts from the end
print(credit_number[::2]) # every second number, starting from the first
print(credit_number[::-1]) # the credit card number backwards
Format Specifiers¶
Used in an f-string to format a value, based on flags. Multiple flags can be combined without separators.
price1 = 3.14159
price2 = -987.65
price3 = 1200.34
print(f"price1 is {price1:.2f}") # rounds to 2 decimal places -> 3.14
print(f"price2 is {price2:10}") # pads the value to a minimum width of 10 characters
print(f"price3 is {price3:,}") # comma thousands separator -> 1,200.34
print(f"{price1:+,.2f}") # plus sign if positive, comma separator, 2 decimals
.<number>f— round to that many decimal places (fixed point):<number>— allocate that many spaces (minimum field width):03— allocate that many spaces, zero-padded:<— left justify:>— right justify:^— center align:+— use a plus sign to indicate a positive value:=— place the sign in the leftmost position``: `` — insert a space before positive numbers
:,— comma separator
Note
Correction: {price2:10} pads the value itself out to a minimum width
of 10 characters (numbers are right-justified by default) — it doesn’t add 10
literal spaces after the surrounding text.
While Loops¶
While loops execute code while some condition remains true.
food = input("Enter a food you like (q to quit): ")
while not food == "q":
print(f"you like {food}")
food = input("Enter another food you like (q to quit): ")
print("Done")
There must be a way to exit the loop, or it becomes an infinite loop — break
can be used to escape early.
For Loops¶
Execute a block of code a fixed number of times. You can iterate over a range, string, sequence, etc.
Range — counting to 10 (start is inclusive, stop is exclusive):
for x in range(1, 11):
print(x)
Counting backwards:
for x in reversed(range(1, 11)): # 10, 9, 8 ... 1
print(x)
# equivalent alternative
for x in range(10, 0, -1): # 10, 9, 8 ... 1
print(x)
Note
Correction: the original notes gave range(11, 1, -1) as equivalent to
reversed(range(1, 11)). It isn’t — range(11, 1, -1) produces 11 down to
2, while reversed(range(1, 11)) produces 10 down to 1. The matching range
is range(10, 0, -1).
Adding a step (a third argument counts by that amount):
for x in range(1, 11, 2): # counts by 2s
print(x)
Skip a specific value with continue:
for x in range(1, 21):
if x == 13:
continue
else:
print(x) # skips 13, prints every other number
End the loop early with break:
for x in range(1, 21):
if x == 13:
break
else:
print(x) # stops when it reaches 13
Looping over a string:
name = "Greyson"
for x in name:
print(x) # prints each letter on a separate line
Collections¶
A single variable used to store multiple values.
List
[ ]— ordered and changeable, allows duplicatesSet
{ }— unordered, mutable (you can add/remove items), does not allow duplicatesTuple
( )— ordered and unchangeable, allows duplicates, faster; use in place of a list when you don’t need to change anything
Note
Correction: sets are mutable — you can add and remove elements from them after creation. It’s the individual elements of a set that must be immutable (hashable), not the set itself.
To see the functions available for a collection: print(dir(fruits)).
To see what a function does: print(help(fruits)).
fruits = ["apple", "orange", "blueberry"] # list
print(fruits[2]) # "blueberry"
print(fruits[0:2]) # ["apple", "orange"]
print("apple" in fruits) # True/False - search for an item
fruits[0] = "pineapple" # change an item by index
Note
Correction: fruits[0:2] prints ["apple", "orange"] (items at
index 0 and 1) — not the whole list.
List Functions¶
fruits.append("strawberry") # add to the end of the collection
fruits.remove("apple") # remove "apple"
fruits.insert(0, "banana") # insert "banana" at the front
fruits.sort() # sort the list alphabetically
fruits.reverse() # reverse the list
fruits.clear() # clear the list
fruits.index("apple") # returns the index of "apple"
fruits.count("banana") # returns how many times "banana" appears
Tuple Functions¶
Tuples are immutable, so they only support these two:
fruits.index("apple") # returns 0
fruits.count("banana") # returns 1
2D Lists¶
A list made up of lists. You need at least two 1D lists to build one.
groceries = [["apple", "orange", "banana"], ["celery", "carrot", "potato"]]
# or, using existing list variables
groceries = [fruits, vegetables]
If you print groceries it shows both lists on the same line, separated by a
comma. Access a specific item by its coordinates:
print(groceries[0][0]) # first item in the first list
Iterate over a 2D list with a nested loop:
for collection in groceries:
for food in collection:
print(food)
Dictionary¶
A collection of {key: value} pairs. Ordered and changeable, no duplicate keys.
capitals = {"USA": "Washington D.C.", "China": "Beijing"}
print(capitals.get("USA")) # "Washington D.C."
Check whether a key exists:
if capitals.get("USA"):
print("That item does exist")
else:
print("That item does not exist")
Update an existing item:
capitals.update({"USA": "New York"})
Remove the last-inserted item:
capitals.popitem()
Clear the dictionary:
capitals.clear()
Get all the keys (or values):
keys = capitals.keys()
for key in capitals.keys():
print(key)
# same pattern, but capitals.values() for values
Print all keys with their values:
items = capitals.items()
for key, value in capitals.items():
print(f"{key}: {value}")
Random¶
Must use import random.
import random
# random number
number = random.randint(low, high)
# random choice
options = ("rock", "paper", "scissors")
choice = random.choice(options)
# shuffle
cards = ["2", "3", "6", "K", "A"]
random.shuffle(cards)
Functions¶
A block of reusable code. Add () after the function name to invoke it.
def name():
# code, indented underneath the function definition
pass
name() # calling the function
With arguments:
def hi_name(name, age):
print(f"Hello {name}! You're {age} years old.")
hi_name("Greyson", 20)
Return Statement¶
Ends a function and sends a result back to the caller.
def add(x, y):
z = x + y
return z
print(add(3, 5))
def create_name(first, last):
first = first.capitalize()
last = last.capitalize()
return first + " " + last
full_name = create_name("Greyson", "T")
print(full_name)
Default Arguments¶
A default value for a parameter, used when the argument is omitted. Makes functions more flexible and reduces the number of required arguments.
def net_price(list_price, discount=0, tax=0.05):
return list_price * (1 - discount) * (1 + tax)
print(net_price(500)) # discount and tax fall back to defaults
print(net_price(500, 0.1)) # discount = 0.1, tax still defaults to 0.05
Keyword Arguments¶
An argument preceded by an identifier. Helps readability; order doesn’t matter.
def hello(greeting, title, first, last):
print(f"{greeting} {title} {first} {last}")
hello(title="Mr.", greeting="Hello", first="Guy", last="Smith")
You can mix positional and keyword arguments, but keyword arguments must come after positional ones when calling the function.
Arbitrary Arguments¶
A varying number of arguments.
*args— packs multiple non-keyword arguments into a tuple**kwargs— packs multiple keyword arguments into a dictionary*is the unpacking operator
def add(*args):
total = 0
for arg in args:
total += arg
return total
print(add(1, 2, 4))
def print_address(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_address(street="123 fake st.", city="Detroit", state="MI", zip="54321")
Note
Correction: the kwargs example looped with for key in kwargs.items()
but then referenced an undefined value. Unpack both with
for key, value in kwargs.items().
Both together:
def shipping_label(*args, **kwargs):
for arg in args:
print(arg, end=" ")
print()
if "apt" in kwargs:
print(f"{kwargs.get('street')} {kwargs.get('apt')}")
else:
print(f"{kwargs.get('street')}")
print(f"{kwargs.get('city')} {kwargs.get('state')} {kwargs.get('zip')} {kwargs.get('country')}")
shipping_label("Dr.", "Spongebob", "Squarepants", street="123 Fake St.",
city="Detroit", state="MI", zip="54321", country="US")
Note
Correction: the final print() in the original was missing its closing
parenthesis and quote.
Iterables¶
An object/collection that can return its elements one at a time so it can be looped over. Examples: list, tuple, set, string, dictionary.
numbers = [1, 2, 3, 4, 5]
for number in numbers:
print(number)
my_dictionary = {"A": 1, "B": 2}
for value in my_dictionary.values(): # values only
print(value)
for key, value in my_dictionary.items(): # keys and values
print(f"{key} = {value}")
for key in my_dictionary: # keys only
print(key)
Membership Operators¶
Test whether a value is found in a sequence (string, list, tuple, set,
dictionary), using in and not in.
word = "APPLE"
letter = input("Guess a letter in the secret word: ")
if letter in word:
print(f"There is a/an {letter} in the word")
elif letter not in word:
print(f"There is not a/an {letter} in the word")
students = {"Spongebob", "Patrick", "Sandy"}
student = input("Enter the name of a student: ")
if student in students:
print(f"{student} is a student")
else:
print(f"{student} is not a student")
grades = {"Sandy": "A", "Squidward": "B", "Spongebob": "C", "Patrick": "D"}
student = input("Enter the name of a student: ")
if student in grades:
print(f"{student}'s grade is {grades[student]}")
else:
print(f"{student} was not found")
List Comprehension¶
A concise way to create lists — more compact and often easier to read than a
traditional loop: [expression for value in iterable if condition].
doubles = [x * 2 for x in range(1, 11)]
print(doubles) # 2, 4, 6, 8 ... 20
numbers = [1, -2, 3, -4, 5, -6]
positive_nums = [num for num in numbers if num > 0]
negative_nums = [num for num in numbers if num < 0]
# sort positive and negative numbers into separate lists
grades = [85, 66, 93, 58, 97, 45]
passing = [grade for grade in grades if grade > 65]
failing = [grade for grade in grades if grade < 65]
fruits = ["apple", "orange", "banana", "coconut"]
fruits = [fruit.upper() for fruit in fruits]
print(fruits) # each item in uppercase
fruit_chars = [fruit[0] for fruit in fruits]
print(fruit_chars) # first letter of each fruit
Note
Correction: the positive/negative example originally used >= 0 and
<= 0, which puts 0 in both lists. Using > 0 and < 0 keeps the
two lists mutually exclusive.
Match-Case Statements (Switch)¶
An alternative to a long chain of elif statements — cleaner and more
readable. Runs the code for whichever case matches the value.
def day_of_week(day):
match day:
case 1:
return "It is Sunday"
case 2:
return "It is Monday"
case 3:
return "It is Tuesday"
case 4:
return "It is Wednesday"
case _:
return "Not a valid day"
print(day_of_week(1)) # "It is Sunday"
Note
Correction: the original call was day_of_week("1") (a string), which
would not match case 1 (an int) and would fall through to case _. Pass
the int 1 to match correctly.
Module¶
A file containing code you want to include in your program. Use import to
include a built-in or your own module — useful for breaking a large program
into reusable files.
print(help("modules")) # list all built-in modules
print(help("math")) # functions in a specific module, with descriptions
To make a module name shorter:
import math as m # m can be whatever you want
To import a single function:
from math import pi
# instead of 1 * math.pi, you can now use:
1 * pi
Creating a Module¶
Just make a new Python file — the file name is the module name. Once imported into the main file, its variables and functions carry over.
Variable Scope¶
Where a variable is visible/accessible. Scope resolution order (LEGB): Local → Enclosed → Global → Built-in.
Local — a function can see its own variables and any passed to it, but not variables from other functions.
Enclosed — a function defined inside another function.
Global — defined outside any function; used if a variable isn’t defined locally.
Built-in — names provided by an imported module/library, used unless overridden by a global, enclosed, or local value of the same name.
def func1():
print(x) # prints 3 - uses the global variable x
def func2():
x = 1
print(x) # prints 1 - the local variable takes precedence
x = 3
func1()
func2()
Note
Correction: the original example called func(1) and func(2) —
neither function exists under that name, and neither func1 nor func2
takes an argument. The calls should be func1() and func2().
if __name__ == '__main__':¶
Indicates that a script can either be imported as a module or run standalone.
When present, the functions and classes in the module can be reused without the
main block automatically executing. Usually placed just before a call to
main(). (Example files: script1.py, script2.py.)
Object-Oriented Programming¶
An object is a “bundle” of related attributes (variables) and methods (functions). A class is the blueprint used to design an object’s structure.
class Car:
def __init__(self, model, year, color, for_sale): # constructor
self.model = model
self.year = year
self.color = color
self.for_sale = for_sale
# methods go inside the class
def drive(self):
print(f"You drive the {self.model}")
def stop(self):
print(f"You stop the {self.model}")
car1 = Car("Mustang", 2024, "red", False)
car2 = Car("Corvette", 2022, "blue", True)
print(car1.model) # "Mustang"
print(car2.model) # "Corvette"
car1.drive() # "You drive the Mustang"
(Example files: car.py, oop.py.)
Class Variables¶
Shared among all instances of a class. Defined outside the constructor, so all objects created from the class share the same data.
class Student:
class_year = 2030 # shared among all students
num_students = 0
def __init__(self, name, age):
self.name = name
self.age = age
Student.num_students += 1 # counts students as you create them
Inheritance¶
Allows a class to inherit attributes/methods from another class — helps code
readability. Syntax: class Child(Parent):.
class Animal:
def __init__(self, name):
self.name = name
self.is_alive = True
def eat(self):
print(f"{self.name} is eating.")
class Dog(Animal):
def speak(self):
print("Woof")
class Cat(Animal):
def speak(self):
print("Meow")
class Mouse(Animal):
def speak(self):
print("Squeak")
Note
Corrections: Python’s keyword is lowercase class, not Class
(fixed throughout this section). Instance methods like speak also need
a self parameter.
Multiple Inheritance¶
Multiple inheritance — inheriting from more than one parent class:
class C(A, B):Multilevel inheritance — inheriting from a parent which itself inherits from another parent:
C(B)whereB(A)whereAis the base class.
class Animal:
def __init__(self, name):
self.name = name
def eat(self):
print(f"{self.name} is eating")
def sleep(self):
print(f"{self.name} is sleeping")
class Prey(Animal):
def flee(self):
print(f"{self.name} is fleeing")
class Predator(Animal):
def hunt(self):
print(f"{self.name} is hunting")
class Rabbit(Prey):
pass
class Hawk(Predator):
pass
class Fish(Prey, Predator):
pass
rabbit = Rabbit("Bugz")
rabbit.eat()
Note
Correction: empty class bodies (Rabbit, Hawk, Fish) need a
pass statement, or Python raises a syntax error.
Super()¶
Used in a child class to call a method from the parent class (superclass), extending the inherited method’s functionality. If a child method shares a name with a parent method, the child’s version overrides it — but both can still be called.
class Parent:
def describe(self):
print("Parent description")
class Child(Parent):
def describe(self):
print("Description") # child
super().describe() # parent
(Example file: super.py.)
Polymorphism¶
From the Greek “poly” (many) + “morphe” (form) — “to have many forms.”
Two ways to achieve polymorphism:
Inheritance — an object can be treated as the same type as its parent class.
Duck typing — an object just needs to have the necessary attributes/methods, regardless of its actual class.