Monday, May 25, 2015

Notes on Python for Informatics Chapter 4: Functions

Source

Function calls

function: A named sequence of statements that performs some useful operation. Functions may or may not take arguments and may or may not produce a result.
function call: A statement that executes a function. It consists of the function name followed by an argument list.
argument: A value provided to a function when the function is called. This value is assigned to the corresponding parameter in the function.
return value: The result of a function. If a function call is used as an expression, the return value is the value of the expression.

Built-in functions
Python provides a number of important built-in functions that we can use without needing to provide the function definition. 
Some of these we already used:
type() # With one argument, return the type of an object.
raw_input()  #  Reads a line from input, converts it to a string, and returns that.
Type conversion functions
float() # Return a floating point number constructed from a number or string x.
int() # Return an integer object constructed from a number or string x.
str() # Return a string containing a nicely printable representation of an object.
...and some will come handy later:
len() # Return the length (the number of items) of an object
min() # Return the smallest item in an iterable or the smallest of two or more arguments.
max() # Return the largest item in an iterable or the largest of two or more arguments.

dir() # Without arguments, return the list of names in the current local scope. With an argument, attempt to return a list of valid attributes for that object.
help() # the built-in help system. (This function is intended for interactive use.) If no argument is given, the interactive help system starts on the interpreter console. If the argument is a string, then the string is looked up as the name of a module, function, class, method, keyword, or documentation topic, and a help page is printed on the console. If the argument is any other kind of object, a help page on the object is generated.

list() # Returns a list object
dict() # Returns a dictionary object
tuple() # Returns a tuple object
set()  # Returns a new set object
open()  # Open a file, returning an object of the file type
range()  # This is a versatile function to create lists containing arithmetic progressions. It is most often used in for loops.

Modules
Modules are external containers of pre-written and reusable functions and variables. Python comes with a library of standard modules, described in a separate document, the Python Library Reference (“Library Reference” hereafter).
To import a module, type import and the module name, like:
import random
This statement creates a module object named random.
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.
import statement: A statement that reads a module file and creates a module object.
module object: A value created by an import statement that provides access to the data and code defined in a module. 
dot notation: The syntax for calling a function in another module by specifying the module name followed by a dot (period) and the function name.

Random numbers
algorithm: A general process for solving a category of problems.
deterministic: Pertaining to a program that does the same thing each time it runs, given the same inputs.
Making a program truly nondeterministic turns out to be not so easy, but there are ways to make it at least seem nondeterministic.
pseudorandom: Pertaining to a sequence of numbers that appear to be random, but are generated by a deterministic program.

The Random module is a Python standard module. The functions in it can be used to generate pseudorandom numbers. Some example functions are:
random.random() # Return the next random floating point number in the range [0.0, 1.0].
random.randint(a, b) # Return a random integer N such that a <= N <= b.
random.choice(seq) # Return a random element from the non-empty sequence seq.
Math functions
example functions from the math module

Adding new functions

Once we define a function, we can reuse the function over and over throughout our program.
function object: A value created by a function definition. The name of the function is a variable that refers to a function object. 
Definitions and uses
The function definition is also a compound statement, therefore it has a header and a body.
function definition: A statement that creates a new function, specifying its name, parameters, and the statements it executes.
Flow of execution
Functions have to be defined in the flow of execution before their first use.
When function definition code runs, only the function object is created, but the code inside it does not run until it is called.
flow of execution: The order in which statements are executed during a program run.

Parameters and arguments
As we have seen, some of the built-in functions require arguments. Inside the function, the arguments are assigned to variables called parameters.
def print_twice(arg):
    print arg
    print arg
parameter: A name used inside a function to refer to the value passed as an argument.
composition: Using an expression as part of a larger expression, or a statement as part of a larger statement.

Fruitful functions and void functions
For lack of a better name, the functions that yield result are called here fruitful functions. In comparison to the functions that don't return a value, which are called here void functions.
fruitful function: A function that returns a value.
When you call a fruitful function, you almost always want to do something with the result; for example, you might assign it to a variable or use it as part of an expression. 
def list_twice(arg):
    twice = [arg, arg]
    return twice 
void function: A function that doesn’t return a value.
When you try to assign a void function to a variable, the value that will get assigned is the special value None.
def print_twice(arg):
    print arg
    print arg

Why functions?
There are several reasons why it is worth the trouble to divide a program into functions:
  • Creating a new function gives you an opportunity to name a group of statements, which makes your program easier to read, understand 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.
Throughout the rest of the book, often we will use a function definition to explain a concept. Part of the skill of creating and using functions is to have a function properly capture an idea such as “find the smallest value in a list of values”. This idea is captured by the function named min which takes a list of values as its argument and returns the smallest value in the list.

Notes on Python for Informatics Chapter 5: Iteration

Source

Updating variables

A common pattern in assignment statements is an assignment statement that updates a variable - where the new value of the variable depends on the old.
Before you can update a variable, you have to initialize it.

initialize: An assignment that gives an initial value to a variable that will be updated.
x = 0 # is equivalent to x = int()
x = 0.0 # is equivalent to x = float()
y = '' # is equivalent to x = str()
# the following are still not discussed types:
a = [] # is an empty list, and equivalent to a = list()
b = {} # is an empty dictionary, and equivalent to b = dict()
c = () # is an empty tuple, and equivalent to c = tuple()
Updating a variable by adding 1 is called an increment; subtracting 1 is called a decrement. decrement: An update that decreases the value of a variable.
increment: An update that increases the value of a variable (often by one).
x = x + 1 # is an incrementation and equivalent to x += 1
x = x - 1 # is a decrementation and equivalent to x -= 1

Loops and Iterations

Loops are used for repeating identical or similar tasks. Each time we execute the body of the loop (it has a header and a body, because it is a compound statement), we call it an iteration. We can say, “This loop had n iterations” which means that the body of the loop was executed n times.
iteration: Repeated execution of a set of statements using either a recursive function call or a loop.
iteration variable: The variable that is tested in the loop header condition for being True, every time the loop executes and therefore controls when the loop finishes.

The while statement
The while statement is used for repeated execution as long as an expression is true. 
The header of the statement has the conditional expression, which is repeatedly tested, while it yields True.

The flow of execution for a while statement:
  1. Evaluate the condition, yielding True or False.
  2. If the condition is True, execute the first suite of the body and then go back to step 1. 
  3. If the condition is False, and a second suite of the else clause is present, it is executed, and and the loop terminates.
In case of the while statement, the body of the loop should change the iteration variable, so that eventually the condition becomes false and the loop terminates.

Infinite loops 
infinite loop: A loop in which the terminating condition is never satisfied or for which there is no termination condition.
while True:
    print "This loop will never terminate" 
“Infinite loops” and break; and Finishing iterations with continue
The break statement breaks out of the smallest enclosing loop.
The continue statement continues with the next iteration of the loop.
This way, the "while True" loop can be controlled from within:

while True:
    line = raw_input('> ')
    if line[0] == '#' :
        continue
    if line == 'done':
        break
    print line

Definite loops using for 
When we have a list of things to loop through, we can construct a definite loop using a for statement. We call the while statement an indefinite loop because it simply loops until some condition becomes False whereas the for loop is looping through a known set of items so it runs through as many iterations as there are items in the set.
Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence.
The break and continue statements can be used with the for loop too.
Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement
A quick way to make a sequence to iterate through with the for loop is by using the built-in function range().

Loop patterns
These loops (while & for) are generally constructed by:
  • Initializing one or more variables before the loop starts.
  • Performing some computation on each item in the loop body, possibly changing the variables in the body of the loop.
  • Looking at the resulting variables when the loop completes.
Counting and summing loops
Loops are often used for counting and accumulating elements.
accumulator: A variable used in a loop to add up or accumulate a result.
counter: A variable used in a loop to count the number of times something happened. We initialize a counter to zero and then increment the counter each time we want to “count” something.