Python Programming

Alex Pacheco

Research Computing

What is Python?

  • A general-purpose programming language (1980) by Guido van Rossum
  • Intuitive and minimal coding
  • Dynamically typed
  • Automatic memory management
  • Interpreted not compiled
  • Free (developed under an OSI-approved open-source license) and portable

What can Python do?

  • web development (server-side),
  • system scripting,
  • connecting to database systems and to read and modify files,
  • handle big data and perform complex mathematics,
  • rapid prototyping, or for production-ready software development.

Why Python?

  • works on different platforms (Windows, Mac, Linux, Raspberry Pi, etc).
  • has a simple syntax similar to the English language.
  • has syntax that allows developers to write programs with fewer lines than some other programming languages.
  • runs on an interpreter system, meaning that code can be executed as soon as it is written. This means that prototyping can be very quick.
  • can be treated in a procedural way, an object-orientated way or a functional way.
  • The most recent major version of Python is Python 3
    • However, Python 2, although not being updated with anything other than security updates, is still quite popular.

Python Syntax compared to other programming languages

  • Python was designed for readability, and has some similarities to the English language with influence from mathematics.
  • Python uses new lines to complete a command, as opposed to other programming languages which often use semicolons or parentheses.
  • Python relies on indentation, using whitespace, to define scope; such as the scope of loops, functions and classes.
  • Other programming languages often use curly-brackets for this purpose.

Installing Python

  • Many PCs and Macs will have python already installed.
  • To check if you have python installed:
    • Open Command Line (cmd.exe) on Windows
    • Open Terminal on Linux or Mac
  • and run the following command
    • python --version

Installing from Source

  • Python is a free and open source software that can downloaded and installed from https://www.python.org/downloads/
  • Latest stable release for Python 3 is 3.7.4
  • A large majority of users still use the older version Python 2.
  • Python 2 is scheduled for end-of-life on Jan 1, 2020 and migrating to Python 3 is strongly recommended.

Anaconda Python Distribution

  • Anaconda Python distribution is the most popular platform for Python
  • It provides

    • a convenient install procedure for over 1400 Data Science libraries for Python and R
    • conda to manage your packages, dependencies, and environments
    • anaconda navigator: a desktop portal to install and launch applications and editors including Jupyter, RStudio, Visual Studio Code, and Spyder
  • Visit https://go.lehigh.edu/linux to use Anaconda (and other Linux software) installed and maintained by the Research Computing group on your local Linux laptop or workstation

Using Python

  • launch python by typing python on the *nix command line or cmd.exe in windows
  • If you have installed Anaconda Python, then you can launch IPython, an enhanced python shell, from the command line IPython Shell
  • Open Anaconda Navigator to launch
    • Jupyter QtConsole
    • Spyder, an open source IDE for python (Available on LUapps)
    • Jupyter (formely IPython) notebooks
    • Jupyter Lab (formerly Jupyter Hub)

Which one to use?

  • You should choose one that suits your need
    • Python Shell, IPython or QtConsole: for interactive use when you do not want to save your work
    • Spyder or other IDE's such as PyCharm: for writing scripts that you want to save for later reuse
    • Jupyter Lab or Notebooks: for writing scripts and workflows that you can share with others, ideal for reproducible research or data reporting
      • This presentation is written in Jupyter Notebook
        • Provides magic commands like ! and %% to provide access to *nix commands.
    • Use an editor such as vi/vim, emacs, Notepad++ etc to write a python script and execute as a batch script.

Printing to screen

  • Python has a built-in function, print to write output to standard output or screen
In [1]:
print("Hello World!")
Hello World!

Reading from screen

  • Python has a built-in function, input to read input from standard input or screen
In [2]:
input('What is your name? ')
What is your name? John Doe
Out[2]:
'John Doe'

Your First Python Script

  • Create a file, myscript.py, with the following content print("Hello There!")
  • On the command line, type python myscript.py and hit enter
In [3]:
!python myscript.py
Hello There!
1
  • If you are using Jupyter Notebooks, then bang (!) is used to invoke shell commands

Your First Python Script

  • On Linux and Mac, add #!/usr/bin/env python as the first line
  • Convert myscript.py to an executable and execute it
In [4]:
!cat myscript.py
#!/usr/bin/env python

print("Hello There!")

x = 1
print(x)


In [5]:
%%bash
chmod +x myscript.py
./myscript.py
Hello There!
1
  • If you are using Jupyter Notebooks, then %%bash is used to enter a series of bash command
    • If you only need to run one command, then use ! followed by the command

Variables and Types

  • A variable is a name that refers to a value.
  • An assignment statement creates new variables and gives them values:
In [6]:
message = 'And now for something completely different'
n = 17
pi = 3.1415926535897931
  • The first assigns a string to a new variable named message
  • the second gives the integer 17 to n
  • the third assigns the (approximate) value of $\pi$ to pi

  • To display the value of a variable, you can use a print function

In [7]:
print(message)
And now for something completely different
  • The type of a variable is the type of the value it refers to.
In [8]:
type(message)
Out[8]:
str
In [9]:
type(n)
Out[9]:
int
In [10]:
type(pi)
Out[10]:
float

Variable names

  • Variable names can be arbitrarily long. They can contain both letters and numbers, but they have to begin with a letter.
  • The underscore character (_) can appear in a name.
    • It is often used in names with multiple words, such as my_name
  • If you give a variable an illegal name, you get a syntax error:
In [11]:
76trombones = 'big parade'
  File "<ipython-input-11-ee59a172c534>", line 1
    76trombones = 'big parade'
              ^
SyntaxError: invalid syntax
In [12]:
class = 'Advanced Theoretical Zymurgy'
  File "<ipython-input-12-73fc4ce1a15a>", line 1
    class = 'Advanced Theoretical Zymurgy'
          ^
SyntaxError: invalid syntax

Reserved Words

  • Python has 31 keywords or reserved words that cannot be used for variable names.
and del for is raise
as elif from lambda return
assert else global not try
break except if or while
class exec import pass with
continue finally in print yield
def
  • Use an editor that has syntax highlighting, wherein python functions have a different color
    • See previous slides, variable names are in the normal color i.e. black while reserved keywords, for e.g. class, are in green

Statements

  • A statement is a unit of code that the Python interpreter can execute. We have seen two kinds of statements: print and assignment.

  • When you type a statement in interactive mode, the interpreter executes it and displays the result, if there is one.

  • A script usually contains a sequence of statements. If there is more than one statement, the results appear one at a time as the statements execute.

Operators and Operands

  • Operators are special symbols that represent computations like addition and multiplication.
  • The values the operator is applied to are called operands.

Arithmetic Operators

Operator Meaning Example
+ (unary) Unary Positive +a
+ (binary) Addition a + b
- (unary) Unary Negation -a
- (binary) Subtraction a - b
* Multiplication a * b
/ Division a / b
% Modulus a % b
// Floor Division (also called Integer Divison a // b
** Exponentiation a ** b
In [13]:
a = 4
b = 3
print(+a)
print(-b)
4
-3
In [14]:
print(a + b)
print(a - b)
7
1
In [15]:
print(a * b)
print(a / b)
print(3 * a // b)
print(2 * a % b)
print(a ** b)
12
1.3333333333333333
4
2
64
In [16]:
print(1)
x = 2
print(x)
1
2

Functions

  • A function is a named sequence of statements
    • functions are specified by name and a sequence of statements.
    • You "call" the function by name.
In [17]:
print(x)
2
  • The name of the function is print.
  • The expression in parentheses is called the argument of the function.
  • The result, for this function, is the type of the argument.

  • It is common to say that a function "takes" an argument and "returns" a result.

  • The result is called the return value.

Built-in Type Conversion Functions

Function Description
ascii() Returns a string containing a printable representation of an object
bin() Converts an integer to a binary string
bool() Converts an argument to a Boolean value
callable() Returns whether the object is callable (i.e., some kind of function)
chr() Returns string representation of character given by integer argument
complex() Returns a complex number constructed from arguments
float() Returns a floating-point object constructed from a number or string
hex() Converts an integer to a hexadecimal string
int() Returns an integer object constructed from a number or string
oct() Converts an integer to an octal string
ord() Returns integer representation of a character
repr() Returns a string containing a printable representation of an object
str() Returns a string version of an object
type() Returns the type of an object or creates a new type object

Modules

  • Python module is a normal python file which can store function, variable, classes, constants etc
  • Module helps us to organize related codes
  • Popular modules
    • math
    • numpy
    • scipy
    • matplotlib
    • pandas
    • mpi4py

Creating modules

  • Create a new file called mymodule.py and write the following code.
In [18]:
!cat mymodule.py
foo = 100
 
def hello():
    print("i am from mymodule.py")


  • This module defines a global variable foo and a function hello
  • To use this module in a program, you need to import the module
In [19]:
import mymodule
In [20]:
mymodule.foo
Out[20]:
100
In [21]:
mymodule.hello()
i am from mymodule.py
  • If you only need to import a variable or function, then use from with import
In [22]:
from mymodule import hello
hello()
i am from mymodule.py
  • You can also abbreviate the module name by adding as to the import
In [23]:
import mymodule as my
my.foo
Out[23]:
100

Math

  • The math module that provides most of the familiar mathematical functions
Function Description
abs() Returns absolute value of a number
divmod() Returns quotient and remainder of integer division
max() Returns the largest of the given arguments or items in an iterable
min() Returns the smallest of the given arguments or items in an iterable
pow() Raises a number to a power
round() Rounds a floating-point value
sum() Sums the items of an iterable
  • A module is a file that contains a collection of related functions
  • Before we can use the module, we have to import it
In [24]:
import math
  • This statement creates a module object named math
  • If you print the module object, you get some information about it
In [25]:
print(math)
<module 'math' from '/Users/apacheco/anaconda3/lib/python3.7/lib-dynload/math.cpython-37m-darwin.so'>
  • The module object contains the functions and variables defined in the module
  • To access one of the functions, you have to specify the name of the module and the name of the function, separated by a dot (also known as a period)
  • This format is called dot notation
In [26]:
degrees = 45
radians = degrees / 360.0 * 2 * math.pi
math.sin(radians)
Out[26]:
0.7071067811865475

Iterables and Iterators

Function Description
all() Returns True if all elements of an iterable are true
any() Returns True if any elements of an iterable are true
enumerate() Returns a list of tuples containing indices and values from an iterable
filter() Filters elements from an iterable
iter() Returns an iterator object
len() Returns the length of an object
map() Applies a function to every item of an iterable
next() Retrieves the next item from an iterator
range() Generates a range of integer values
reversed() Returns a reverse iterator
slice() Returns a slice object
sorted() Returns a sorted list from an iterable
zip() Creates an iterator that aggregates elements from iterables

Data Types

Python has 5 Data types

  1. Numbers
    1. Integers
    2. Floating Point Numbers
    3. Complex Numbers
  2. Strings
  3. Lists
  4. Dictionaries
  5. Tuples
  6. Boolean

Integers

  • There is effectively no limit to how long an integer value can be
  • You are constrained by the amount of memory your system
In [27]:
print(123123123123123123123123123123123123123123123123 + 1)
123123123123123123123123123123123123123123123124
  • Python interprets a sequence of decimal digits without any prefix to be a decimal number:
In [28]:
print(10)
print(0o10)
print(0b10)
10
8
2
  • Add a prefix to an integer value to indicate a base other than 10:
Prefix Interpretation Base
0b Binary 2
0o Octal 8
0x Hexadecimal 16
  • The underlying type of a Python integer, irrespective of the base used to specify it, is called int
In [29]:
type(10)
Out[29]:
int
In [30]:
type(0o10)
Out[30]:
int
In [31]:
type(0x10)
Out[31]:
int

Floating Point Number

  • The float type in Python designates a floating-point number.
  • float values are specified with a decimal point.
  • Optionally, the character e or E followed by a positive or negative integer may be appended to specify scientific notation
In [32]:
4.2
Out[32]:
4.2
In [33]:
type(0.2)
Out[33]:
float
In [34]:
type(.4e7)
Out[34]:
float
In [35]:
4.2e-4
Out[35]:
0.00042

Floating-Point Representation

  • For 64-bit systems, the maximum value a floating-point number can have is approximately $1.8 \times 10^{308}$
  • Python will indicate a number greater than that by the string inf
In [36]:
1.79e308
Out[36]:
1.79e+308
In [37]:
1.8e+308
Out[37]:
inf
  • The closest a nonzero number can be to zero is approximately $5.0 \times 10^{-324}$
  • Anything closer to zero than that is effectively zero
In [38]:
5e-324
Out[38]:
5e-324
In [39]:
2e-324
Out[39]:
0.0
  • Floating point numbers are represented internally as binary (base-2) fractions
  • Most decimal fractions cannot be represented exactly as binary fractions, so in most cases the internal representation of a floating-point number is an approximation of the actual value
  • In practice, the difference between the actual value and the represented value is very small and should not usually cause significant problems
In [40]:
0.5 - 0.4 - 0.1
Out[40]:
-2.7755575615628914e-17
  • You can convert between an int and float types using built-in functions
In [41]:
int(4.2)
Out[41]:
4
In [42]:
float(15)
Out[42]:
15.0

Complex Numbers

  • Complex numbers are specified as (real part)+(imaginary part)j. For example:
In [43]:
a = 2 + 3j
type(a)
Out[43]:
complex
In [44]:
print(a.real, a.imag)
2.0 3.0
In [45]:
a*a
Out[45]:
(-5+12j)
In [46]:
a*a.conjugate()
Out[46]:
(13+0j)

Strings

  • Strings are sequences of character data. The string type in Python is called str.
  • String literals may be delimited using either single or double quotes.
    • All the characters between the opening delimiter and matching closing delimiter are part of the string:
In [47]:
print("I am a string.")
I am a string.
In [48]:
type("I am a string.")
Out[48]:
str
In [49]:
print('I am too.')
I am too.
In [50]:
type('I am too.')
Out[50]:
str
  • A string in Python can contain as many characters as you wish.
    • The only limit is your machine’s memory resources.
  • A string can also be empty:
In [51]:
''
Out[51]:
''
  • If you want to include either type of quote character within the string, the simplest way is to delimit the string with the other type.
    • If a string is to contain a single quote, delimit it with double quotes and vice versa
In [52]:
print("This string contains a single quote (') character.")
print('This string contains a double quote (") character.')
This string contains a single quote (') character.
This string contains a double quote (") character.
  • Alternatively, escape the quote character using a backslah
In [53]:
print('This string contains a single quote (\') character.')
print("This string contains a double quote (\") character.")
This string contains a single quote (') character.
This string contains a double quote (") character.
  • Escape sequences
Escape Sequence Escaped Interpretation
\' Literal single quote (') character
\" Literal double quote (") character
\newline Newline is ignored
\\ Literal backslash () character
\n ASCII Linefeed (LF) character
\r ASCII Carriage Return (CR) character
\t ASCII Horizontal Tab (TAB) character
\v ASCII Vertical Tab (VT) character

Interactive Python - User Input

  • To interact with standard input, the input function can be assigned to a string variable
  • Modify your myscript.py file to ask for your name or anyone's name interactively
In [54]:
# To run example within Jupyter Notebook or IPython or Python Shell
name = input ("What is your name? ")
print("Hello ",name)
What is your name? Jane Doe
Hello  Jane Doe
  • You need to use built-in functions, int or float to read integer or floating numbers from standard input

Triple Quoted Strings

  • Triple-quoted strings are delimited by matching groups of three single quotes or three double quotes.
  • Escape sequences still work in triple-quoted strings, but single quotes, double quotes, and newlines can be included without escaping them.
  • This provides a convenient way to create a string with both single and double quotes in it
In [55]:
print('''This string has a single (') and a double (") quote.''')
This string has a single (') and a double (") quote.
  • Because newlines can be included without escaping them, this also allows for multiline strings:
In [56]:
print("""This is a
string that spans
across several lines""")
This is a
string that spans
across several lines

String Operations

  • Python strings are immutable i.e. once a string is created it can’t be modified
In [57]:
str1="Hello"
str2="Hello"
print(id(str1),id(str2))
4414402376 4414402376
  • str1 and str2 both refer to the same memory location
  • If you modify str1, it creates a new object at a different memory location
In [58]:
str1+=", Welcome to LTS Seminars"
print(str1,id(str1),id(str2))
Hello, Welcome to LTS Seminars 4414004880 4414402376
  • Every element of a string can be referenced by their index (first index is 0)
In [59]:
str1[0]
Out[59]:
'H'
  • + operator is used to concatenate string and * operator is a repetition operator for string.
In [60]:
s = "So, you want to learn Python? " * 4
print(s)
So, you want to learn Python? So, you want to learn Python? So, you want to learn Python? So, you want to learn Python? 
  • You can take subset of string from original string by using [] operator, also known as slicing operator.
  • s[start:end] will return part of the string starting from index start to index end - 1
In [61]:
s[3:15]
Out[61]:
' you want to'
  • start index and end index are optional.
  • default value of start index is 0
  • default value of end is the last index of the string
In [62]:
s[:3]
Out[62]:
'So,'
In [63]:
s[15:]
Out[63]:
' learn Python? So, you want to learn Python? So, you want to learn Python? So, you want to learn Python? '
In [64]:
s[:]
Out[64]:
'So, you want to learn Python? So, you want to learn Python? So, you want to learn Python? So, you want to learn Python? '

String functions

  • ord(): returns the ASCII code of the character.
  • chr(): function returns character represented by a ASCII number.
  • len(): returns length of the string
  • max(): returns character having highest ASCII value
  • min(): returns character having lowest ASCII value
In [65]:
len(s)
Out[65]:
120

Lists

  • Like a string, a list is a sequence of values.
  • In a string, the values are characters; in a list, they can be any type.
  • The values in list are called elements or sometimes items.
In [66]:
a = [10, 20, 30, 40]
print(a)
[10, 20, 30, 40]
  • lists can be nested.
In [67]:
b = ['spam', 2.0, 5, [10, 20]]
print(b)
['spam', 2.0, 5, [10, 20]]
  • An empty list i.e. list with no elements is created with empty brackets [].
In [68]:
c=[]
print(c)
[]
  • Lists are mutable i.e. they can be modified after creation
In [69]:
numbers = [17, 123]
print(numbers,id(numbers))
[17, 123] 4414144648
In [70]:
numbers[0] = 5
print(numbers,id(numbers))
[5, 123] 4414144648
  • The + operator concatenates lists:
In [71]:
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
print(c)
[1, 2, 3, 4, 5, 6]
  • You can reference a section of the list using a slice operator
In [72]:
c[2:5]
Out[72]:
[3, 4, 5]

list operations

  • append adds a new element to the end of the list
In [73]:
t1 = ['a', 'b', 'c']
t1.append('d')
print(t1)
['a', 'b', 'c', 'd']
  • extend takes a list as an argument and appends all of the elements
In [74]:
t2 = ['e', 'f']
t1.extend(t2)
print(t1)
['a', 'b', 'c', 'd', 'e', 'f']
  • sort arranges the elements of the list from low to high:
In [75]:
t = ['d', 'c', 'e', 'b', 'a']
t.sort()
print(t)
['a', 'b', 'c', 'd', 'e']

deleting list elements

  • pop modifies the list and returns the element that was removed.
  • If you don’t provide an index, it deletes and returns the last element
In [76]:
t = ['a', 'b', 'c']
x = t.pop(1)
print(t)
['a', 'c']
In [77]:
print(x)
b
  • Use del if you do not need the removed value
In [78]:
t = ['a', 'b', 'c']
del t[1]
print(t)
['a', 'c']
  • If you know the element you want to remove (but not the index), you can use remove
In [79]:
t = ['a', 'b', 'c', 'd', 'e', 'f']
t.remove('b')
print(t)
['a', 'c', 'd', 'e', 'f']
  • To remove more than one element, you can use del with a slice index
In [80]:
t = ['a', 'b', 'c', 'd', 'e', 'f']
del t[1:5]
print(t)
['a', 'f']

lists and strings

  • A string is a sequence of characters and a list is a sequence of values
  • list of characters is not the same as a string.
  • To convert from a string to a list of characters, you can use list
In [81]:
s = 'spam'
t = list(s)
print(t)
['s', 'p', 'a', 'm']
  • The list function breaks a string into individual letters.
  • If you want to break a string into words, you can use the split method
In [82]:
s = 'pining for the fjords'
t = s.split()
print(t)
['pining', 'for', 'the', 'fjords']
  • An optional argument called a delimiter specifies which characters to use as word boundaries
In [83]:
s = 'spam-spam-spam'
delimiter = '-'
s.split(delimiter)
Out[83]:
['spam', 'spam', 'spam']
  • join is the inverse of split.
  • It takes a list of strings and concatenates the elements.
  • join is a string method, so you have to invoke it on the delimiter and pass the list as a parameter
In [84]:
t = ['pining', 'for', 'the', 'fjords']
delimiter = ':'
delimiter.join(t)
Out[84]:
'pining:for:the:fjords'

Dictionaries

  • A dictionary is a mapping between a set of indices (which are called keys) and a set of values.
  • Each key maps to a value.
  • The association of a key and a value is called a key-value pair
  • The function dict creates a new dictionary with no items
In [85]:
eng2sp = dict()
print(eng2sp)
{}
  • To add items to the dictionary, you can use square brackets
In [86]:
eng2sp['one'] = 'uno'
print(eng2sp)
{'one': 'uno'}
  • You can update a dictionary by adding a new entry or a key-value pair
In [87]:
eng2sp['two'] = 'dos'
print(eng2sp)
{'one': 'uno', 'two': 'dos'}
  • You can create a dictionary as follows
In [88]:
eng2sp = {'one': 'uno', 'two': 'dos', 'three': 'tres'}
print(eng2sp)
{'one': 'uno', 'two': 'dos', 'three': 'tres'}
  • the order of items in a dictionary is unpredictable
  • use keys to look up the corresponding value
In [89]:
print(eng2sp['three'])
tres
  • To delete entries in a dictionary, use del
In [90]:
del eng2sp['two']
print(eng2sp)
{'one': 'uno', 'three': 'tres'}
  • The clear() function is used to remove all elements of the dictionary
In [91]:
eng2sp.clear()
print(eng2sp)
{}
  • The len function returns the number of key-value pairs
In [92]:
eng2sp = {'one': 'uno', 'two': 'dos', 'three': 'tres'}
len(eng2sp)
Out[92]:
3

Tuples

  • A tuple is a sequence of values
  • The values can be any type, and they are indexed by integers.
In [93]:
t = ('a', 'b', 'c', 'd', 'e')
  • To create a tuple with a single element, you have to include the final comma
In [94]:
t1 = ('a',)
type(t1)
Out[94]:
tuple
In [95]:
t2 = ('a')
type(t2)
Out[95]:
str
  • Another way to create a tuple is the built-in function tuple.
  • With no argument, it creates an empty tuple
In [96]:
t = tuple()
print(t)
()
  • If the argument is a sequence (string, list or tuple), the result is a tuple with the elements of the sequence
In [97]:
t = tuple('lupins')
print(t)
('l', 'u', 'p', 'i', 'n', 's')
  • Most list operators also work on tuples. The bracket operator indexes an element
In [98]:
t = ('a', 'b', 'c', 'd', 'e')
print(t[1])
b
  • slice operator selects a range of elements
In [99]:
print(t[1:])
('b', 'c', 'd', 'e')
  • Unlike lists, tuples are immutable
In [100]:
t[0] = 'A'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-100-7e674cdf20e6> in <module>
----> 1 t[0] = 'A'

TypeError: 'tuple' object does not support item assignment
  • You can’t modify the elements of a tuple, but you can replace one tuple with another
In [101]:
print(t,id(t))
t = ('A',) + t[1:]
print(t,id(t))
('a', 'b', 'c', 'd', 'e') 4412348112
('A', 'b', 'c', 'd', 'e') 4412348640

Assignment

  • It is often useful to swap the values of two variables using a cumbersome procedure
In [102]:
a = 1
b = 2
In [103]:
temp = a
a = b
b = temp
print(a,b)
2 1
  • tuple assignment is more elegant
In [104]:
a,b = b,a
print(a,b)
1 2
  • The number of variables on the left and the number of values on the right have to be the same
In [105]:
a, b = 1,2,3
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-105-6b644e00ae5e> in <module>
----> 1 a, b = 1,2,3

ValueError: too many values to unpack (expected 2)
  • Tuples can be used to return multiple values from a function
In [106]:
quot, rem = divmod(7, 3)
print(quot)
2
In [107]:
print(rem)
1

Boolean

  • Objects of Boolean type may have one of two values, True or False:
In [108]:
type(True)
Out[108]:
bool
In [109]:
type(False)
Out[109]:
bool

Comparison Operators

  • Can be used for both numbers and strings
  • Python compares string lexicographically i.e using ASCII value of the characters
Operator Meaning Example
== Equal to a == b
!= Not equal to a != b
< Less than a < b
<= Less than or equal to a <= b
> Greater than a > b
>= Greater than or equal to a >= b
In [111]:
a = 10
b = 20
print(a == b)
False
In [112]:
c = 'Hi'
d = 'hi'
print(c == d)
print( c < d)
print(ord('H'),ord('h'),ord('i'))
False
True
72 104 105
  • Consider two strings 'Hi' and 'HI' for comparison.
  • The first two characters ( H and H ) are compared.
  • Since 'i' has a greater ASCII value (105) than 'I' with ASCII value (73), 'Hi' is greater than 'HI'
In [113]:
'HI' < 'Hi'
Out[113]:
True

Logical Operators

Operator Example Meaning
not not x True if x is False
False if x is True
(Logically reverses the sense of x)
or x or y True if either x or y is True
False otherwise
and x and y True if both x and y are True
False otherwise
In [114]:
x = 5
not x < 10
Out[114]:
False
In [115]:
x < 10 or callable(x)
Out[115]:
True
In [116]:
x < 10 and callable(len)
Out[116]:
True

User Defined Functions

  • Python allows programmers to define their OWN function
  • A function definition specifies the name of a new function and the sequence of statements that execute when the function is called.

Why create your own functions?

  • Creating a new function gives you an opportunity to name a group of statements, which makes your program easier to read and debug.
  • Functions can make a program smaller by eliminating repetitive code. Later, if you make a change, you only have to make it in one place.
  • Dividing a long program into functions allows you to debug the parts one at a time and then assemble them into a working whole.
  • Well-designed functions are often useful for many programs. Once you write and debug one, you can reuse it.
In [117]:
def celcius_to_fahrenheit(tempc):
    tempf = 9.0 / 5.0 * tempc + 32.0
    return tempf
In [118]:
tempc = float(input('Enter Temperature in Celcius: '))

print("%6.2f C = %6.2f F" % (tempc, celcius_to_fahrenheit(tempc)))
Enter Temperature in Celcius: 25
 25.00 C =  77.00 F
  • When you create a variable inside a function, it is local, which means that it only exists inside the function.
    • e.g. tempf is local within the celcius_to_fahrenheit function and does not exist outside the scope of the function
In [119]:
print(tempf)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-119-8f86e1a6cd78> in <module>
----> 1 print(tempf)

NameError: name 'tempf' is not defined

Conditional Execution

  • Conditional Statements gives the programmer an ability to check conditions and change the behavior of the program accordingly.
  • The simplest form is the if statement:

Image Not Found

Syntax: if condition: statements

  • The boolean expression after the if statement is called the condition.

    • If it is true, then the indented statement gets executed.
    • If not, nothing happens.
  • if statements have the same structure as function definitions:

    • a header followed by an indented block.
    • Statements like this are called compound statements.
  • There is no limit on the number of statements that can appear in the body, but there has to be at least one.
  • Occasionally, it is useful to have a body with no statements (usually as a place keeper for code you haven't written yet).
  • In that case, you can use the pass statement, which does nothing.
In [120]:
if x < 0:
    pass
  • There may be a situation where you want to execute a series of statements if the condition is false
  • Python provides an if ... else ... conditional
  • Syntax if condition: statments_1 else: statements_2
In [121]:
if x % 2 == 0:
    print('x is even')
else:
    print('x is odd')
x is odd
  • If the remainder when x is divided by 2 is 0, then we know that x is even, and the program displays a message to that effect.
  • If the condition is false, the second set of statements is executed.
  • Since the condition must be true or false, exactly one of the alternatives will be executed. - The alternatives are called branches, because they are branches in the flow of execution.
  • Sometimes there are more than two possibilities and we need more than two branches.
  • Python provides a if ... elif ... else conditional
  • Syntax if condition1: statements_1 elif condition2: statements_2 else statements_3
In [122]:
y = 10
if x < y:
    print('x is less than y')
elif x > y:
    print('x is greater than y')
else:
    print('x and y are equal')
x is less than y
  • elif is an abbreviation of “else if.”
  • Again, exactly one branch will be executed.
  • There is no limit on the number of elif statements.
  • If there is an else clause, it has to be at the end, but there doesn’t have to be one.
In [123]:
choice='d'
if choice == 'a':
    print('choice is a')
elif choice == 'b':
    print('choice is b')
elif choice == 'c':
    print('choice is c')
  • Each condition is checked in order.
  • If the first is false, the next is checked, and so on.
  • If one of them is true, the corresponding branch executes, and the statement ends.
  • Even if more than one condition is true, only the first true branch executes.
  • Conditional can also be nested within another.
In [124]:
if x == y:
    print('x and y are equal')
else:
    if x < y:
        print('x is less than y')
    else:
        print('x is greater than y')
x is less than y
  • The outer conditional contains two branches.
  • The first branch contains a simple statement.
  • The second branch contains another if statement, which has two branches of its own.
  • Those two branches are both simple statements, although they could have been conditional statements as well.
  • Logical operators often provide a way to simplify nested conditional statements.
In [125]:
if 0 < x:
    if x < 10:
        print('x is a positive single-digit number.')
x is a positive single-digit number.
  • The print statement is executed only if we make it past both conditionals
  • we can get the same effect with the and operator
In [126]:
if 0 < x and x < 10:
    print('x is a positive single-digit number.')
x is a positive single-digit number.

Control Statements

Python provides three control statements that can be used within conditionals and loops

  1. break: Terminates the loop statement and transfers execution to the statement immediately following the loop
  2. continue: Causes the loop to skip the remainder of its body and immediately retest its condition prior to reiterating.
  3. pass: The pass statement is used when a statement is required syntactically but you do not want any command or code to execute.

Recursion

  • Python functions can call itself recursively
In [127]:
def factorial(n):
    if n < 1:
        return 1
    else:
         return n*factorial(n-1)
In [128]:
factorial(5)
Out[128]:
120
In [129]:
def double_fact(n):
    if n < 2:
        return 1
    else:
        return n * double_fact(n - 2)
In [130]:
double_fact(10)
Out[130]:
3840

Loops

  • There may be a situation when you need to execute a block of code a number of times.

  • A loop statement allows us to execute a statement or group of statements multiple times.

Image Not Found

for loops

  • The for statement has the ability to iterate over the items of any sequence, such as a list or a string
  • If a sequence contains an expression list, it is evaluated first.
  • Then, the first item in the sequence is assigned to the iterating variable iterating_var.
  • Next, the statements block is executed.
  • Each item in the list is assigned to iterating_var, and the statement(s) block is executed until the entire sequence is exhausted.

for iterating_var in sequence: statements(s)

In [131]:
for letter in 'Hola': 
   print('Current Letter :', letter)
Current Letter : H
Current Letter : o
Current Letter : l
Current Letter : a
In [132]:
fruits = ['banana', 'apple',  'mango']
for fruit in fruits: 
   print ('Current fruit :', fruit)
Current fruit : banana
Current fruit : apple
Current fruit : mango
  • An alternative way of iterating through each item is by index offset into the sequence itself
In [133]:
fruits = [0,1,2,3,4]
for index in range(len(fruits)):
   print ('Current fruit :', fruits[index])
Current fruit : 0
Current fruit : 1
Current fruit : 2
Current fruit : 3
Current fruit : 4

range function

  • The built-in function range() iterates over a sequence of numbers.
In [134]:
range(5)
Out[134]:
range(0, 5)
In [135]:
list(range(5))
Out[135]:
[0, 1, 2, 3, 4]
In [136]:
for var in list(range(5)):
    print(var)
0
1
2
3
4
  • You can loop through keys or values by using the keys and values functions
In [137]:
for keys in eng2sp.keys():
    print(keys)
one
two
three
In [138]:
for vals in eng2sp.values():
    print(vals)
uno
dos
tres

while loop

  • A while loop statement repeatedly executes a target statement as long as a given condition is true.
  • Here, statement(s) may be a single statement or a block of statements with uniform indent.
  • The condition may be any expression, and true is any non-zero value. The loop iterates while the condition is true.
  • When the condition becomes false, program control passes to the line immediately following the loop.

while expression: statement(s)

In [139]:
number = int(input('Enter any integer: '))

fact = count = 1
while (count <= number ):
    fact = count * fact
    count += 1
print('Factorial of %d is %d' % (number, fact))
Enter any integer: 15
Factorial of 15 is 1307674368000

infinite loop

  • A loop becomes infinite loop if a condition never becomes FALSE

number = int(input('Enter any integer: ')) fact = count = 1 while (count <= number ): fact = count * fact print('Factorial of %d is %d' % (number, fact))

Using else Statement with Loops

  • Python supports having an else statement associated with a loop statement.
  • If the else statement is used with a for loop, the else block is executed only if the for loops terminates normally (and not by encountering break statement).
  • If the else statement is used with a while loop, then the else statement is executed when the condition becomes false.
In [140]:
numbers = [11,33,55,39,55,75,37,21,23,41,13]

for num in numbers:
   if num%2 == 0:
      print ('the list contains an even number')
      break
else:
   print ('the list does not contain even number')
the list does not contain even number
In [141]:
count = 0
while count < 5:
   print (count, " is  less than 5")
   count = count + 1
else:
   print (count, " is not less than 5")
0  is  less than 5
1  is  less than 5
2  is  less than 5
3  is  less than 5
4  is  less than 5
5  is not less than 5

File Handling

  • To read/write a file, you have to open it with an appropriate mode as the second parameter

open(filename, mode)

mode description
r Opens a file for reading only, default mode
w Opens a file for writing only
a Opens a file for appending only. File pointer is at end of file
rb Opens a file for reading only in binary
wb Opens a file for writing only in binary
In [142]:
fout = open('output.txt', 'w')
print(fout)
<_io.TextIOWrapper name='output.txt' mode='w' encoding='UTF-8'>
  • If the file already exists, opening it in write mode clears out the old data.
  • If the file doesn’t exist, a new one is created.
  • The write method puts data into the file.
In [143]:
line1 = "This here's the wattle,\n"
fout.write(line1)
Out[143]:
24
In [144]:
line2 = "the emblem of our land.\n"
fout.write(line2)
Out[144]:
24
  • When you are done writing, you have to close the file.
In [145]:
fout.close()
!cat output.txt
This here's the wattle,
the emblem of our land.
  • To read data back from the file you need one of these three methods
Method Description
read([number]) Return specified number of characters from the file.
if omitted it will read the entire contents of the file.
readline() Return the next line of the file.
readlines() Read all the lines as a list of strings in the file
  • Reading all the data at once.
In [146]:
f = open('myscript.py', 'r')
f.read() 
Out[146]:
'#!/usr/bin/env python\n\nprint("Hello There!")\n\nx = 1\nprint(x)\n\n\n'
In [147]:
f.close()
  • Reading all lines as an array
In [148]:
f = open('myscript.py', 'r')
f.readlines() 
Out[148]:
['#!/usr/bin/env python\n',
 '\n',
 'print("Hello There!")\n',
 '\n',
 'x = 1\n',
 'print(x)\n',
 '\n',
 '\n']
In [149]:
f.close()
  • Reading only one line.
In [150]:
f = open('myscript.py', 'r')
f.readline() 
Out[150]:
'#!/usr/bin/env python\n'
In [151]:
f.close()
  • You can iterate through the file using file pointer.
In [152]:
f = open('myscript.py', 'r')
for line in f:
    print(line)
f.close()    
#!/usr/bin/env python



print("Hello There!")



x = 1

print(x)





Formatted output

  • The argument of write has to be a string
  • convert other values to strings using str
In [153]:
f = open('output.txt', 'w')
x = 52
f.write(str(x))
f.close()
!cat output.txt
52
  • An alternative is to use the format operator, %
  • The first operand is the format string, and the second operand is a tuple of expressions.
In [154]:
tempc = float(input('Enter Temperature in Celcius: '))

print("%6.2f C = %6.2f F" % (tempc, celcius_to_fahrenheit(tempc)))
Enter Temperature in Celcius: 35
 35.00 C =  95.00 F
  • The general syntax for print function is print(format string with placeholder % (variables) )

  • The general syntax for a format placeholder is %[flags][width][.precision]type

type data type
s strings
f or F floating point numbers
d or i integers
e or E Floating point exponential format
g or G same as e or E if exponent is greater than -4, f or F otherwise
  • If you try to open a file that doesn’t exist, you get an IOError:
In [155]:
fin = open('bad_file')
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-155-a7d7d7ad396b> in <module>
----> 1 fin = open('bad_file')

FileNotFoundError: [Errno 2] No such file or directory: 'bad_file'
  • If you don’t have permission to access a file
In [156]:
fout = open('/etc/passwd', 'w')
---------------------------------------------------------------------------
PermissionError                           Traceback (most recent call last)
<ipython-input-156-8a9adb191927> in <module>
----> 1 fout = open('/etc/passwd', 'w')

PermissionError: [Errno 13] Permission denied: '/etc/passwd'
  • or if you try to open a directory for reading
In [157]:
fin = open('/home')
---------------------------------------------------------------------------
IsADirectoryError                         Traceback (most recent call last)
<ipython-input-157-a2032f82d461> in <module>
----> 1 fin = open('/home')

IsADirectoryError: [Errno 21] Is a directory: '/home'
  • Python provides statements, try and except to allow programmers to gracefully quit the program
In [158]:
try:    
    fin = open('bad.txt')
    for line in fin:
        print(line)
    fin.close()
except:
    print('Something went wrong.')
Something went wrong.
In [159]:
!cat test1.py
fin = open('bad.txt')
for line in fin:
    print(line)
fin.close()
    
print('Hello World!')
In [160]:
!python test1.py
Traceback (most recent call last):
  File "test1.py", line 1, in <module>
    fin = open('bad.txt')
FileNotFoundError: [Errno 2] No such file or directory: 'bad.txt'
In [161]:
!cat test2.py
try:    
    fin = open('bad.txt')
    for line in fin:
        print(line)
    fin.close()
except:
    print('Something went wrong.')
    
print('Hello World!')
In [162]:
!python test2.py
Something went wrong.
Hello World!

NumPy

  • NumPy is the fundamental package for scientific computing with Python.
  • It contains among other things
    • a powerful N-dimensional array object
    • sophisticated (broadcasting) functions
    • tools for integrating C/C++ and Fortran code
    • useful linear algebra, Fourier transform, and random number capabilities
  • NumPy can also be used as an efficient multi-dimensional container of generic data.
  • Numpy arrays are a great alternative to Python Lists
  • NumPy’s main object is the homogeneous multidimensional array.
  • NumPy’s array class is called ndarray. It is also known by the alias array
  • The more important attributes of an ndarray object are:
    • ndarray.ndim: the number of axes (dimensions) of the array.
    • ndarray.shape: the dimensions of the array.
    • ndarray.size: the total number of elements of the array.
    • ndarray.dtype: an object describing the type of the elements in the array.
    • ndarray.itemsize: the size in bytes of each element of the array.
    • ndarray.data: the buffer containing the actual elements of the array.
  • To use Numpy, you need to import the numpy module
    • convention: import as np and then use the dot notation
In [163]:
import numpy as np

Numpy Arrays

  • create an array from a regular Python list or tuple using the array function
In [164]:
a = np.array([2,3,4])
print(a, a.dtype)
[2 3 4] int64
  • array transforms sequences of sequences into two-dimensional arrays, sequences of sequences of sequences into three-dimensional arrays
In [165]:
b = np.array([(1.2, 3.5, 5.1),(4.1,6.1,0.5)])
print(b, b.dtype)
[[1.2 3.5 5.1]
 [4.1 6.1 0.5]] float64
  • The type of the array can also be explicitly specified at creation time
In [166]:
c = np.array( [ [1,2], [3,4] ], dtype=complex )
c
Out[166]:
array([[1.+0.j, 2.+0.j],
       [3.+0.j, 4.+0.j]])
  • The function zeros creates an array full of zeros,
  • the function ones creates an array full of ones, and
  • the function empty creates an array whose initial content is random and depends on the state of the memory.
In [167]:
print('Zeros: ',np.zeros( (3,4) ))
print('Ones', np.ones( (2,4), dtype=np.float64 ))
print('Empty', np.empty( (2,3) ))
Zeros:  [[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
Ones [[1. 1. 1. 1.]
 [1. 1. 1. 1.]]
Empty [[1.2 3.5 5.1]
 [4.1 6.1 0.5]]
  • NumPy provides a function analogous to range that returns arrays instead of lists.
In [168]:
np.arange( 10, 30, 5 )
Out[168]:
array([10, 15, 20, 25])
  • The reshape function can be used to convert an array into a matrix
In [169]:
a = np.arange(15).reshape(3, 5)
a
Out[169]:
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
In [170]:
print("array dimensions: ", a.shape)
print("number of dimensions: ", a.ndim)
print("element types: ", a.dtype.name)
print("size of elements: ", a.itemsize)
print("total number of elements: ",a.size)
print("type of object:",type(a))
array dimensions:  (3, 5)
number of dimensions:  2
element types:  int64
size of elements:  8
total number of elements:  15
type of object: <class 'numpy.ndarray'>
  • Arithmetic operators on arrays apply elementwise
In [171]:
a = np.array( [20,30,40,50] )
b = np.arange( 4 )
print('a: ', a)
print('b:', b)
print('a-b:', a-b)
print('B**2', b**2)
print('10*sin(a): ', 10*np.sin(a))
print('Which elements of a < 35:', a<35)
print('Elements of a < 35: ',a[a<35])
a:  [20 30 40 50]
b: [0 1 2 3]
a-b: [20 29 38 47]
B**2 [0 1 4 9]
10*sin(a):  [ 9.12945251 -9.88031624  7.4511316  -2.62374854]
Which elements of a < 35: [ True  True False False]
Elements of a < 35:  [20 30]
In [172]:
A = np.array( [[1,1], [0,1]] )
B = np.array( [[2,0], [3,4]] )
print('A = ', A)
print('B = ', B)
print('A*B = ', A*B)
print('A . B = ', A.dot(B))
print('Numpy A. B = ', np.dot(A, B))
A =  [[1 1]
 [0 1]]
B =  [[2 0]
 [3 4]]
A*B =  [[2 0]
 [0 4]]
A . B =  [[5 4]
 [3 4]]
Numpy A. B =  [[5 4]
 [3 4]]
  • Numpy provides linspace for generating a sequence of linearly spaced numbers and a random number generator
In [173]:
np.linspace(0,2*pi,4)
Out[173]:
array([0.        , 2.0943951 , 4.1887902 , 6.28318531])
In [174]:
np.random.random((2,3))
Out[174]:
array([[0.32677336, 0.10528816, 0.20271135],
       [0.68526784, 0.58842625, 0.44910518]])
  • NumPy provides mathematical functions such as sin, cos, and exp.
In [175]:
B = np.arange(3)
print('B: ',B)
print('exp(B): ',np.exp(B))
print('sqrt(B): ',np.sqrt(B))
C = np.array([2., -1., 4.])
print('C: ', C)
print('B + C: ', np.add(B, C))
B:  [0 1 2]
exp(B):  [1.         2.71828183 7.3890561 ]
sqrt(B):  [0.         1.         1.41421356]
C:  [ 2. -1.  4.]
B + C:  [2. 0. 6.]

Further Reading: Python Books

  • Think Python 2e - Allen B. Downey
  • Automate the Boring Stuff with Python - Al Sweigart
  • Python for Data Analysis: Data Wrangling with Pandas, NumPy, and IPython - Wes McKinney
  • Think Stats - Allen B. Downey
  • Think Bayes: Bayesian Statistics in Python - Allen B. Downey
  • Python Data Science Handbook - Jake VanderPlas