Python Primer
Everything you already know but in Python
Python is a dynamically-typed, interpreted, object-oriented programming (OOP) language. It's known for being powerful but syntactically similar to pseudocode.
Syntax
Python's syntax is much lighter than other common object-oriented programming (OOP) languages. In Java, curly braces are used to create and separate blocks of code. In Python, however, whitespace/indentation is used to create blocks:
for i in range(10):
print(i)
This is both a blessing and a curse. This makes Python code quicker to write and more concise, but inconsistent indentation will cause syntax errors. Be mindful of unintended blocks appearing in your code.
Also, notice that there are no semicolons required to differentiate lines!
Typing
Python being "dynamically-typed" means that a variable's type is decided at runtime. That means we can create variables without explicitly telling Python what its type is:
number = 10
Python developers operate on the "duck typing" principle:
This means we care about an object having the functions and properties that we require, and not much about its class. As such, Python programs often don't involve type checking.
With that said, let's get into how basic programming is done in Python syntax.
Comments
One-line comments start with #
. Python (technically) supports multi-line comments with docstrings (''' ... '''
).
x = 1 # this is a comment
# this is another comment
'''
line 1
line 2
'''
Control Flow
Operators
Boolean operators use their English names, rather than symbols.
a and b or c and not (d or e)
Comparison operators (==, >=, etc.) are the same as in Java and C.
Interval comparisons can be used:
if 1 <= number <= 5:
Loops
The only valid for-loop formats:
# iterate over values
for value in lst:
# do something
# iterate over indices
for i in range(len(lst)):
# do something
While loops:
while condition:
# do something
Control Keywords
break
: exits a loopcontinue
: skips to the next iterationpass
: placeholder where code is required
if condition:
pass
else:
print("some actual code")
A for
loop can include an else
, which runs if the loop exits normally (without break
).
Strings and Lists
String Formatting
String formatting is typically done through an f-string:
animal = "Blahaj"
kind = "shark"
print(f"{animal} is a {kind}")
# 'Blahaj is a shark'
animal = "Ducks"
print(f"{animal} can fly. {animal} can also swim.")
# 'Ducks can fly. Ducks can also swim.'
List Joining
This syntax is a bit odd-we first state the joining String and then the Strings we want to join:
', '.join(['x', 'y', 'z'])
# "x, y, z"
List Comprehension
This doesn't exist in Java! We can process lists in a one-liner in Python:
squares = [i * i for i in range(5)]
print(squares) # [0, 1, 4, 9, 16]
Slices
Slices work with both lists and strings.
l = [1, 2, 3, 4, 5]
print(l[1:]) # [2,3,4,5]
print(l[:4]) # [1,2,3,4]
print(l[1:4]) # [2,3,4]
print(l[::-1]) # [5,4,3,2,1]
s = "CMSC388J"
print(s[:4]) # CMSC
print(s[4:]) # 388J
print(s[4:7]) # 388
print(s[:3:-1]) # J883
Data Structures
Dictionaries
This is the Python implementation of a hashmap.
# initialization
birth_years = {'bach': 1685, 'da vinci': 1452, 'erdos': 1913}
# setting a key and value pair
birth_years['jobs'] = 1955
# iteration
for name in birth_years:
print(name)
for name, year in birth_years.items():
print(name, year)
print('erdos' in birth_years) # True
print('scholze' in birth_years) # False
print(1685 in birth_years.values()) # True
print(1729 in birth_years.values()) # False
Tuples
You (probably) saw this in OCaml already. They're not as powerful or common here, but are still useful.
record = ('Priya', 20, [1, 2, 3])
print(record[0])
record[0] = 'Amy' # TypeError, tuples are immutable
Tuple unpacking:
nums = ((1,2,3), (4,5,6), (7,8,9))
for a, b, c in nums:
print(f'First: {a}, Second: {b}, Third: {c}')
Swapping variables:
a, b = 8, 4
a, b = b, a
print(a, b) # 4, 8
Sets
Python implementation of a hashset. Supports set operations.
visited = {4, 2, 1, 3, 5}
visited.add('cookie')
visited.remove(2)
print(1 in visited)
print(6 not in visited)
s1 = {1, 2, 3}
s2 = {1, 2, 3, 4}
print(s1 <= s2) # subset check
print(s1 | s2) # union
print(s1 & s2) # intersection
Functions
Definition
def distance(p1, p2) -> float:
x_dist = (p1[0] - p2[0]) ** 2
y_dist = (p1[1] - p2[1]) ** 2
return (x_dist + y_dist) ** 0.5
Functions as Objects
def apply(func):
data = [1, 2, 5, 6, 1, 3, 0, 5, 8, 9, 2]
return func(data)
Returning multiple values:
def animals():
return 'duck', 'camel'
a = animals() # ('duck', 'camel')
d, c = animals() # d='duck', c='camel'
Function Arguments
Python supports positional and keyword arguments.
def print_stuff(x, y, z):
print(x, y, z)
print_stuff('a', z='b', y='c') # prints a c b
Default arguments:
def print_something(x=0):
print(x)
print_something() # 0
print_something(1) # 1
Lambda Functions
This shouldn't require explanation if you took CMSC330, but don't worry if you haven't.
a = lambda x, y: x + y
print(a(1, 2)) # 3
print(list(map(lambda x: x * 2, [1,2,3]))) # [2,4,6]
Built-in Functions
s = "darth vader"
print(type(s))
print(dir(s))
l = [True, True, True]
print(len(l)) # 3
Conversions:
print(str(123)) # "123"
print(int("456")) # 456
Map and filter:
def square(x): return x ** 2
print(list(map(square, range(5))))
def long_string(s): return len(s) >= 8
print(list(filter(long_string, ['fantastic', 'python', 'acrobatic'])))
Any/All:
def is_prime(p): ...
print(all(map(is_prime, range(100))))
print(any([False, True, False]))
Classes
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String greet() {
return "Hello, my name is " + name + " and I am " + age + " years old.";
}
public static void main(String[] args) {
Person p = new Person("Alice", 20);
System.out.println(p.greet());
}
}
Exceptions
Raising Exceptions
Since Python is dynamically-typed, we need more runtime error-checking.
def process(data):
if not all(map(lambda x: x > 0, data)):
raise ValueError("All values must be positive.")
process(["hello", "world"])
Handling Exceptions
For our purposes, this isn't any different from Java:
data = [(1,2,3,4,5), {-1,2,30,4,-5}, range(20)]
for datum in data:
try:
process(datum)
except ValueError as e:
print(f"Invalid input {datum}: {str(e)}")
else:
print("Nothing went wrong")
finally:
print("End of try-except block")
Imports
Import modules or packages with the import keyword
import <package_name>
Assign your own name with the as keyword
import <package_name> as <new_name>
Import specific methods, classes, or packages
from <package_name> import <method/class>
Gets rid of dot notation: package_name.method()
becomes method()
Import modules:
import math
import math as m
from math import sqrt
__init__.py
file in its directory.Final Notes
We tried to give an overview of the Python language, but we definitely didn’t cover all features available.
- Please refer to the standard library docs: https://docs.python.org/3/library/index.html
- And to the language reference: https://docs.python.org/3/reference/index.html
- We’ll go over more interesting features in coming weeks (generators, context managers, file I/O, enums, RNGs, other tools…)