Kushal Keshavamurthy Raviprakash
kushalkr2992@gmail.com
This notebook is a part of the Python for Earth and Atmospheric Sciences workshop.
We are going to use the interactive python shell first to write simple commands.
To do this:
python
and press Enter
. You will see the python prompt >>>
with some details about the version of python etc...print("Hello World!")
and press the Enter
key.NOTE : Here I am using something called the IPython shell(Interactive Python shell). It works just the same as the python shell. Later on, we will move to IPython rather than the regular Python shell.
Now you have succesfully run your first python program. Albeit an extremely simple one.
The interactive python shell in its simplest form, can be used as a calculator. For example:
print("Hello World!")
Hello World!
1 + 1
2
2 + 5
7
11 - 1
10
2 * 5
10
2**3
8
2/2
1.0
Here are some common operators in python:
Operation | Symbol | Symbol name |
---|---|---|
Brackets | ( ) |
Parantheses |
exponentiation | ** |
double-asterisk |
Multiplication | * |
asterisk |
Modulo | % |
Percent |
Floor Division | // |
double-slash |
Float Division | / |
slash |
Addition | + |
plus |
Subtraction | - |
minus or hyphen |
Operation | Symbol |
---|---|
Greater than | > |
Lesser than | < |
Greater than or equal to | >= |
Lesser than or equal to | <= |
Equal to | == |
not Equal to | != |
Object Identity | is |
Negated Object Identity | is not |
Operation | Symbol |
---|---|
Logical AND | and |
Logical OR | or |
Logical NOT | not |
The logical operators typically return a boolean value or type i.e True
or False
. In Python, False
, numeric zero, None
, empty objects are all treated as False
.
Let's print something
print('Hello World!')
print('Hello Again')
print('I love printing!')
Hello World! Hello Again I love printing!
User input can be obtained using the input
function.
name = input("Enter your name: ")
print("Hello,", name)
print(type(name))
Enter your name: Kushal Hello, Kushal <class 'str'>
To make our lives easier, we python multiple commands of python inside a file with an extension of .py
. This file with the .py
extension is called a python script.
For the first few programs, I would like you to get used to using just a text editor and a terminal to write your programs and later move to an IDE(Integrated Development Environment) such as spyder (Scientific PYthon Development EnviRonment).
I will be using the Atom text editor to write my python scripts.
Atom is a cross-platform text-editor which is a very stable and supports python.
You can download and install Atom by from Atom.io.
Note: I will be using jupyter-notebook
the entire duration of the workshop (I like to have my code and execution is the same place). My recommendation is to use jupyter-notebook
unless you really need to use a text editor and a terminal because you can do everything with jupyter-notebook
that can be done with a text editor and a terminal and in some cases, more.
If you do decide to use a text editor and a terminal, the following steps are for you.
Once you fire up the atom editor, it should look like this:
Create a new file called ex1.py
and put in all the commands you entered in the previous section on the interactive shell into it.
In the terminal, go to the directory where the ex1.py file is saved and type python ex1.py
.
Did you find anything fishy? What do you think happened?
What would you do if I want you to get the output to print only certain lines in that file without deleting any of the lines in the file?
# %load scripts/basics_of_python/ex1.py
# Remove the "#" from the above line and hit Ctrl/Cmd + Enter in jupyter-notebook
Hello World! Hello World! Hello Again I love printing! 2 7 10 10 8 1.0
In the previous exercise, in order to print only certain lines of the code, we insert the octothorpe or hash or pound symbol (#) at the beginning of the line that you don't want to print.
Try it out.
Python code is usually stored in text files with the file ending ".py
":
myprogram.py
Every line in a Python program file is assumed to be a Python statement, or part thereof.
#
(optionally preceded by an arbitrary number of white-space characters, i.e., tabs or spaces). Comment lines are usually ignored by the Python interpreter.To run our Python program from the command line we use:
$ python myprogram.py
On UNIX systems it is common to define the path to the interpreter on the first line of the program (note that this is a comment line as far as the Python interpreter is concerned):
#!/usr/bin/env python
If we do, and if we additionally set the file script to be executable, we can run the program like this:
$ myprogram.py
NOTE : The material in this cell was obtained from Lectures on Scientific Computing with Python
Also, if your text encoding is different or if you are from another country, you may get errors about ASCII encodings. To take care of that, it is advised to insert
# -*- coding: utf-8 -*-
at the beginning of all your your ".py"
files.
According to Wikipedia:
In computer programming, a variable or scalar is a storage location paired with an associated symbolic name (an identifier), which contains some known or unknown quantity of information referred to as a value.
All it means is that a variable is a location in memory which has a value associated with it and you can access this location by the specific name provided to that location called the variable name.
Creating and using variables of different types are shown below:
a = 2
type(a)
int
b = 3
type(b)
int
c = a + b
type(c)
int
c
5
print(c)
5
Floats are short for floating point numbers. This means that real numbers such as 3.141592654, 0.1, 73.0000005 etc... are floating point numbers.
NOTE : Floats, just like integers don't have infinite precision i.e the computer can only store values with finite (still enormously large) precision.
a = 3.
type(a)
float
b = 7.0
type(b)
float
c = a + b
type(c)
float
print(c)
10.0
Boolean variables are variables that can have only one of two values: True
or False
.
Boolean variables are used extensively with conditional statements, relational operators and logical operators.
Let's try out a few.
a = 10;b = 5
print(a>b)
True
(a > 10) and (b > 1)
False
(a > 10) or (b > 1)
True
not(a > 10) and (b > 1)
True
Moving the parantheses around could get you different results with the same expression.
Tip: Make (correct) use of parantheses in long expression for better code readability.
not(a) > (10 and (b > 1))
False
Strings are a sequence of characters where each character is of the type "string". In other words, individual characters are strings of length 1.
NOTE :
a = "Hello"
type(a)
str
b = " World"
print(type(b))
<class 'str'>
c = a + b
type(c)
str
print(c)
Hello World
Some operations are not possible and Python throws an error. Let us try one such operation.
a = 5
b = '2'
c = a + b
print (c)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-29-11aaba454972> in <module>() 1 a = 5 2 b = '2' ----> 3 c = a + b 4 print (c) TypeError: unsupported operand type(s) for +: 'int' and 'str'
But some might be allowed and it can be confusing.
a * b
'22222'
If you noticed, I used the same variable names and the same addition operation but Python still did something different for each kind of input. This is called operator overloading (It is a concept from object-oriented programming which I will touch upon later).
Python uses duck typing. It is basically a test for whether an operator is possible on a a certain type of variable.
Everything in python is what we call an object. Variables, data types, classes, functions, are all objects.
In python, you can access an object's methods or attributes using the dot (.) notation.
An object's attributes are variables or information about an object that is particular to that object. Similarly, methods are default functions that can be used only with that object.
For now, our objects will just be variables.
Let us try some things.
a = "hello"
b = "world"
print(a.capitalize())
print(b.upper())
Hello WORLD
Here, the variables a
and b
are both strings. In Python, string objects have built-in methods such as:
To get to know the available methods for an objects, in the interactive shell, type dir(object)
where object
is the name of your object or variable.
dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
String variables can be combined with other types. For example:
a = "I am "
b = 25
c = " years old"
# we can use a number inside strings by forcing it to be a string, like so
print(a + str(b) + c) # the forcing of one data type to another data type is called type casting
I am 25 years old
You can also format your output in a preferred format.
age = 25
print("I am %s years old" % (str(age))) # Old format
# OR
print("I am {} years old".format(age)) # New format
I am 25 years old I am 25 years old
For more information on formatting your output, refer pyformat.info
Now let's try one of the methods of strings
a = "hello"
a.count('l')
2
print(len(a)) # Returns the length of the string a
print(len("hello")) # this is the same thing as above
5 5
As defined earlier, a string is a sequence of characters. Since it is a sequence, python allows us to access each element of the string. The method by which we can access individual elements of a string is called indexing.
Indexing basically means that each character is given an index (number) according to its position in the string. For example, in the string "Python", the letter P has index 0, the letter y has index 1 and so on.
Accessing a value at a particular index is done by string[index] where string is your string or the name of the variable contatining the string and index is the position of the character you require.
NOTE : Indexing starts at 0 in Python instead of 1.
lang = "Python"
lang[0]
'P'
lang[1]
'y'
Here's something awesome:
lang[-1]
'n'
lang[-2]
'o'
Before we move on, I would like to introduce the concept of mutability.
Mutability means "the ability to change".
In python, there are few datatypes that can be changed and few that cannot. The data types which can be changed are called mutable and the datatypes which cannot be changed are called immutable.
In python, lists and dictionaries (both of which you will see later) are mutable datatypes. Whereas numbers, strings and tuples(also covered subsequently) are immutable datatypes.
Examples:
lang[0] = "C" # I cannot change Python to Cython
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-42-6827d5216706> in <module>() ----> 1 lang[0] = "C" # I cannot change Python to Cython TypeError: 'str' object does not support item assignment
But, one workaround is:
lang ="Cython" # Reassigning the string
lang
'Cython'
Another workaround is:
lang.replace("C","P") # Using the replace() method.
'Python'
# Here's another method
lang = "C" + "ython"
lang
'Cython'
NOTE : We will introduce slicing in the next few sections and the same rules for slicing of lists can be applied to strings since each character is a string by itself.
Till now we've looked at some simple datatypes such as integers, floating point numbers, booleans and strings. It becomes inconvenient when you have lots of variables. Python has a separate datatype called a list which is basically a sequence of values (could be integers, strings etc..)
NOTE :
You can create a list by putting values separated by commas (,
) enclosed with square brackets ([]
). a generic list would look like this:
[value1, value2, value3,....]
Let's create some lists.
lst = [1, "Panda", 3.14, True]
print(lst, type(lst))
[1, 'Panda', 3.14, True] <class 'list'>
# We can have lists within lists
m = [lst, [1,"hey"]]
m
[[1, 'Panda', 3.14, True], [1, 'hey']]
# Lists can also be created like this
n = list(["Hello", "Everyone"] + lst)
n
['Hello', 'Everyone', 1, 'Panda', 3.14, True]
n = list
Accessing values within lists is by indexing.
m[0]
[1, 'Panda', 3.14, True]
For accessing values inside lists which are themselves inside lists,
m[0][2] # Accesses 3rd value of the 1st list inside m
3.14
Multiple values inside a list can be accessed thorugh slicing.
Slicing generally follows the form [ start : end-1 : skip ]
lst[1:4]
['Panda', 3.14, True]
lst[:-1] # Returns elements from first through last but but one element
[1, 'Panda', 3.14]
lst[2:] # Returns elements from 3rd through last elements
[3.14, True]
lst[:] # return all elements
[1, 'Panda', 3.14, True]
lst[:-1:2] # Returns every 2nd element
[1, 3.14]
Let's list the attributes and methods of the list lst
.
dir(lst)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
Let me add some elements to the list lst
.
Here's one way of doing that:
lst.append("Valar")
lst.append("Morghulis")
lst
[1, 'Panda', 3.14, True, 'Valar', 'Morghulis']
Here's another way of adding items to lists:
lst + ["Valar","Dohaeris"] # You can add multiple items this way
# In this method, you will also need to assign it back to the original
# list if you want to retain the additions
[1, 'Panda', 3.14, True, 'Valar', 'Morghulis', 'Valar', 'Dohaeris']
There is yet another way of adding multiple items to the list.
lst.extend(("Valar", "Dohaeris")) # The extend() method only takes in an iterable as argument
lst
[1, 'Panda', 3.14, True, 'Valar', 'Morghulis', 'Valar', 'Dohaeris']
In a file called ex2.py, create a list having the strings "Luke", "Leia"
and "Obiwan"
. Create another list with contents "Yoda", "Vader"
and "Death Star"
. Create a third list with contents "Storm Trooper"
and "R2D2"
.
HINT : Look up the remove()
method of lists or the pop()
method or the built-in del
command in Python. I recommend you create the list and perform the removal of elements using all 3 possibilities.
address
with your address as a list i. e.# %load scripts/ex2.py
#!/usr/bin/env python3
"""
@author: Kushal Keshavamurthy Raviprakash
"""
a = ["Luke", "Leia", "Obiwan"]
b = ["Yoda", "Vader", "Death Star"]
c = ["Storm Trooper", "R2D2"]
# Solution:
d = a + b + c # concatenating the list items.
# Method 1: using del
print("Method 1: Using del")
print("Before: ", d)
del d[4], d[4], d[4]
# Err what?! yeah that's right. because 4 is the index "Vader"
# in the list d. but when you delete "Vader", "Death Star"
# occupies index 4 and same happens to "Storm Trooper".
print("After: ",d,"\n")
# Method 2: Using the remove(method)
d = a + b + c # Resetting list d
print("Method 2: Using remove()")
print("Before: ", d)
d.remove('Vader')
d.remove('Death Star')
d.remove('Storm Trooper')
print("After: ",d,"\n")
# Method 3: Using the pop() method
d = a + b + c # Resetting list d
print("Method 3: Using pop()")
print("Before: ", d)
d.pop(4)
d.pop(4)
d.pop(4)
print("After: ",d,"\n")
# Part two of the exercise
address = [1001, "East", "10th", "street", "GY428", "Bloomington", "IN", 47408]
print(address[0] + address[-1])
address[1] = "North"
print(address)
Method 1: Using del Before: ['Luke', 'Leia', 'Obiwan', 'Yoda', 'Vader', 'Death Star', 'Storm Trooper', 'R2D2'] After: ['Luke', 'Leia', 'Obiwan', 'Yoda', 'R2D2'] Method 2: Using remove() Before: ['Luke', 'Leia', 'Obiwan', 'Yoda', 'Vader', 'Death Star', 'Storm Trooper', 'R2D2'] After: ['Luke', 'Leia', 'Obiwan', 'Yoda', 'R2D2'] Method 3: Using pop() Before: ['Luke', 'Leia', 'Obiwan', 'Yoda', 'Vader', 'Death Star', 'Storm Trooper', 'R2D2'] After: ['Luke', 'Leia', 'Obiwan', 'Yoda', 'R2D2'] 48409 [1001, 'North', '10th', 'street', 'GY428', 'Bloomington', 'IN', 47408]
a = (2,'flash', [3.14, ("a","b")])
a
(2, 'flash', [3.14, ('a', 'b')])
a[0]
2
a[1]
'flash'
a[2]
[3.14, ('a', 'b')]
a[2][0]
3.14
a[2][1]
('a', 'b')
a[2][1][0]
'a'
Let's try modifying the tuple
a[0] = 3
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-69-91049de15e23> in <module>() ----> 1 a[0] = 3 TypeError: 'tuple' object does not support item assignment
you get a type error because tuples are immutable. However, like strings, you can create new tuples with the existing values along with the additions or deletions. For example:
print(a)
a = (3,) + a[1:]
print(a)
(2, 'flash', [3.14, ('a', 'b')]) (3, 'flash', [3.14, ('a', 'b')])
Dictionaries are collections of elements just like lists and tuples. The difference is that dictionaries are not ordered and are not referenced by position (index) but by keys.
The keys are generally strings or integers. and the values, like lists and tuples, can be anything.
NOTE : Dictionaries are very important because most of the times, as we'll see later, Atmospheric Science/ Earth Science data in NetCDF format are stored in dictionaries.
Dictionaries are delimited by "{}
" just like lists are delimited by "[]
" and tuples by "()
"
info = {'name': "Kushal", 'age': 25, 'address': {'street': "1001, E10th street, GY428", 'city': "Bloomington", 'state': "IN", 'Pin': 47408}}
info
{'address': {'Pin': 47408, 'city': 'Bloomington', 'state': 'IN', 'street': '1001, E10th street, GY428'}, 'age': 25, 'name': 'Kushal'}
Dictionaries are accessed by keys.
print(info['name'])
print(info['age'])
Kushal 25
this is much more intuitive than using info[0]
and info[1]
.
Collections within dictionaries are referenced by indices if the collections are list/tuples and keys if the collections are dictionaries.
info['address']['Pin']
47408
Dictionaries are mutable.
info['age'] = 24
info
{'address': {'Pin': 47408, 'city': 'Bloomington', 'state': 'IN', 'street': '1001, E10th street, GY428'}, 'age': 24, 'name': 'Kushal'}
We have built-in methods for dictionaries as well.
info.keys()
dict_keys(['name', 'age', 'address'])
info.values()
dict_values(['Kushal', 24, {'street': '1001, E10th street, GY428', 'city': 'Bloomington', 'state': 'IN', 'Pin': 47408}])
info.items()
dict_items([('name', 'Kushal'), ('age', 24), ('address', {'street': '1001, E10th street, GY428', 'city': 'Bloomington', 'state': 'IN', 'Pin': 47408})])
In a file called ex3.py, create a variable of the dictionary type called myaddress
having the strings "street", "city", "state"
and "PIN"
as keys and whatever you want for the values for each key .
fulladdress
.NOTE : Values must be strings for this exercise only, but can be anything in general.
# %load scripts/basics_of_python/ex3.py
#!/usr/bin/env python3
"""
@author: Kushal Keshavamurthy Raviprakash
"""
myaddress = {'street':"1001 E10th Street, GY428", 'city':"Bloomington",
'state':"IN", 'PIN':"47408"}
print(myaddress)
fulladdress = myaddress['street'] + \
myaddress['city'] + \
myaddress['state'] + myaddress['PIN']
print(fulladdress)
print(myaddress.keys())
myaddress['PIN'] = "47405"
{'street': '1001 E10th Street, GY428', 'city': 'Bloomington', 'state': 'IN', 'PIN': '47408'} 1001 E10th Street, GY428BloomingtonIN47408 dict_keys(['street', 'city', 'state', 'PIN'])
We learnt how to perform some actions using operators and some datatypes in the previous sections but, sometimes we come across the need for performing some action if a condition is met and a different action if some other condition is met. This is possible by what is called Branching.
In Python, branching is performed by using the if-elif-else
construct.
Indentation (tabs or spaces) in Python is what tells you where a particular block of code (body of code viz. if-statement, function, loop, etc...) is starting or ending. If your code is not indented properly, you might encounter a lot of errors.
the basic construct is as follows:
if (conditional statements):
commands
elif (conditional statements):
commands
else:
commands
NOTE : The indentation is generally 4 spaces. (Personally, I use 2 spaces).
Let us try out some if-statements:
a = 7 ; b = 3
if (a > b):
print('a is greater')
else:
print('b is greater')
a is greater
a = 7 ; b = 3; c = 10
if ((a > b) and (a > c)):
print('a is the largest')
elif ((b > a) and (b > c)):
print('b is the largest.')
else:
print('c is the largest.')
c is the largest.
you can use if-statements
inside if-statements
.
a = 7 ; b = 3; c = 10
if (a >= b):
if (a >= c):
print('a is the largest')
else:
print('c is the largest.')
elif (b >= c):
print('b is the largest.')
else:
print('b is the largest.')
c is the largest.
Iterating means to repeat something and computers are really good at doing it efficiently. In Python, the iteration control structures are called loops. We will discuss few loops in this section.
i = 0
while(i<10):
print(i)
i = i + 1 # This can also be written as i+=1
0 1 2 3 4 5 6 7 8 9
the for
loop is used for looping a particular number of times or through iterables such as lists, tuples, dictionaries
and a particular iterable called range
which generates a sequence of numbers. The for
loop has the following syntax:
for variable in iterable:
commands
Let's do a few examples:
for i in range(10):
print(i)
0 1 2 3 4 5 6 7 8 9
cities = ['Bloomington', 'Boston', 'San Francisco', 'Maryland', 'Boulder', 'Seattle']
for city in cities:
print(city)
Bloomington Boston San Francisco Maryland Boulder Seattle
for
loops can be used with dictionaries in conjunction with a function called zip
.
animals = {'lion': "carnivore", 'zebra': "herbivore", 'cheetah': "carnivore", 'giraffe': "herbivore"}
for animal, foodtype in zip(animals.keys(), animals.values()):
print('{0:s} : {1:s}'.format(animal, foodtype))
lion : carnivore zebra : herbivore cheetah : carnivore giraffe : herbivore
for animal, foodtype in animals.items():
print('{0:s} : {1:s}'.format(animal, foodtype))
lion : carnivore zebra : herbivore cheetah : carnivore giraffe : herbivore
for key in animals:
print(key, animals[key])
lion carnivore zebra herbivore cheetah carnivore giraffe herbivore
a = "Hello"
for i in a:
print(i)
H e l l o
We have seen different ways of accessing collections. Let's move on to writing functions of our own.
Most of the times you will need to reuse some code and it is not worth the time to repeat the entire code everytime it is required. So, we put our code into functions that can be called every time we need to use that particular code.
the syntax for functions in Python is as follows:
def function_name (parameters):
commands
return values
Let's write a couple of functions of our own:
def area(r):
return 3.14 * r**2
area(2)
12.56
You can have multiple function definitions in one file.
def area_triangle(base, height):
area = 0.5 * base * height
return area
def area_rectangle(width, height):
area = width * height
return area
print("The area of the triangle is: ", area_triangle(4, 8))
print("The area of the rectangle is: ", area_rectangle(4,8))
The area of the triangle is: 16.0 The area of the rectangle is: 32
Write functions for the conversion of temperature from Fahrenheit to Celsius and vice versa. The relationships are as follows: $$ \begin{align*} C &= \frac{5}{9}\left(F - 32\right) \\ F &= \left(\frac{9}{5}C\right) + 32 \end{align*} $$
You need two functions called f2c
and c2f
. Put both the functions in a file called ex4.py
def f2c(f):
return ((5/9.) * (f - 32))
def c2f(c):
return ((9/5.)*c + 32)
print(f2c(72))
print(c2f(27))
22.22222222222222 80.6
We now know how to define functions that can be defined and reused in a file. But, what if you want to use the functions you defined in a file in another program?
Python allows you to make use of pre-written functions and some other things through what are known as modules. Modules are basically definitions of functions and few other things put into a file. They can be "imported" wherever needed.
The name of the module is the name of the file with the functions you have saved without the .py
suffix
Similarly, a collection of modules is called a package. Eg. Numpy, Scipy, matplotlib etc...
Let's turn the exercise 4 solution into a module.
Since our file name here is ex4.py, our module will be called ex4.
You can directly import a file as module if you have the file in the same directory as the code you are running. If otherwise, you will have to append the path as shown below.
import sys
sys.path.append('scripts/basics_of_python/') #My file is inside the directory scripts/
The above commands are telling python to look inside the basics_of_python/
directory inside my scripts/
directory. The reason being, python does not look inside that folder by default.
import ex4
ex4.c2f(32)
89.6
ex4.f2c(54)
12.222222222222223
There are lots of modules already available for use with python. We will also look at some of them (Numpy, Scipy, matplotlib, etc...)
Before that, here's a sample to show the different ways of importing modules:
import urllib
file_list = urllib.request.urlopen('ftp://ftp.unidata.ucar.edu/')
html = file_list.read()
html.splitlines()
[b'-r--r--r-- 1 ftp ftp 830 Mar 13 1997 README', b'drwxrwxr-x 17 ftp ftp 4096 Aug 30 2016 pub', b'-rw-r--r-- 1 ftp ftp 26 Oct 03 2013 robots.txt']
from urllib import *
file_list = request.urlopen('ftp://ftp.unidata.ucar.edu/')
html = file_list.read()
html.splitlines()
[b'-r--r--r-- 1 ftp ftp 830 Mar 13 1997 README', b'drwxrwxr-x 17 ftp ftp 4096 Aug 30 2016 pub', b'-rw-r--r-- 1 ftp ftp 26 Oct 03 2013 robots.txt']
from urllib.request import urlopen
file_list = urlopen('ftp://ftp.unidata.ucar.edu/')
html = file_list.read()
html.splitlines()
[b'-r--r--r-- 1 ftp ftp 830 Mar 13 1997 README', b'drwxrwxr-x 17 ftp ftp 4096 Aug 30 2016 pub', b'-rw-r--r-- 1 ftp ftp 26 Oct 03 2013 robots.txt']
import urllib as ul
file_list = ul.request.urlopen('ftp://ftp.unidata.ucar.edu/')
html = file_list.read()
html.splitlines()
[b'-r--r--r-- 1 ftp ftp 830 Mar 13 1997 README', b'drwxrwxr-x 17 ftp ftp 4096 Aug 30 2016 pub', b'-rw-r--r-- 1 ftp ftp 26 Oct 03 2013 robots.txt']
Until now, almost every concept we have looked at, pertains to procedural programming.
Object-oriented programming on the other hand, is a different kind of programming philosophy wherein an object has both data and functions attached to it. The data are called attributes and the functions are called methods.
In the real world, everything is a replica of a type or class. For example, individual people, though they possess different characteristics, are of the type or class humans beings since all humans are made up of DNA, have cells in their body, have a brain etc... and each individual is said to be an instance of the human class.
Syntax for objects:
The syntax for referring to an object's attribute is to put a dot (.)
after the object name followed by the name of the attribute. Example: a.year
Similarly, the syntax to refer to an object's method is to again use the the dot (.)
after the object name and within parantheses ()
, the arguments to the method if any. Example: a.run()
a = "hello"
a.upper()
'HELLO'
a.capitalize()
'Hello'
Classes are blueprints for creating objects by defining initial attributes and methods that will be attached to the instances. For example, the class string
contains the definition of the isupper()
method which we can see in the string "Hello" as well as the string "everyone".
Here are some rules for creating your own classes:
class
.__init__
method. The reason is, the __init__
method is called whenever a new object of the class is created and all your initializations go into this method.__init__
method can take in arguments that are then used to define attributes while initializing the object.def
keyword.self
within the class definition.All this theory is a lot to digest!
Let's try some examples:
class Person(object):
def __init__(self, name):
self.name = name
def talk(self):
if self.name.capitalize() == "Batman":
print("I'm Batman!")
else:
print("Hello! My name is {0:s}".format(self.name))
print("I am your friend.")
person1 = Person("Peter")
person2 = Person("Batman")
person1.talk()
Hello! My name is Peter I am your friend.
person2.talk()
I'm Batman!
The above class is a really basic example of a class. There are so many concepts such as inheritance, polymorphism etc..., that I haven't discussed in here. I want to keep it simple for the beginners. Once you are familiar with some python, there are lots of resources to learn the advanced concepts.
In the field of Earht and Atmospheric Sciences, more often than not, we need to read in data from a file and then perform some operation on the data and then write out the results to a file.
We will look at input/output with text files.
Python intefaces with files of any kind through file objects.
File objects are instantiated (created) using the built-in open
statement.
fname = open('data/foo.txt', 'r')
data = fname.read()
fname.close()
print(data)
print(type(data))
Thundercats pok pok aesthetic pug cred brunch bespoke normcore tousled venmo kombucha Poutine hashtag cray biodiesel hot chicken vice helvetica, retro post-ironic everyday carry pop-up tbh pok pok. <class 'str'>
The open
statement has different modes in which it interacts with files:
'r'
- read mode (cannot write or modify the file)'w'
- write mode (can write to file)'r+'
- read and write mode. File pointer is at the beginning of the file'w+'
- write and read mode. Overwrites if file exists or new file is created if it doesn't.'a'
- append mode. File pointer is at the end of the file if file exists or new file is created if it doesn'tThere are other modes of file access, but these are the most common ones that we are likely to use.
NOTE : It is very important that you use the close()
method and close the file after you are done using the data. There are chances that the file can be tampered with, if it is not closed properly.
Let's try some methods with the file object and put them into a list.
fname = open('data/foo.txt', 'r')
data = fname.readline()
print(data)
data = fname.readlines()
print(data)
print(type(data))
fname.close()
Thundercats pok pok ['aesthetic pug cred\n', 'brunch bespoke normcore\n', 'tousled venmo kombucha\n', 'Poutine hashtag cray\n', 'biodiesel hot chicken\n', 'vice helvetica, retro post-ironic\n', 'everyday carry pop-up\n', 'tbh pok pok. \n'] <class 'list'>
the readline()
method produces a string whereas the readlines()
method produces a list of strings with each line in the file as one element of the list.
Let's write a file and save it as baz.txt
.
data = ['a b c d e\n', 'f g h i j\n', 'k l m n o\n', 'p q r s t\n', 'u v w x y\n', 'z']
f = open('baz.txt', 'w')
for line in data:
f.write(line)
f.close()
data = ['a b c d e\n', 'f g h i j\n', 'k l m n o\n', 'p q r s t\n', 'u v w x y\n', 'z']
f = open('baz.txt', 'w')
f.writelines(data)
f.close()