Lecture nine - Python - introduction
Python's name is derived from the British comedy group Monty Python, (as a tribute from the Python creator Guido van Rossum).
Python is a high level language suitable for rapid development
Python has become one of the core languages of scientific / AI computing.
Guido van Rossum started to work on Python worked in the late 1980s as a "project for fun".
First version of Python (version 0.9.0) was published in February 1991. This release included already exception handling, functions, and the core data types of list, dict, str and others. It was also object oriented and had a module system
Python version 1.0 was released in January 1994 - added functional programming tools lambda, map, filter and reduce.
Python 2.0 was introduced in October 2000 - added list comprehensions, a full garbage collector and unicode support.
Next major release was Python 3.0 (also known as "Python 3000" and "Py3K") from 2008.
Python 3 is not backwards compatible with Python 2.x.
The emphasis in Python 3 had been on the removal of duplicate programming constructs and modules.
For beginners there is no real difference between Python 2 & 3. Basic are the same (except for print, and raw_input).
Python 2.x is legacy, Python 3.x is the present and future of the language.
The official end-of-life date for the Python 2 series is 2020.
Many programs and applications still use Python 2.x, so it is very much "alive". However, nowadays 344 of the 360 top packages for Python support 3.x.
Choose language according to libraries you want to use in your program.
Some of Python 3 features have been backported to the backward-compatible Python 2.6.x and 2.7.x version series.
Python looks like a pseudocode.
Goal: express concepts in fewer lines of code than might be used in languages such as C++ or Java.
Python code is usually stored in text files with the file ending ".py".
To run our Python program from the command line we use:
$ python myprogram.py
In Linux we can add the following
#!/usr/bin/env python
to the top to make it runnable.
We can also use interactive interpreter (shell) to execute commands "as we type them".
A code block is a group of statements that, together, perform a task.
Python programs get structured through indentation, i.e. code blocks are defined by their indentation.
Exemplary error:
IndentationError: expected an indented block (<string>, line XXX)
All statements with the same distance to the right belong to the same block of code, i.e. the statements within a block line up vertically.
This principle makes it easier to read and understand other people's Python code.
Spaces are the preferred indentation method.
Tabs should be used solely to remain consistent with code that is already indented with tabs.
In most of the editors there's a default to put 4 spaces on pressing the TAB button. It is a custum to use 4 spaces as indents in Python codes.
Python 3 disallows mixing the use of tabs and spaces for indentation.
Python 2 code indented with a mixture of tabs and spaces should be converted to using spaces exclusively.
Example, what is wrong about such a code checking whether the number is prime?
def is_prime(number):
for divisor in range(2,number):
if (number % divisor) == 0:
return False
return True
Notice that neither semicolons or curly brackets are necessary in Python.
PEP 8 - Style Guide for Python Code
Variable names in Python can contain alphanumerical characters a-z, A-Z, 0-9 and some special characters such as _.
Normal variable names must start with a letter.
By convention, variable names start with a lower-case letter, and Class names start with a capital letter.
Keywords list:
and, as, assert, break, class, continue, def, del, elif, else, except,
exec, finally, for, from, global, if, import, in, is, lambda, not, or,
pass, print, raise, return, try, while, with, yield
Example of reading the data (Python 2.x):
name = raw_input("What is your name? ")
city = raw_input("What city do you live in? ")
state = raw_input("What state is that in? ")
print name, "from", city, state
Wrong:
age = raw_input("Pardon my rudeness, but how old are you? ")
print "Wow! You look like you could be", age - (0.15*age), "!!"
As raw_input returns string.
age = input("Pardon my rudeness, but how old are you? ")
int(argument) forces the argument to be an integer by rounding down.
print "Wow! You look like you could be", int(age - (0.15*age)), "!!"
The input function behaves like the raw_input function from Python 2.
eval(input()) works like input() in Python 2.
The eval functions takes a string as argument and evaluates this string as a Python expression. The result of an expression is an object.
In other words eval do the same as if we were to type:
x = 1 + 2
Example, input:
x = input()
>> 12
print(x)
x = x + 2
x = eval(x)
x = x + 2
print(x)
Output:
12
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: must be str, not int
14
Example of printing the data on the screen (Python 3.x):
String formatting examples
print("str1", "str2", "str3") # The print statement concatenates strings with a space
print("str1", 1.0, False, -1j) # The print statements converts all arguments to strings
print("str1" + "str2" + "str3") # strings added with + are concatenated without space
print("value = %f" % 1.0) # we can use C-style string formatting
# this formatting creates a string
s2 = "value1 = %.2f. value2 = %d" % (3.1415, 1.5)
print(s2)
# alternative, more intuitive way of formatting a string
s3 = 'value1 = {0}, value2 = {1}'.format(3.1415, 1.5)
print(s3)
Output:
str1 str2 str3
str1 1.0 False (-0-1j)
str1str2str3
value = 1.000000
value1 = 3.14. value2 = 1
value1 = 3.1415, value2 = 1.5
Notice that # begins the comment in Python
Methods on objects are functions attached to the object's class; the syntax:
instance.method(argument)
stands for normal methods and functions execution.
There are two flavors: built-in methods (such as append() on lists) and class instance methods. Built-in methods are described with the types that support them.
Example, methods on integers:
x = 1
# type x. and press TAB
x.bit_length( x.denominator x.imag x.real
x.conjugate( x.from_bytes( x.numerator x.to_bytes(
Modules are functions and variables defined in separate files (sth. like headers in C++).
Items are imported using keywords from or import.
Modules are namespaces in Python, we access function by the name of the module followed by a dot and name of the function. It helps preventing to use two functions with the same name.
Most of the functionality in Python is provided by modules. The Python Standard Library is a large collection of modules that provides cross-platform implementations of common facilities such as access to the operating system, file I/O, string management, network communication, and much more.
import math
This includes the whole module and makes it available for use later in the program. For example, we can do:
import math
x = math.cos(2 * math.pi)
print(x)
Alternatively, we can chose to import all symbols (functions and variables) in a module to the current namespace (so that we don't need to use the prefix "math." every time we use something from the math module:
from math import *
x = cos(2 * pi)
print(x)
Once a module is imported, we can list the symbols it provides using the dir function:
import math
print(dir(math))
Output:
['__doc__', '__file__', '__name__', '__package__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']
The boolean operators are spelled out as the words and, not, or.
Bitwise operators (~,^,|,&,<<,>>) are like in C/C++.
The power operators in python are two asterisks:
>> a = 2 ** 2
4
During second lecture we discussed the way that variables in Python works.
How can we prove that x and y really reference the same object after the assignment y = x ?
The identity function id() can be used for this purpose.
Every instance (object or variable) has an identity, i.e. an integer which is unique within the script or program, i.e. other objects have different i identities.
Input:
x = 42
print(id(x))
y = x
print(id(x), id(y))
y = 78
print(id(x), id(y))
Output:
10107136
10107136, 10107136
10107136, 10108288
Mutable objects can be changed in place Immutable objects cannot be modified once created
Simple types in Python are immutable objects and it is not possible to modify its value. What we can do is to create new element from an original one.
Input:
a = "hello, world!"
a[2] = 'z'
a.replace('l', 'z', 1)
Output:
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
'hezlo, world!'
Operations on an object may fail, signifying that the given object is not of a suitable type.
Python is strongly typed, forbidding operations that are not well-defined (for example, adding a number to a string) rather than silently attempting to make sense of them.
Input:
x = 1.5
print(x, type(x))
isinstance(x, float)
x = int(x)
print(x, type(x))
Output:
1.5 <class 'float'>
True
1 <class 'int'>
The / operator always performs a floating point division in Python 3.x. This is not true in Python 2.x, where the result of / is an integer.
Input:
x = 7
print 1/x
print 1./x
print 1/float(x)
Output:
0
0.14285714285714285
0.14285714285714285
Operator == is used to compare values while is compare references:
Input:
a = [1,2]
b = [1,2]
c = a
a is b
a is c
a == b
Output:
False
True
True
In given example c can be interpreted as an alias for variable a.
General format:
if <condition is True>:
<code to execute if condition is True>
else:
<code to execute if condition is False>
Example:
# Get user's height
height = input("How tall are you? ")
if height > 150:
print "wow you're tall!"
if height >= 56:
print "ok"
else:
print "too short"
General format:
for some_variable in range:
do_something
Example:
for x in [1,2,3]:
print(x)
string = "Hello World"
for x in string:
print x
The ''range'' is seen so often in for statements that you might think range is part of the for syntax. It is not: it is a Python built-in function which returns a sequence, which meets the requirement of providing a sequence for the for statement to iterate over.
For loop examples using range:
Range with 1 argument goes from 0 through n-1:
for num in range(10):
print num
Range with 2 arguments goes from the first number through the last-1:
for num in range(7, 15):
print num
Range with 3 arguments goes from the first number through the second-1, in increments determined by the third number:
for num in range(2, 12, 2):
print num
A loop that will be repeated until a given condition changes:
count = 1
print "Count is initially", count
while count < 100:
count = count * 9
print "Now count is", count
Same as in C++ only difference is the use of :.
The else of the while/else will be executed if the 'while' loop is exited normally, meaning if the condition in the 'while' loop ever evaluates to False.
while n >= 0:
print n
n -= 1
else:
print "You've failed to enter a nonnegative number."
You can define default values for argument in functions.
All functions in Python have a return value. Functions without a return return the special value None.
def ret_5():
print 5
print ret_5()
Output:
5
None
To define function we use keyword def
def <name>(arg1, arg2, ..., argN):
<statements>
return <value>
Return sends a result back to the caller.
Arguments are passed by assignment. Assignment to argument names don't affect the caller unless argument is mutable.
Arguments and return types are not declared.
Example:
base = 10
exp = 4
def hello_world():
base = 20
print "inside of helloworld base is", base
return "Hello, world!"
print hello_world()
print "outside of helloworld base is", base
Output:
inside of helloworld base is 20
Hello, world!
outside of helloworld base is 10
Variables declared outside the function can be referenced within the function.
But these “global” variables cannot be modified within the function, unless declared global in the function.
y = 0
z = 0
def setx(y):
global x
x = y
global z
z = 99
print('x is %d' % x)
print(z)
print(y)
setx(10)
print(x)
print(y)
print(z)
0
0
x is 10
10
0
99
There is no function overloading in Python.
The number, order, names, or types of its arguments cannot be used to distinguish between two functions with the same name.
Two different functions can’t have the same name, even if they have different numbers of arguments.
But operator overloading – overloading +, ==, -, etc. is possible using special methods on various classes.
In Python we can also create unnamed functions, using the lambda keyword:
f1 = lambda x: x**2
# is equivalent to
def f1(x):
return x**2
This technique is useful for example when we want to pass a simple function as an argument to another function, like this:
# map(function, iterable, ...)
# Apply function to every item of iterable and return a list of the results.
map(lambda x: x**2, range(-3,4))
Output:
[9, 4, 1, 0, 1, 4, 9]
Examples:
new_string = "Hi Class!"
for letter in new_string:
print letter
s1 = "Hi"
s2 = "Class"
print s1 + s2
print "new_string[0] is", new_string[0]
print "new_string[0:3] is", new_string[0:3]
print "len(new_string) is:", len(new_string)
print "new_string.upper()", new_string.upper()
print "new_string.lower()", new_string.lower()
Check the Python documentation for more string methods!
Output:
H
i
C
l
a
s
s
!
HiClass
new_string[0] is H
new_string[0:3] is Hi
len(new_string) is: 9
new_string.upper() HI CLASS!
new_string.lower() hi class!
There are no arrays in Python! Lists are defined by brackets.
new_list = [3, 4, 5, 6]
print "new_list is:", new_list
# Just like strings, we can index & slice them
print "new_list[2] is:", new_list[2]
print "new_list[0:2] is:", new_list[0:2]
# And iterate through them:
for item in new_list:
print item
Lists, however, are mutable! So, if we want we can change the value of one element
new_list[2] = 100
print "new_list is:", new_list
# Or, add on a new element with append:
new_list.append(87)
print "new_list is:", new_list
# Or insert
new_list.insert(0, 200) # insert at position 0 the element 200
print "new_list is:", new_list
# Or even delete an element using remove
new_list.remove(100) # Write in the item that you want to remove from the list
print "new_list is:", new_list
There are following methods which can be executed on list:
l.append()
l.count()
l.extend()
l.index()
r.insert()
r.pop()
r.remove()
r.reverse()
r.sort()
Operator in is boolean test whether a value is inside a collection (often called a container in Python):
t = [1, 2, 4, 5]
3 in t
4 in t
4 not in t
Output:
False
True
False
For strings, it tests for substrings.
Be careful: the in keyword is also used in the syntax of for loops and list comprehensions.
List comprehension is a mechanism similar to math notation.
S = {x^2 : x in {0 ... 9}}
Generate a new list by applying a function to every member of an original list.
[ expression for name in list ]
li = [3, 6, 2, 7]
[ elem *2 for elem in li]
Output:
[6, 12, 4, 14]
If the elements of list are other collections, then name can be replaced by a collection of names that match the “shape” of the list members.
li = [(‘a’, 1), (‘b’, 2), (‘c’, 7)]
[ n * 3 for (x, n) in li ]
Output:
[3, 6, 21]
Filter determines whether expression is performed on each member of the list.
When processing each element of list, first check if it satisfies the filter condition.
If the filter condition returns False, that element is omitted from the list before the list comprehension is evaluated.
li = [3, 6, 2, 7, 1, 9]
[ elem * 2 for elem in li if elem > 4]
Output:
[12, 14, 18]
Tuples are immutable and defined by parentheses
new_tuple = (5, 6, 7, 8)
print "new_tuple is:", new_tuple
# We can index them, just like strings
print "new_tuple[2] is:", new_tuple[2]
# And iterate through them:
for item in new_tuple:
print item
Iterate throug tuple:
for index in range(len(new_tuple)):
print "Index is:", index
print "Value at that index is:", new_tuple[index]
We can also do something called tuple unpacking
new_tuple = (5, 6, 7, 8)
(a, b, c, d) = new_tuple
print "a is:", a
print "b is:", b
print "c is:", c
print "d is:", d
Make sure that you always have the same number of variables when you unpack a tuple!
Tuples are immutable. To change a tuple, we would need to first unpack it, change the values, then repack it.
Dictionaries are also like lists, except that each element is a key-value pair.
They are like a map container in C++.
The syntax for dictionaries is {key1 : value1}
params = {"parameter1" : 1.0,
"parameter2" : 2.0,
"parameter3" : 3.0}
print(type(params))
print(params)
params["parameter1"] = "A"
params["parameter2"] = "B"
Output:
<class 'dict'>
{'parameter1': 1.0, 'parameter2': 2.0, 'parameter3': 3.0}
https://en.wikipedia.org/wiki/Python_(programming_language)
http://www.scipy-lectures.org/language/first_steps.html
https://www.python-course.eu/python3_blocks.php
https://lectures.quantecon.org/py/about_py.html
http://sebastianraschka.com/Articles/2014_python_2_3_key_diff.html
http://www.seas.upenn.edu/~cis391/Lectures/python-tutorial.pdf