Programming With Python: by Mustapha
Programming With Python: by Mustapha
PYTHON
by Mustapha
VARIABLES AND SIMPLE DATA
TYPES
• Every variable is connected to a value, which is the information
associated with that variable.
• Examples: message = “Live and Love!”
• Acc1 = 200000
• To display the value associated with a variable, the print function is used.
• Examples: print(message)
• print(Acc1)
• The value of the variable can be changed at any time. Python will keep
track of the current value.
NAMING AND USING VARIABLES
• Variable names can contain only letters, numbers, and underscores.
• They can start with a letter or an underscore, but not with a number
• Examples: Valid: Classifier_1, _1classifier
• Invalid: 1classifier, #1classifier
• Spaces are not allowed in variable names, but underscores can be
used to separate words in variable names.
• Valid: knn_classifier
• Invalid: knn classifier
• As a rule, avoid using Python keywords and function names as
variable names.
NAMING AND USING VARIABLES
• Example: keywords: if, elif, while, etc.
Function names: print, sort, etc.
• You should use the built-in function max() rather than defining yours.
Exercise: Write a function isIn that accepts two strings as arguments and
returns True if either string occurs anywhere in the other, and False
otherwise.
Hint: you might want to use the built-in str operation in.
Functions: scoping
def f(x): #x is a formal parameter
y=1
x=x+y
print(‘x =‘, x)
return x
x=3
y=2
z = f(x)
print(‘z = ‘, z)
print(‘x= ‘, x)
print(‘y =‘, y)
What are the outputs? Explain z = 5, y = 2, x = 3,
Functions: Scoping
• Each function defines a new name space, also called a scope.
• The formal parameter x and the local variable y that are used in f exist
only within the scope of the definition of f.
• The assignment statement x = x+y within the function body binds the
local name x to the object 4
• The assignments in f have no effect at all on the bindings of the names x
and y that exist outside the scope of f.
x=4
z=4
x=3
y=2
Functions: scoping
def f(x):
def g():
x = ‘abc’
print(‘x =‘, x)
def h():
z=x
print(‘z = ‘, z)
x=x+1
print(‘x = ‘, x)
h()
g()
print(‘x = ‘, x)
h() ‘abc’, 4, ‘abc’, 4
g()
print(‘x =‘, x)
return g
x = 3; z = f(x); print(‘x =‘, x); print(‘z =‘, z); z() #Predict the outputs
Functions: Specification
• A specification of a function defines a contract between the
implementer function and those who will be writing programs that use
the function or the clients
• Often contains two parts: Assumption and Guarantees
• Assumptions describe conditions that must be met by clients of the
function.
• Typically, assumptions describe constraints on the actual parameters
• Almost always, assumptions specify the acceptable set of types for each
parameter, and not-infrequently some constraints on the value of one
or more of the parameters
Functions: Specification
• Guarantees describe conditions that must be met by the function,
provided it has been called in a way that satisfies the assumptions
• Assumptions and guarantees are enclosed in a pair of three quotation
marks.
• The first two lines of the docstring findRoot describe conditions
(assumptions) that must be met by clients of the function.
• The last two lines of the docstring of findRoot describe the guarantees
that the implementation of the function must must.
Functions: Specification
Dictionaries (associative array)
• Objects of type dict are similar to lists except that indexing is done
using keys.
• A dictionary can be thought of as a set of key/ value pairs
• Literals of type dict are enclosed in curly braces. {}
• Each element is written as a key followed by a colon followed by a
value. Ty = {1: “jan’’, 2: “feb”}
• Dictionaries are mutable.
Dictionaries
• The general form of dictionaries is:
Variable = {key_1: value_1, key_2:value_2, key_3:value_3,…., key_n:value_n}
• The keys can be objects of type str, int, or a tuple. Lists and dicts are
unhashable
calender = {‘Jan’:1, ‘Feb’:2, ‘Mar’:3, ‘Apr’:4, 1: ‘Jan’, 2: ‘Feb’, 3: ‘Mar’, (‘26 Dec’, 1
Jan): [‘Boxing Day’, ‘Christmas’]}
• In calender, ‘Jan’ is mapped to 1, ‘Feb’ to 2, etc.
• The entries in a dictionary are unordered and cannot be accessed with
an index
• Entries are accessed with the keys associated with them
Dictionaries: Example program
Dictionaries
• It is often convenient to use tuples as keys.
• E.g. A tuple of the form (EquipNumber, MTTR) to represent
equipment reliability.
• It would easy to use this tuple as key in a dictionary implementing a
mapping from equipment to reliabilities.
• A for statement can be used to iterate over the entries in a dictionary.
• As with lists, there are many useful methods associated with
dictionaries.
Dictionaries: common methods
• len(d) returns the number of items in d.
• d.keys() returns a view of the keys in d.
• d.values() returns a view of the values in d.
• k in d returns True if key k is in d.
• d[k] returns the item in d with key k.
• d.get(k, v) returns d[k] if k is in d, and v otherwise.
• d[k] = v associates the value v with the key k in d. If there is already a value
associated with k, that value is replaced.
• del d[k] removes the key k from d.
• for k in d iterates over the keys in d.
Functions as Objects
• In Python, functions are first-class objects: they can be treated like
objects of any other type, e.g int or list.
• They have types e.g type(abs) has the value <type built-in_function_or_method>
• They can appear in expressions, e.g., as the right-hand side of an assignment
statement or as an argument to a function
• They can be elements of lists; etc.
• Using functions as arguments allows a style of coding called higher-
order programming.
Functions
def applyToEach(L, f):
”””Assumes L is a list, f a function
Mutates L by replacing each element, e, of L by f(e)”””
for i in range(len(L)):
L[i] = f(L[i])
• The open() function can be written inside the with statement. When
the with block is exited, the file is automatically closed.
with open(path, ‘r’) as f:
lines = [x.rstrip() for x in f]
File handling
Exercise:
Write a program to open results for appending, write three new lines to
it, and print the number of lines in the updated file.
Common functions for accessing files
open(fn, ‘w’) creates a file fn for writing and returns a file handle
open(fn, ‘r’) opens an existing file for reading and returns a file handle
open(fn, ‘a’) opens an existing file for appending and returns a file handle
fh.read() returns a string containing the contents of the file associated with the file handle fh
fh.readline() returns the next line in the file associated with the file handle fh
fh.readlines() returns a list each element of which is one line of the file associated with the
file handle fh.
fh.write(s) writes the string s to the end of the file associated with the file handle fh
fh.writeLines(S) S is a sequence of strings. Write each element of S as a separate line to the
file associated with the file handle fh.
fh.close() closes the file associated with the file handle fh.
Exercises
1. Write a program that asks the user to input a string, then searches the string for numbers, and prints a dictionary in
which each number is mapped to a key that depicts its position in the list.
For example,
Given a string, string_ = “I know 7one is the first word 4 in the library”, your program should be print dictionary, {‘1st’: 7, “2nd”: 2}
Hint: it might help to consider including a try-except block
2. Implement a function that meets the specification below. Use a try-except block
def sumDigits(s):
“””Assumes s is a string
Returns the sum of the decimal digits in s
For example, if s is ‘a2b3c’ it returns 5”””
3. Implement a function that meets the specification below.
def numWords(p):
“””Assumes p is a string for the file path
Returns the total number of words in the file”””
4. Write a program that examines three distinct variables – x, y, and z – and prints the largest odd number among
them. If none of them is odd, it should print a message to that effect.
5. Write a program to open results for appending, write three new lines to it, and print the number of lines in the
updated file.
6. Let s be a string that contains a sequence of decimals separated by commas and white spaces, e.g.
s = “1.23,2.4 3.123, 6.7”. Write a program that prints the sum of the numbers in s
*Your program should request for an input
NumPy Basics: Arrays and Vectorized
Computation
• NumPy is short for Numerical Python.
• It is one of the most important foundational packages for numerical
computation in python.
• NumPy itself does not provide modeling or scientific functionality.
• However, an understanding of NumPy arrays and array-oriented
computing will help you use tools with array-oriented semantics, like
pandas
• NumPy is important for numerical computations in Python because it
is designed for efficiency on large arrays of data
NumPy Basics: why is NumPy efficient?
• NumPy internally stores data in contiguous block of memory,
independent of other built-in python objects
• NumPy operations perform complex computations on entire arrays
without the need for python for loops.
• NumPy-based algorithms are generally 10 to 100 times faster (or
more) than their pure Python counterparts and use significantly less
memory.
• An example code to compare the compute times on array and a
Python list is shown below:
NumPy Basics
import numpy as np
my_arr = np.arange(1000000)
my_list = list(range(1000000))
data.dtype
NumPy Basics: creating ndarrays
• The easiest way to create an array is to use the array function
• The array function accepts any sequence-like object (including other
arrays) and produces a NumPy array containing the passed data.
data1 = [9,6,4,3,3,6.3]
arr1 = np.array(data1)
arr1
• Unless explicitly specified, np.array tries to infer a good data type for
the array that it creates.
arr1.dtype
arr2.dtype
• There are a number of other functions for creating new arrays.
Examples are zeros, ones, and empty.
Creating ndarrays
np.zeros(10)
np.zeros((3,6))
np.empty(2,3,2)
arr1.dtype
arr2.dtype1
Arithmetic with NumPy Arrays
• Arrays of the same shape can be added, subtracted, and multiplied using the +, -, and
* operators, respectively.
• When arrays of the same size are compared, the operation produces boolean arrays.
arr = np.array(([1, 2, 3], [4, 5, 6]))
arr2 = np.array(([0, 4, 1], [7, 2, 12]))
arr2>arr1
• Operations between arrays of different shapes is called broadcasting.
• The simplest example of broadcasting occurs when combining a scalar value with an
array.
arr * 4
• The scalar value 4 is broadcast to all the other elements in the multiplication
operation.
Broadcasting cont’d…..
• Broadcasting is useful in standardization or scaling of data.
• Scaling can help to reduce multicollinearity. It is especially useful when
the model contains highly correlated predictors, higher order terms and
interaction terms
• For example, in standard scaling, Z =
• Broadcasting can be used to implement the computation of the Z-score
above.
• A scalar value (the mean) is subtracted from each feature (or
predictor), then the differences are each divided by another scalar (the
standard deviation).
Broadcasting cont’d
• The columns of arr can be broadcasted as shown in the code below:
mean = arr.mean(0) # computes the mean of each column
demeaned = arr – mean
scaled_arr = demeaned/arr.std(0)
Quiz:
Create a 7x4 array. Scale all the columns of the array using the min-max
scaling (use broadcasting)
Xmm =
Broadcasting Rule
• Two arrays are compatible for broadcasting if for each trailing
dimension (i.e, starting from the end) the axis lengths match, or if
either of the lengths is 1.
Broadcasting is performed over the missing or length 1 dimensions
(4, 3) (3, ) (4, 3)
0 0 0 1 2 3 1 2 3
1 1 1 1 2 3 2 3 4
2 2 2 1 2 3 = 3 4 5
3 3 3 1 2 3 4 5 6
Basic Indexing and Slicing
• NumPy indexing can be used to select a subset of your data or
individual elements.
• Indexing in 1D arrays on the surface act similarly to Python lists.
arr = np.arange(10)
arr[5]
arr[5:8] #slicing
arr_slice[1] = 1234
arr
Q_arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
Predict the shapes of:
1) Q_arr[:2, 1:] (2,2)
2) Q_arr[2] (3,)
3) Q_arr[2, :] (3,)
4) Q_arr[2:, :] (1,3)
5) Q_arr[:, :2] (3,2)
6) Q_arr[1, :2] (2,)
7) Q_arr[1:2, :2] (1,2)
Boolean Indexing
• The ~ operator can be useful when you need to invert a general condition.
• For example,
cond = names == ‘Ada’
data[~cond]
• Selection can be made on multiple items by using the Boolean arithmetic
operators like &(and) and | (or)
For example,
Tail = (names == ‘ada’) | (names == ‘ola’)
• Selecting data from an array by Boolean indexing always creates a copy of
the data, even if the returned array is unchanged.
Boolean Indexing
• The Python keywords and and or do not work with Boolean arrays
• Other operators such as less than (<), greater than (>) can be used similarly to the equal (=), !, or a
combination of any two.
• For example,
data[data<0]
data[names ! = ‘ada’]
data[data<=0]
• These operations with two-dimensional data are more convenient to do with pandas
arr = np.empty((5,5))
for i in range(4):
arr[i+1] = 0
arr[arr<0]
Fancy Indexing
• Fancy indexing is used to describe indexing using integer array
• A list of integer slice can be passed to the array to be sliced
arr = np.empty((10,5)) # creates an empty 10x5 array
for i in range(10):
arr[i] = i
arr
• To select a subset of the rows in a particular order, you can pass a list or ndarray of integers
specifying the desired order:
arr[[4, 3, 0, 6]]
Quiz:
Predict the output
arr[[-3, -5, -7]]
Fancy Indexing
• Passing multiple index arrays selects a one-dimensional array of
elements corresponding to each tuple of indices:
arr = np.arange(24).reshape((6,4))
arr[[1,4,3,5,0], [3,0,1,2,0]]
• Fancy indexing unlike slicing copies the data into a new array
Quiz:
Predict the outputs
arr[[-1,-3,-4,0],[-3,0,1,2]]
arr[[1,2,3,4],[0,1,2,3]]
Transposing Arrays and Swapping Axes
• Transposing is a form of reshaping. Similar to reshaping, it returns a view on the underlying data
without copying anything.
• Arrays have a transpose method and a special transpose attribute
• To transpose an array using the array attribute, use:
arr.T
• For higher dimensional array, you can pass a tuple indicating the axes transpose order.
arr = np.arange(24).reshape(2,4,3)
arr
arr.transpose(1,2,0)
• Here, the axes will be reordered with the second axis first, the third axes second, and the first axis
unchanged. The transposed array will have a shape corresponding to 4x3x2
Universal Functions
• A universal function, or ufunc performs element-wise operations on data in
ndarrays
• Examples are np.sqrt(array), np.exp(array). These are referred to as unary
ufuncs.
• Binary unfuncs take two arrays and return a single array as the result
Examples are: np.add(array1, array2) and np.maximum(array1, array2)
Quiz:
Create two arrays of the same shape and compare each element of the arrays
and save the maximum in a new array.
Unary ufuncs
Binary Unfunc
Other binary unfunc
Simple Mathematical and Statistical
Methods
• A set of mathematical functions that can compute statistics about an entire array
are accessible as methods of the array class.
• Aggregations such as sum, mean, std can be used either by calling the array
instance method or using the top-level NumPy function.
arr = np.random.randn(5,4)
QUIZ:
Predict the outputs of:
arr.cumsum(axis = 0)
arr.cumprod(axis = 1)
Other statistical methods
Methods for Boolean Arrays
• Certain methods can work on Boolean arrays to provide insights
• For example sum can be used to count the True values in a Boolean
array.
(arr>0).sum() #counts the number of positive values in arr
• any and all also work with non-boolean arrays, where non-zero
elements evaluate to True.
Sorting and Unique set operations
• NumPy arrays can be sorted in-place with the sort method
arr = np.random.randn(8)
arr.sort()
arr1 = np.random.randn(5,3)
arr1