x = 42
In Jupyter/IPython (an interactive version of Python), the last line of a cell will automatically be printed to screen so we don’t actually need to explicitly call print().
x # Anything after the pound/hash symbol is a comment and will not be run
Arithmetic Operators
Below is a table of the syntax for common arithmetic operations in Python:
Operator
Description
addition
subtraction
multiplication
division
exponentiation
integer division / floor division
modulo
Let’s have a go at applying these operators to numeric types and observe the results.
1 + 2 + 3 + 4 + 5 # add
But the syntax // allows us to do “integer division” (aka “floor division”) and retain the int data type, it always rounds down.
101 / 2
We refer to this as “integer division” or “floor division” because it’s like calling int on the result of a division, which rounds down to the nearest integer, or “floors” the result.
int(101 / 2)
None
NoneType is its own type in Python. It only has one possible value, None - it represents an object with no value. We’ll see it again in a later chapter.
x = None
Strings
Text is stored as a data type called a string. We can think of a string as a sequence of characters.
Actually they are a sequence of Unicode code points. Here’s a great blog post on Unicode if you’re interested.
We write strings as characters enclosed with either:
single quotes, e.g., 'Hello'
double quotes, e.g., "Goodbye"
There’s no difference between the two methods, but there are cases where having both is useful (more on that below)! We also have triple double quotes, which are typically used for function documentation (more on that in a later chapter), e.g., """This function adds two numbers""".
my_name = "Tomas Beuzen"
If the string contains a quotation or apostrophe, we can use a combination of single and double quotes to define the string.
sentence = "It's a rainy day."
Comparison Operators
We can compare objects using comparison operators, and we’ll get back a Boolean result:
Operator
Description
x == y
is x equal to y?
x != y
is x not equal to y?
x > y
is x greater than y?
x >= y
is x greater than or equal to y?
x < y
is x less than y
?
x <= y
is x less than or equal to y?
x is y
is x the same object as y?
Boolean Operators
We also have so-called “boolean operators” which also evaluates to either True or False:
Operator
Description
x and y
are x and y both True?
x or y
is at least one of x and y True?
not x
is x False?
print(f"Bit representation of the number 5: {5:0b}")
print(f"Bit representation of the number 4: {4:0b}")
print(f" ↓↓↓")
print(f" {5 & 4:0b}")
print(f" ↓ ")
print(f" {5 & 4}")
Casting
Sometimes we need to explicitly cast a value from one type to another. We can do this using functions like str(), int(), and float(). Python tries to do the conversion, or throws an error if it can’t.
x = 5.0
type(x)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-60-7124e8e12e61> in <module>
----> 1 float("hello")
ValueError: could not convert string to float: 'hello'
3. Lists and Tuples
Lists and tuples allow us to store multiple things (“elements”) in a single object. The elements are ordered (we’ll explore what that means a little later). We’ll start with lists. Lists are defined with square brackets [].
my_list = [1, 2, "THREE", 4, 0.5]
another_list = [1, "two", [3, 4, "five"], True, None, {"key": "value"}]
another_list
Tuples look similar to lists but have a key difference (they are immutable - but more on that a bit later). They are defined with parentheses ().
today = (1, 2, "THREE", 4, 0.5)
Indexing and Slicing Sequences
We can access values inside a list, tuple, or string using square bracket syntax. Python uses zero-based indexing, which means the first element of the list is in position 0, not position 1.
my_list
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-74-075ca585e721> in <module>
----> 1 my_list[5]
IndexError: list index out of range
Note from the above that the start of the slice is inclusive and the end is exclusive. So my_list[1:3] fetches elements 1 and 2, but not 3.
Strings behave the same as lists and tuples when it comes to indexing and slicing. Remember, we think of them as a sequence of characters.
alphabet = "abcdefghijklmnopqrstuvwxyz"
List Methods
A list is an object and it has methods for interacting with its data. A method is like a function, it performs some operation with the data, but a method differs to a function in that it is defined on the object itself and accessed using a period .. For example, my_list.append(item) appends an item to the end of the list called my_list. You can see the documentation for more list methods.
primes = [2, 3, 5, 7, 11]
primes
Sets
Another built-in Python data type is the set, which stores an un-ordered list of unique items. Being unordered, sets do not record element position or order of insertion and so do not support indexing.
s = {2, 3, 5, 11}
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-93-c9c96910e542> in <module>
----> 1 s[0]
TypeError: 'set' object is not subscriptable
Mutable vs. Immutable Types
Strings and tuples are immutable types which means they can’t be modified. Lists are mutable and we can assign new values for its various entries. This is the main difference between lists and tuples.
names_list = ["Indiana", "Fang", "Linsey"]
names_list
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-97-bd6a1b77b220> in <module>
----> 1 names_tuple[0] = "Not cool guy"
TypeError: 'tuple' object does not support item assignment
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-99-9bfcf81dbcf0> in <module>
----> 1 my_name[-1] = "q"
TypeError: 'str' object does not support item assignment
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-101-415ce6bd0126> in <module>
----> 1 x[1] = 7
TypeError: 'tuple' object does not support item assignment
Note that the method lower doesn’t change the original string but rather returns a new one.
all_caps
We can also chain multiple methods together (more on this when we get to NumPy and Pandas in later chapters):
"".join(caps_list).lower().split(" ")
String formatting
Python has ways of creating strings by “filling in the blanks” and formatting them nicely. This is helpful for when you want to print statements that include variables or statements. There are a few ways of doing this but I use and recommend f-strings which were introduced in Python 3.6. All you need to do is put the letter “f” out the front of your string and then you can include variables with curly-bracket notation {}.
name = "Newborn Baby"
age = 4 / 12
day = 10
month = 6
year = 2020
template_new = f"Hello, my name is {name}. I am {age:.2f} years old. I was born {day}/{month:02}/{year}."
template_new
5. Dictionaries
A dictionary is a mapping between key-values pairs and is defined with curly-brackets:
house = {
"bedrooms": 3,
"bathrooms": 2,
"city": "Vancouver",
"price": 2499999,
"date_sold": (1, 3, 2015),
condo = {
"bedrooms": 2,
"bathrooms": 1,
"city": "Burnaby",
"price": 699999,
"date_sold": (27, 8, 2011),
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-126-ab081f66baa5> in <module>
----> 1 condo["not-here"]
KeyError: 'not-here'
There’s no real difference between the two methods above, [] is apparently marginally faster…
tup = tuple() # empty tuple
7. Conditionals
Conditional statements allow us to write programs where only certain blocks of code are executed depending on the state of the program. Let’s look at some examples and take note of the keywords, syntax and indentation.
name = "Tom"
if name.lower() == "tom":
print("That's my name too!")
elif name.lower() == "santa":
print("That's a funny name.")
else:
print(f"Hello {name}! That's a cool name!")
print("Nice to meet you!")
Use keywords if, elif and else
The colon : ends each conditional expression
Indentation (by 4 empty space) defines code blocks
In an if statement, the first block whose conditional statement returns True is executed and the program exits the if block
if statements don’t necessarily need elif or else
elif lets us check several conditions
else lets us evaluate a default block if all other conditions are False
the end of the entire if statement is where the indentation returns to the same level as the first if keyword
If statements can also be nested inside of one another:
name = "Super Tom"
if name.lower() == "tom":
print("That's my name too!")
elif name.lower() == "santa":
print("That's a funny name.")
else:
print(f"Hello {name}! That's a cool name.")
if name.lower().startswith("super"):
print("Do you really have superpowers?")
print("Nice to meet you!")
Inline if/else
We can write simple if statements “inline”, i.e., in a single line, for simplicity.
words = ["the", "list", "of", "words"]
x = "long list" if len(words) > 10 else "short list"
Truth Value Testing
Any object can be tested for “truth” in Python, for use in if and while (next chapter) statements.
True values: all objects return True unless they are a bool object with value False or have len() == 0
False values: None, False, 0, empty sequences and collections: '', (), [], {}, set()
Read more in the docs here.
x = 1
if x:
print("I'm truthy!")
else:
print("I'm falsey!")
Short-circuiting
Python supports a concept known as “short-circuting”. This is the automatic stopping of the execution of boolean operation if the truth value of expression has already been determined.
fake_variable # not defined
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-142-38b1451e4717> in <module>
----> 1 fake_variable # not defined
NameError: name 'fake_variable' is not defined
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-144-a7196cc665d5> in <module>
----> 1 True and fake_variable
NameError: name 'fake_variable' is not defined