Metasnake Python Tips
Metasnake Python Tips
Python Basics
This handout will cover Python programming basics for those looking to use Python for data‑related
tasks. Python is a versatile language that is easy to learn and use. Check out store.metasnake.com for
more professional Python and data‑related materials.
Installation - Conda
• Install Anaconda (for Python 3) from anaconda.com/downlaod
• Install libraries:
• Launch Jupyter:
jupyter lab
Installation - Python.org
• Install Python 3
• Windows:
1
env/Scripts/activate
• Unix (Mac/Linux):
$ source env/bin/activate
• Install libraries:
• Launch Jupyter:
$ jupyter lab
Jupyter
• Command Mode:
– a ‑ Above
– b ‑ Below
– CTL-Enter ‑ Run
– c, x, v ‑ Copy, cut, paste
– ii ‑ Interrupt Kernel
– 00 ‑ Restart Kernel (zero two times)
• Edit Mode:
– TAB ‑ Completion
– Shift-TAB ‑ Documentation
– ESC ‑ Back to command mode w/o running
– CTL-Enter ‑ Run
• Hints:
Variables
• You don't need to declare variables. Just put their name followed by =
• Don't name variables keywords (see help(); keywords)
• Don't name variables built‑ins (see dir(__builtins__))
• See PEP 8 http://legacy.python.org/dev/peps/pep-0008/
Copyright 2024 2
Math
Use Python as a calculator.
Operation Result
41 + 1 42 Adds numbers
41 - 1 40 Subtracts numbers
41 * 1 42 Multiplies numbers
41 / 1 42 Divides numbers
5 % 2 1 Modulus operation (remainder)
8 ** 2 64 Power operation
Getting Help
Operation Result
dir(5) Lists attributes of integer
help(range) Shows documentation for range built‑in
range? Shows documentation for range built‑in. (Can also hit Shift-TAB four
times.) Jupyter only
pd.read_csv?? Shows source code for read_csv function in pandas. Jupyter only
help() Goes into help mode. Hit ENTER to exit.
Strings
Operation Result
name = 'paul' Create a variable with a string (can also use double quotes)
dir(name) List attributes of string
name.upper? Shows documentation for .upper method on string. Jupyter only
name.upper() Paul ‑ Uppercase string
name.find('au') 1 ‑ Index location of au
name[0] p ‑ Character at position 0
name[-1] l ‑ Last character in string
greeting = '\N{GRINNING FACE}' Create string with GRINNING FACE Unicode glyph (😀) (1f600 is
Hex for GRINNING FACE).
greeting = '\U0001f600' Create string with GRINNING FACE Unicode glyphs (1f600 is Hex
for GRINNING FACE).
A triple quoted string can span multiple lines. Python 3.6 introduced F‑strings:
minutes = 36
paragraph = f"""Greetings {name.title()},
Copyright 2024 3
Thank you for attending tonight.
We will be here for {minutes/60:.2f} hours
Long-winded talk.
Goodbye {name}!"""
Files
Writing to a UTF‑8 file:
Mode Meaning
'r' Read text file (default)
'w' Write text file (truncates if exists)
'x' Write text file, throw FileExistsError if exists.
'a' Append to text file (write to end)
'rb' Read binary file
'wb' Write binary (truncate)
'w+b' Open binary file for reading and writing
'xb' Write binary file, throw FileExistsError if exists.
'ab' Append to binary file (write to end)
Lists
Lists are ordered mutable sequences. They can be created with the list literal syntax:
Lists can also be created by calling the constructor with an optional sequence:
Copyright 2024 4
>>> 'Yoko' in people
False
If we need the index number during iteration, the enumerate function gives us a tuple of index item
pairs:
>>> people[0]
'Paul'
>>> people[-1] # len(people) - 1
'Ringo'
>>> people[1:2]
['John']
>>> people[:1] # Implicit start at 0
['Paul']
>>> people[1:] # Implicit end at len(people)
['John', 'George', 'Ringo']
>>> people[::2] # Take every other item
['Paul', 'George']
>>> people[::-1] # Reverse sequence
['Ringo', 'George', 'John', 'Paul']
Copyright 2024 5
Operation Provided By Result
No hash __hash__ Set to None to ensure you can't insert in dictionary
l += l2 __iadd__ Augmented (mutates l) concatenation
l *= 3 __imul__ Augmented (mutates l) repetition
for thing in l: __iter__ Iteration
l <= l2 __le__ Less than or equal. Compares items in lists from left
len(l) __len__ Length
l < l2 __lt__ Less than. Compares items in lists from left
l * 2 __mul__ Repetition
l != l2 __ne__ Not equal
repr(l) __repr__ Programmer friendly string
reversed(l) __reversed__ Reverse
foo * l __rmul__ Called if foo doesn't implement __mul__
l[idx] = 'bar' __setitem__ Index operation to set value
l.__sizeof__() __sizeof__ Bytes for internal representation
str(l) __str__ User friendly string
Operation Result
l.append(item) Append item to end
l.clear() Empty list (mutates l)
l.copy() Shallow copy
l.count(thing) Number of occurrences of thing
l.extend(l2) List concatenation (mutates l)
l.index(thing) Index of thing else ValueError
l.insert(idx, bar) Insert bar at index idx
l.pop([idx]) Remove last item or item at idx
l.remove(bar) Remove first instance of bar else ValueError
l.reverse() Reverse (mutates l)
l.sort([key=], reverse=False) In‑place sort, by optional key function (mutates l)
Slicing
Python uses the half‑open interval (Pandas .loc slicing is an exception). This means that it includes
the start index but not the end index. Also, the length equals the end index minus the start index.
Operation Result
names = ['lennon', Create a list
'mccartney',
'harrison', 'starr']
names[0] 'lennon' ‑ First item
Copyright 2024 6
Operation Result
names[-1] 'starr' ‑ Last item
names[0:3] ['lennon', 'mccartney', 'harrison'] ‑ First three items
names[:3] ['lennon', 'mccartney', 'harrison'] ‑ First three items
names[2:] ['harrison', 'starr'] ‑ From position three (index location 2) to end
names[-3:] ['mccartney', 'harrison', 'starr'] ‑ Third from last to end
names2 = names[:] Makes a shallow copy of names
names[::-1] ['starr', 'harrison', 'mccartney', 'lennon'] ‑ Copy in reverse order
(stride ‑1)
list(range(10))[::3] [0, 3, 6, 9] ‑ Every third item
Dictionaries
Dictionaries are mutable mappings of keys to values. Keys must be hashable, but values can be any
object. Here is a dictionary literal:
>>> instruments = {'Paul': 'Bass',
... 'John': 'Guitar'}
Dictionaries can also be made by calling the constructor with an optional mapping, an iterable, or
using keyword arguments. The iterable must be a sequence of 2‑pairs:
>>> instruments = dict([('Paul', 'Bass'),
... ('John', 'Guitar')])
Copyright 2024 7
Table 8: Magic Dictionary Methods
Operation Result
d.clear() Remove all items (mutates d)
d.copy() Shallow copy
d.fromkeys(iter, value=None) Create dict from iterable with values set to value
d.get(key, [default]) Get value for key or return default (None)
d.items() View of (key, value) pairs
d.keys() View of keys
d.pop(key, [default]) Return value for key or default (KeyError if not set)
d.popitem() Return arbitrary (key, value) tuple. KeyError if empty
d.setdefault(k, [default]) Does d.get(k, default). If k missing, sets to default
d.update(d2) Mutate d with values of d2 (dictionary or iterable of (key, value) pairs)
d.values() View of values
Looping
You can loop over objects in a sequence:
Copyright 2024 8
>>> for name in names:
... if name == 'Paul':
... break
... print(name)
John
The continue statement skips over the body of the loop, and continues at the next item of iteration:
Comprehensions
Comprehension constructs allow us to combine the functional ideas behind map and ‘filter“ into an
easy‑to‑read, single line of code. When you see code that is aggregating into a list (or dict, set, or
generator), you can replace it with a list comprehension (or dict, set comprehension, or generator
expression). Here is an example of the code smell:
• Assign the result (result) to brackets. The brackets signal to the reader of the code that a list
will be returned:
result = [ ]
• Place the for loop construct inside the brackets. No colons are necessary:
• Insert any operations that filter the accumulation after the for loop:
Copyright 2024 9
• Insert the accumulated object (num*num) at the front directly following the left bracket. Insert
parentheses around the object if it is a tuple:
Functions
Functions may take input, do some processing, and return output. You can provide a docstring directly
following the name and parameters of the function:
We can create anonymous functions using the lambda statement. Because they only allow an
expression following the colon; it is somewhat lacking in functionality. They are commonly used as a
key argument to sorted, min, or max:
Functions can have default arguments. Since Python 3.7, you can have more than 255 arguments
for a single function! Be careful with mutable types as arguments, as the default is bound to the
function when the function is created, not when it is called:
>>> add_n(10)
52
>>> add_n(3, -10)
-7
We can unpack arguments from a list or dictionary using the * and ** operators:
Copyright 2024 10
>>> add_three(*nums) # same as add_three(1, 2, 3)
6
Modules
A module is a Python file (ending in .py). Modules are files that end in .py. According to PEP 8, we
lowercase the module name and don't put underscores between the words in them. Any module
found in the PYTHONPATH environment variable or the sys.path list, can be imported.
A directory with a file named __init__.py is a package. A package can have modules in it as well
as sub packages. The package should be found in PYTHONPATH or sys.path to be imported. An example
might look like this:
packagename/
__init__.py
module1.py
module2.py
subpackage/
__init__.py
The __init__.py module can be empty or can import code from other modules in the package to
remove nesting in import statements.
You can import a package or a module:
import packagename
import packagename.module1
Assume there is a fib function in module1. You have access to everything in the namespace
of the module you imported. To use this function, you will need to use the fully qualified name,
packagename.module1.fib:
import packagename.module1
packagename.module1.fib()
If you only want to import the fib function, use the from variant:
from packagename.module1 import fib
fib()
package_fib()
Copyright 2024 11
Classes
Python supports object‑oriented programming but doesn't require you to create classes. You can
use the built‑in data structures to great effect. Here's a class for a simple bike. The class attribute,
num_passengers, is shared for all instances of Bike. The instance attributes, size and ratio, are unique
to each instance:
We can call the constructor (__init__), by invoking the class name. Note that self is the instance,
but Python passes that around for us automatically:
We can access both class attributes and instance attributes on the instance:
>>> bike.num_passengers
1
>>> bike.size
26
If an attribute is not found on the instance, Python will then look for it in the class, and it will
look through the parent classes to continue to try and find it. If the lookup is unsuccessful, an
AttributeError is raised.
Exceptions
Python can catch one or more exceptions (PEP 3110). You can provide a chain of different exceptions
to catch if you want to react differently. A few hints:
Copyright 2024 12
• Try to keep the block of the try statement down to the code that throws exceptions
• Be specific about the exceptions that you catch
• If you want to inspect the exception, use as to create a variable to point to it
If you use a bare raise inside of an except block, Python's traceback will point back to the location
of the original exception, rather than where it is raised from.
>>> avg('matt')
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for +: 'int'
and 'str'
You can raise an exception using the raise statement (PEP 3109):
>>> bad_code(1)
Traceback (most recent call last):
...
ValueError: Bad code
NumPy
The convention to import is:
import numpy as np
Copyright 2024 13
Operation Result
digits = np.array(range(10)) Make a NumPy array
digits.shape (10, ) ‑ Number of items (tuple)
digits.dtype int64 ‑ NumPy optimized block
np.log(digits) Return array with log of values
np.sin(digits) Return array with sine of values
digits.mean() Return mean of all values
digits + 10 Return array with value incremented by 10
nums = (np.arange(100) Create a two‑dimensional array (20 rows, 5 columns)
.reshape(20,5))
nums.mean() Return mean of all values
nums.mean(axis=0) Return array with mean of each column (5 results)
nums.mean(axis=1) Return array with mean of each row (20 results)
nums.mean(axis=1, keepdims=True) Return array with mean of each row (20 results), but in 2
dimensions
Operation Result
nums = (np.arange(100) Create a two‑dimensional array (20 rows, 5 columns)
.reshape(20,5))
nums[0] First row
nums[[0,5,10]] Rows at index positions 0, 5, and 10
nums[0:10] First ten rows
nums[:,0:3] All rows (:), first three columns
Operation Result
nums = (np.arange(100) Create a two‑dimensional array (20 rows, 5 columns)
.reshape(20,5))
nums % 2 == 0 Return array with booleans where values are even
nums[nums %2 == 0] Return array where values are even
nums.sum(axis=1) < 100 Return array with booleans where row sum is less than 100
nums[nums.sum(axis=1) < Return array with values where row sum is less than 100
100]
nums.mean(axis=0) > 50 Return array with booleans where column sum is greater than 50
nums[:, nums.mean(axis=0) > Return array with columns where column sum is greater than 50
50]
Copyright 2024 14
Pandas
Operation Result
import pandas as pd Import pandas
df = pd.read_csv('names.csv') Load dataframe
df.age >= 30 Return a boolean series where entries in the age column are >= 30
df[df.age >= 30] Return a dataframe with rows only where age >= 30
df.age + 2 Return series incrementing ages by 2
df.mean() Return series with mean of each column (column name in index)
Thanks
I hope you found this sheet useful. To receive more Python and data‑related materials, sign up for the
mailing list at store.metasnake.com.
Copyright 2024 15