Fundamentals of Programming Lecture 2. Procedural Programming
Fundamentals of Programming Lecture 2. Procedural Programming
Structured types
List
Tuple
Dictionary
Lists
Lists represent the finite ordered sets indexed by non-negative numbers. See [3, sections 3.1.4,
5.1].
Operations:
creation
accessing values (index, len), changing values (lists are mutable)
removing items (pop), inserting items (insert)
slicing
nesting
generate list using range(), list in a for loop
lists as stacks (append, pop)
# create
a = [1, 2, 'a']
print (a)
x, y, z = a
print(x, y, z)
# slicing
print a[:2]
b = a[:]
print (b)
b[1] = 5
print (b)
# indices: 0, 1, ..., len(a) 1
a[len(a):] = [7, 9]
print a[0]
print(a)
print ('last element = ', a[len(a)-1]) a[:0] = [-1]
print(a)
# lists are mutable
a[0:2] = [-10, 10]
a[1] = 3
print(a)
print a
# lists as stacks
stack = [1, 2, 3]
stack.append(4)
print stack
print stack.pop()
print stack
# nesting
c = [1, b, 9]
print (c)
Tuples
Tuples are immutable sequences. A tuple consists of a number of values separated by
commas. See [3, section 5.3].
Operations:
packing values (creation)
nesting
empty tuple
tuple with one item
sequence unpacking
# Tuples are immutable sequences
# A tuple consists of a number of
values separated by commas
# tuple packing
t = 12, 21, 'ab'
print(t[0])
# empty tuple (0 items)
empty = ()
# sequence unpacking
x, y, z = t
print (x, y, z)
Dictionaries
A dictionary is an unordered set of (key, value) pairs with unique keys. The keys must be
immutable. See [3, section 5.5]
Operations:
creation
getting the value associated to a given key
adding/updating a (key, value) pair
removing an existing (key, value) pair
checking whether a key exists
#create a dictionary
a = {'num': 1, 'denom': 2}
print(a)
Procedural programming
A programming paradigm is a fundamental style of computer
programming.
Imperative programming is a programming paradigm that describes
computation in terms of statements that change a program state.
Procedural programming is imperative programming in which the
program is built from one or more procedures (also known as subroutines
or functions).
What is a function
A function is a self contained block of statements that:
has a name,
may have a list of (formal) parameters,
may return a value
has a documentation (specification) which consists of:
a short description
Exceptions
def max(a, b):
"""
Compute the maximum of 2 numbers
a, b - numbers
Return a number - the maximum of two integers.
Raise TypeError if parameters are not integers.
"""
if a>b:
return a
return b
def isPrime(a):
"""
Verify if a number is prime
a an integer value (a>1)
return True if the number is prime, False otherwise
"""
Functions
The following function is working but we do not consider as a function at the lab/exam
def f(k):
l = 2
while l<k and k % l>0:
l=l+1
return l>=k
Definition
A function definition is an executable statement introduced using the keyword def.
The function definition does not execute the function body; this gets executed only when the
function is called.
A function definition defines a user-defined object function.
def max(a, b):
"""
Compute the maximum of 2 numbers
a, b - numbers
Return a number - the maximum of two integers.
Raise TypeError if parameters are not integers.
"""
if a>b:
return a
return b
Variable scope
A scope defines the visibility of a name within a block.
If a local variable is defined in a block, its scope includes that block.
All variables defined at a particular indentation level or scope are considered local to that
indentation level or scope
Local variable
Global variable
global_var = 100
def f():
local_var = 300
print local_var
print global_var
Variable scope
When a name is used in a code block, it is resolved using the nearest enclosing scope.
a = 100
def f():
a = 300
print a
f()
print a
a = 100
def f():
global a
a = 300
print a
f()
print a
Calls
A block is a piece of Python program text that is executed as a unit. Blocks of code are denoted
by line indentation.
A function body is a block. A block is executed in an execution frame. When a function is
invoked a new execution frame is created.
max(2,5)
An execution frame contains:
some administrative information (used for debugging)
determines where and how execution continues after the code block's execution has
completed
defines two namespaces, the local and the global namespace, that affect execution of
the code block.
A namespace is a mapping from names (identifiers) to objects.
A particular namespace may be referenced by more than one execution frame, and from other
places as well.
Adding a name to a namespace is called binding a name (to an object);
changing the mapping of a name is called rebinding;
removing a name is unbinding.
Namespaces are functionally equivalent to dictionaries (and often implemented as dictionaries).
Passing parameters
Formal parameters is an identifier for an input parameter of a function. Each call to the
function must supply a corresponding value (argument) for each mandatory parameter
Actual parameter is a value provided by the caller of the function for a formal parameter.
The actual parameters (arguments) to a function call are introduced in the local symbol table of
the called function when it is called (arguments are passed by
object reference )
def change_or_not_immutable(a):
print ('Locals ', locals())
print ('Before assignment: a = ', a, ' id = ', id(a))
a = 0
print ('After assignment: a = ', a, ' id = ', id(a))
g1 = 1
#global immutable int
print ('Globals ', globals())
print ('Before call: g1 = ', g1, ' id = ', id(g1))
change_or_not_immutable(g1)
print ('After call: g1 = ', g1, ' id = ', id(g1))
def change_or_not_mutable(a):
print ('Locals ', locals())
print ('Before assignment: a = ', a, ' id = ', id(a))
a[1] = 1
a = [0]
print ('After assignment: a = ', a, ' id = ', id(a))
g2 = [0, 1] #global mutable list
print ('Globals ', globals())
print ('Before call: g2 = ', g2, ' id = ', id(g2))
change_or_not_mutable(g2)
print ('After call: g2 = ', g2, ' id = ', id(g2))
Test cases
Before implementing a function we write test cases in order to understand what the function
must perform. This is also a a design step.
A test case specifies a set of test inputs, execution conditions, and expected results that you
identify to evaluate a particular part of a program (e.g. a function).
For each function we will create a test function, verify input output pairs using the built in assert
function
T2
T3
T4
Test function
Output: gdc(a,b)
23
24
64
02
20
24 9
def test_gcd():
assert gcd(2, 3) == 1
assert gcd(2, 4) == 2
assert gcd(6, 4) == 2
assert gcd(0, 2) == 2
assert gcd(2, 0) == 2
assert gcd(24, 9) == 3
Implement gdc
def gcd(a, b):
"""
Compute the greatest common divisor of two positive integers
a, b integers a,b >=0
Return the greatest common divisor of two positive integers.
"""
if a == 0:
return b
if b == 0:
return a
while a != b:
if a > b:
a = a - b
else:
b = b - a
return a
Refactorings
Code refactoring is "disciplined technique for restructuring an existing body of code, altering its
internal structure without changing its external behavior" [5].
Code smell is any symptom in the source code of a program that possibly indicates a deeper
problem:
Duplicated code: identical or very similar code exists in more than one
location.
Long method: a method, function, or procedure that has grown too large.
Refactorings:
Extract Method
You have a code fragment that can be grouped together.
Turn the fragment into a method whose name explains the
purpose of the method.
Substitute Algorithm
You want to replace an algorithm with one that is clearer.
Replace the body of the method with the new algorithm.
Replace Temp with Query
You are using a temporary variable to hold the result of an
expression.
Extract the expression into a method. Replace all references to
the temp with the expression. The new method can then be used
in other methods.
References
1. The Python language reference.
http://docs.python.org/py3k/reference/index.html
2. The Python standard library. http://docs.python.org/py3k/library/index.html
3. The Python tutorial. http://docs.python.org/tutorial/index.html
4. Kent Beck.Test Driven Development: By Example. Addison-Wesley Longman,
2002. See also Test-driven development. http://en.wikipedia.org/wiki/Testdriven_development
5. Martin Fowler. Refactoring. Improving the Design of Existing Code. AddisonWesley, 1999. See also http://refactoring.com/catalog/index.html