Nikolay Koldunov
koldunovn@gmail.com
This is part of Python for Geosciences notes.
================
Python uses duck typing
a = 10
a
10
type(a)
int
z = 10.7
z
10.7
type(z)
float
b = '2'
b
'2'
Some operations are not allowed on different types:
a+b
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-7-ca730b97bf8a> in <module> ----> 1 a+b TypeError: unsupported operand type(s) for +: 'int' and 'str'
But some of them are allowed:
a*b
'2222222222'
Might be a source of confusion :)
String variables can be combined:
c = ' guys walk into a bar'
c
' guys walk into a bar'
b+c
'2 guys walk into a bar'
In order to include variable of another type in to string you have to convert it:
str(a)+c
'10 guys walk into a bar'
In IPython you can get the list of object's methods and attributes by typing dot and pressing TAB:
c.
Methods are basically default functions that can be applied to our variable:
c.upper()
' GUYS WALK INTO A BAR'
c.title()
' Guys Walk Into A Bar'
c.count('a')
3
c.find('into')
11
If you need help on method in IPython type something like:
c.find?
Or open bracket and press SHIFT+TAB:
c.find(
Int variable is also an object:
a.bit_length()
4
Methods can be combined (kind of a pipeline)
c.title().count('a').bit_length()
2
There are several other interesting variable types in Python, but the one we would need the most is the list.
In order to create list put coma separated values in square brackets:
l = [1,2,3,4,5]
l
[1, 2, 3, 4, 5]
Sort of similar to Matlab variables, but not exactly.
Values in list can be any type:
l = ['one', 'two', 'three', 'four', 'five']
l
['one', 'two', 'three', 'four', 'five']
Combined
l = ['one', 2, 'three', 4.0, 3+2]
l
['one', 2, 'three', 4.0, 5]
Any type means ANY type:
l = ['one', 2, 'three', [1,2,3,4,5], 3+2]
l
['one', 2, 'three', [1, 2, 3, 4, 5], 5]
You can access list values by index:
l[0]
'one'
Oh, yes, indexing starts with zero, so for Matlab users the zero is the new one :) See discussion on the matter here.
l[1]
2
Let's have a look at the 4th element of our list:
l[3]
[1, 2, 3, 4, 5]
It's also a list, and its values can be accessed by indexes as well:
l[3][4]
5
You also can acces multiple elements of the list using slices:
l
['one', 2, 'three', [1, 2, 3, 4, 5], 5]
l[1:3]
[2, 'three']
Slice will start with the first slice index and go up to but not including the second slice index.
l[3]
[1, 2, 3, 4, 5]
This loop will print all elements from the list l
l = ['one', 2, 'three', [1,2,3,4,5], 3+2]
for element in l:
print(element)
one 2 three [1, 2, 3, 4, 5] 5
Two interesting thins here. First: indentation, it's in the code, you must use it, otherwise code will not work:
for element in l:
print(element)
File "<ipython-input-32-c5812f5beca3>", line 2 print(element) ^ IndentationError: expected an indented block
Second - you can iterate through the elements of the list. There is an option to iterate through a bunch of numbers as we used to in Matlab:
for index in range(5):
print(l[index])
one 2 three [1, 2, 3, 4, 5] 5
where range is just generating a sequence of numbers:
list(range(5))
[0, 1, 2, 3, 4]
We are not going to use branches in this notes, but this is how they look like just as another example of indentation use:
x = -1
if x > 0:
print("Melting")
elif x == 0:
print("Zero")
else:
print("Freezing")
Freezing
Pure python does not do much. To do some specific tasks you need to import modules. Here I am going to demonstrate several ways to do so.
The most common one is to import complete library. In this example we import urllib2 - a library for opening URLs using a variety of protocols.
import requests
Here we get information from FESOM website site. Note how function get is called. We have to use name of the library, then dot, then name of the function from the library:
response = requests.get('http://fesom.de/')
response.headers
{'Date': 'Tue, 28 Apr 2020 15:58:46 GMT', 'Server': 'Apache', 'Content-Language': 'en', 'Vary': 'Accept-Encoding', 'Content-Encoding': 'gzip', 'Cache-Control': 'max-age=0', 'Expires': 'Tue, 28 Apr 2020 15:58:46 GMT', 'X-UA-Compatible': 'IE=edge', 'X-Content-Type-Options': 'nosniff', 'Content-Length': '7375', 'Keep-Alive': 'timeout=3, max=500', 'Connection': 'Keep-Alive', 'Content-Type': 'text/html; charset=utf-8'}
Another option is to import it like this:
from requests import *
In this case all functions will be imported in to the name-space and you can use get directly, without typing the name of the library first:
response = get('http://fesom.de/')
response.headers
{'Date': 'Tue, 28 Apr 2020 15:58:48 GMT', 'Server': 'Apache', 'Content-Language': 'en', 'Vary': 'Accept-Encoding', 'Content-Encoding': 'gzip', 'Cache-Control': 'max-age=0', 'Expires': 'Tue, 28 Apr 2020 15:58:48 GMT', 'X-UA-Compatible': 'IE=edge', 'X-Content-Type-Options': 'nosniff', 'Content-Length': '7375', 'Keep-Alive': 'timeout=3, max=500', 'Connection': 'Keep-Alive', 'Content-Type': 'text/html; charset=utf-8'}
But generally this is very bad idea and is not recomended, because your name-space is populated by things that you don't really need and it's hard to tell where the function comes from.
whos
Variable Type Data/Info --------------------------------------------------- ConnectTimeout type <class 'requests.exceptions.ConnectTimeout'> ConnectionError type <class 'requests.exceptions.ConnectionError'> DependencyWarning type <class 'urllib3.exceptions.DependencyWarning'> FileModeWarning type <class 'requests.exceptions.FileModeWarning'> HTTPError type <class 'requests.exceptions.HTTPError'> NullHandler type <class 'logging.NullHandler'> PreparedRequest type <class 'requests.models.PreparedRequest'> ReadTimeout type <class 'requests.exceptions.ReadTimeout'> Request type <class 'requests.models.Request'> RequestException type <class 'requests.exceptions.RequestException'> RequestsDependencyWarning type <class 'requests.exceptio<...>questsDependencyWarning'> Response type <class 'requests.models.Response'> Session type <class 'requests.sessions.Session'> Timeout type <class 'requests.exceptions.Timeout'> TooManyRedirects type <class 'requests.exceptions.TooManyRedirects'> URLRequired type <class 'requests.exceptions.URLRequired'> a int 10 adapters module <module 'requests.adapter<...>es/requests/adapters.py'> api module <module 'requests.api' fr<...>ackages/requests/api.py'> auth module <module 'requests.auth' f<...>ckages/requests/auth.py'> b str 2 c str guys walk into a bar certs module <module 'requests.certs' <...>kages/requests/certs.py'> chardet module <module 'chardet' from '/<...>ges/chardet/__init__.py'> check_compatibility function <function check_compatibility at 0x107e7f3b0> codes LookupDict <lookup 'status_codes'> compat module <module 'requests.compat'<...>ages/requests/compat.py'> cookies module <module 'requests.cookies<...>ges/requests/cookies.py'> cryptography_version str 2.9.2 delete function <function delete at 0x108e7a050> element int 5 exceptions module <module 'requests.excepti<...>/requests/exceptions.py'> get function <function get at 0x108e565f0> head function <function head at 0x108e5b440> hooks module <module 'requests.hooks' <...>kages/requests/hooks.py'> index int 4 l list n=5 logging module <module 'logging' from '/<...>3.7/logging/__init__.py'> models module <module 'requests.models'<...>ages/requests/models.py'> options function <function options at 0x108e5b560> packages module <module 'requests.package<...>es/requests/packages.py'> patch function <function patch at 0x108e76f80> post function <function post at 0x108e76e60> put function <function put at 0x108e76ef0> pyopenssl module <module 'urllib3.contrib.<...>b3/contrib/pyopenssl.py'> request function <function request at 0x108e09680> requests module <module 'requests' from '<...>es/requests/__init__.py'> response Response <Response [200]> session function <function session at 0x108e615f0> sessions module <module 'requests.session<...>es/requests/sessions.py'> status_codes module <module 'requests.status_<...>equests/status_codes.py'> structures module <module 'requests.structu<...>/requests/structures.py'> urllib3 module <module 'urllib3' from '/<...>ges/urllib3/__init__.py'> utils module <module 'requests.utils' <...>kages/requests/utils.py'> warnings module <module 'warnings' from '<...>b/python3.7/warnings.py'> x int -1 z float 10.7
You can import only function that you need:
from requests import get
response = get('http://fesom.de/')
response.headers
{'Date': 'Tue, 28 Apr 2020 15:58:50 GMT', 'Server': 'Apache', 'Content-Language': 'en', 'Vary': 'Accept-Encoding', 'Content-Encoding': 'gzip', 'Cache-Control': 'max-age=0', 'Expires': 'Tue, 28 Apr 2020 15:58:50 GMT', 'X-UA-Compatible': 'IE=edge', 'X-Content-Type-Options': 'nosniff', 'Content-Length': '7375', 'Keep-Alive': 'timeout=3, max=500', 'Connection': 'Keep-Alive', 'Content-Type': 'text/html; charset=utf-8'}
Or import library as alias in order to avoid extensive typing:
import requests as rq
response = rq.get('http://fesom.de/')
response.headers
{'Date': 'Tue, 28 Apr 2020 15:58:51 GMT', 'Server': 'Apache', 'Content-Language': 'en', 'Vary': 'Accept-Encoding', 'Content-Encoding': 'gzip', 'Cache-Control': 'max-age=0', 'Expires': 'Tue, 28 Apr 2020 15:58:51 GMT', 'X-UA-Compatible': 'IE=edge', 'X-Content-Type-Options': 'nosniff', 'Content-Length': '7375', 'Keep-Alive': 'timeout=3, max=500', 'Connection': 'Keep-Alive', 'Content-Type': 'text/html; charset=utf-8'}