Python Demo
Contents
Python Demo#
UW Geospatial Data Analysis
CEE467/CEWA567
David Shean
Overview#
Quick set of interactive examples to illustrate a few key aspects of Python and iPython.
Emphasis on concepts needed for lab exercises.
Tentative discussion topics#
Importing modules
Indentation
Variables
(don’t use “list” as a variable name)
Strings, formatting
Quoting
Tuples, lists, dictionaries
0 vs. 1 as first index
List comprehension
Indexing
Functions
Objects, classes - attributes and methods
Interpreting error/warning messages
Topics for later#
Main and doc strings
Import modules#
import os
os?
Type: module
String form: <module 'os' from '/srv/conda/envs/notebook/lib/python3.9/os.py'>
File: /srv/conda/envs/notebook/lib/python3.9/os.py
Docstring:
OS routines for NT or Posix depending on what system we're on.
This exports:
- all functions from posix or nt, e.g. unlink, stat, etc.
- os.path is either posixpath or ntpath
- os.name is either 'posix' or 'nt'
- os.curdir is a string representing the current directory (always '.')
- os.pardir is a string representing the parent directory (always '..')
- os.sep is the (or a most common) pathname separator ('/' or '\\')
- os.extsep is the extension separator (always '.')
- os.altsep is the alternate pathname separator (None or '/')
- os.pathsep is the component separator used in $PATH etc
- os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
- os.defpath is the default search path for executables
- os.devnull is the file path of the null device ('/dev/null', etc.)
Programs that import and use 'os' stand a better chance of being
portable between different platforms. Of course, they must then
only use functions that are defined by all platforms (e.g., unlink
and opendir), and leave all pathname manipulation to os.path
(e.g., split and join).
os.path?
Type: module
String form: <module 'posixpath' from '/srv/conda/envs/notebook/lib/python3.9/posixpath.py'>
File: /srv/conda/envs/notebook/lib/python3.9/posixpath.py
Docstring:
Common operations on Posix pathnames.
Instead of importing this module directly, import os and refer to
this module as os.path. The "os.path" name is an alias for this
module on Posix systems; on other systems (e.g. Windows),
os.path provides the same operations in a manner specific to that
platform, and is an alias to another module (e.g. ntpath).
Some of this can actually be useful on non-Posix systems too, e.g.
for manipulation of the pathname component of URLs.
os.path.split?
Signature: os.path.split(p)
Docstring:
Split a pathname. Returns tuple "(head, tail)" where "tail" is
everything after the final slash. Either part may be empty.
File: /srv/conda/envs/notebook/lib/python3.9/posixpath.py
Type: function
os.path.split??
Signature: os.path.split(p)
Source:
def split(p):
"""Split a pathname. Returns tuple "(head, tail)" where "tail" is
everything after the final slash. Either part may be empty."""
p = os.fspath(p)
sep = _get_sep(p)
i = p.rfind(sep) + 1
head, tail = p[:i], p[i:]
if head and head != sep*len(head):
head = head.rstrip(sep)
return head, tail
File: /srv/conda/envs/notebook/lib/python3.9/posixpath.py
Type: function
Variable assignment#
p = /srv/conda/envs/notebook/lib/python3.8/posixpath.py
File "/tmp/ipykernel_521/2673790754.py", line 1
p = /srv/conda/envs/notebook/lib/python3.8/posixpath.py
^
SyntaxError: invalid syntax
Errors and Warnings#
The above is an
Error
Stops execution
Read the output from the bottom up (trace can be long)
Different than a warning
p = "/srv/conda/envs/notebook/lib/python3.8/posixpath.py"
p
'/srv/conda/envs/notebook/lib/python3.8/posixpath.py'
Quotes#
p = '/srv/conda/envs/notebook/lib/python3.8/posixpath.py'
p
'/srv/conda/envs/notebook/lib/python3.8/posixpath.py'
Tuples#
os.path.split(p)
('/srv/conda/envs/notebook/lib/python3.8', 'posixpath.py')
mytuple = os.path.split(p)
mytuple
('/srv/conda/envs/notebook/lib/python3.8', 'posixpath.py')
Basic indexing#
Zero-based index
mytuple[0]
'/srv/conda/envs/notebook/lib/python3.8'
mytuple[1]
'posixpath.py'
mytuple[2]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
/tmp/ipykernel_521/2368449210.py in <module>
----> 1 mytuple[2]
IndexError: tuple index out of range
# Try to assign value to first item in tuple
mytuple[0] = 'something different'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_521/1845405818.py in <module>
1 # Try to assign value to first item in tuple
----> 2 mytuple[0] = 'something different'
TypeError: 'tuple' object does not support item assignment
Variable assignment and types#
a = 0
print(a)
type(a)
0
int
a = 'cool string'
print(a)
type(a)
cool string
str
What’s a str
?#
https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str
str?
Init signature: str(self, /, *args, **kwargs)
Docstring:
str(object='') -> str
str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or
errors is specified, then the object must expose a data buffer
that will be decoded using the given encoding and error handler.
Otherwise, returns the result of object.__str__() (if defined)
or repr(object).
encoding defaults to sys.getdefaultencoding().
errors defaults to 'strict'.
Type: type
Subclasses: DeferredConfigString, _rstr, LSString, include, ColorDepth, Keys, InputMode, CompleteStyle, SortKey
#Lots of methods, explore with tab completion
a.capitalize()
'Cool string'
b = a.upper()
b
'COOL STRING'
String formatting#
Many ways to accomplish this
Suggest you learn f-strings: https://realpython.com/python-f-strings/
f'Here is a {a}'
'Here is a cool string'
f'Here is a {a}, and another: {b}'
'Here is a cool string, and another: COOL STRING'
lon = -121.01234567
f'{lon:.2f}'
'-121.01'
Lists#
a = range(10)
a
range(0, 10)
range?
Init signature: range(self, /, *args, **kwargs)
Docstring:
range(stop) -> range object
range(start, stop[, step]) -> range object
Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).
Type: type
Subclasses:
a.start
0
t = tuple(a)
t
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Built-in functions#
https://docs.python.org/3/library/functions.html
len?
Signature: len(obj, /)
Docstring: Return the number of items in a container.
Type: builtin_function_or_method
len(t)
10
l = list(a)
l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
l.len()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/tmp/ipykernel_521/2236946988.py in <module>
----> 1 l.len()
AttributeError: 'list' object has no attribute 'len'
len(l)
10
Boolean#
0 in l
True
True?
Type: bool
String form: True
Namespace: Python builtin
Docstring:
bool(x) -> bool
Returns True when the argument x is true, False otherwise.
The builtins True and False are the only two instances of the class bool.
The class bool is a subclass of the class int, and cannot be subclassed.
int(True)
1
i = 'asdf' in l
i
False
int(False)
0
Conditional#
if 5 in l:
print("It's totally there!")
It's totally there!
if 'asdf' in l:
print("It's totally there!")
else:
print("Nope")
Nope
Indexing#
l[2]
2
l[-2]
8
l[-5:-1]
[5, 6, 7, 8]
l[::2]
[0, 2, 4, 6, 8]
l[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
#Operates in place
l.reverse()
l
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
l.sort()
l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Assignment#
#Lists can contain variable object types
l[0] = 'first'
l
['first', 1, 2, 3, 4, 5, 6, 7, 8, 9]
l[2]
2
l[2] = 12
l
['first', 1, 12, 3, 4, 5, 6, 7, 8, 9]
l[2] = l[2] + 1
l
['first', 1, 13, 3, 4, 5, 6, 7, 8, 9]
l[2] += 1
l
['first', 1, 14, 3, 4, 5, 6, 7, 8, 9]
Loops#
for i in l:
print(i)
first
1
14
3
4
5
6
7
8
9
for n, i in enumerate(l):
print(n, i)
0 first
1 1
2 14
3 3
4 4
5 5
6 6
7 7
8 8
9 9
#List comprehension
[print(i) for i in l]
first
1
14
3
4
5
6
7
8
9
[None, None, None, None, None, None, None, None, None, None]
l = list(range(10))
l_float = [float(i) for i in l]
l_float
[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
out = [i/2 for i in l]
out
[0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5]
Combining objects#
1 + 2
3
1.1 + 2
3.1
'asdf'+'jkl;'
'asdfjkl;'
'asdf'+1
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_521/917225922.py in <module>
----> 1 'asdf'+1
TypeError: can only concatenate str (not "int") to str
'asdf'+str(1)
'asdf1'
Find multiples of a given integer in a list#
Find all multiples of 5 in the list of integers between 0 and 100
Use the python modulo operator (
%
) - returns remainderIf remainder is 0, the number is a multiple!
l = list(range(100))
l
[0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99]
result = []
for i in l:
if i % 5 == 0:
result.append(i)
result
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
OK, what about multiples of 7#
result = []
for i in l:
if i % 7 == 0:
result.append(i)
result
[0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98]
OK, what about multiples of 10. This is getting old…#
result = []
for i in l:
if i % 10 == 0:
result.append(i)
result
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
Create a function#
def find_multiples_list(inlist, n):
result = []
for i in inlist:
if i % n == 0:
result.append(i)
return result
out = find_multiples_list(l, 5)
out
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
find_multiples_list(l, 7)
[0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98]
find_multiples_list(l, 10)
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]