Variables, Expressions and Statements

One of the most powerful features of a programming language is the ability to manipulate 
variables. A variable is a name that refers to a value.

Assignment Statements
An assignment statement creates a new variabble and gives it a value. A common way to 
represent variables on paper is to write the name with an arrow pointing to its value. This
kind of figure is called a state diagram.

String Operations
In general, you can't perform mathematical operations on strings, even if the strings look
like numbers, so the following are illegal: '2' - '1', 'eggs'/'easy', 'third'*'a charm'

But there are two expections + and *

The + operator performs string concatenation, which means it joins the strings by linking
them end-to-end. For example: >>> first = 'throat'	>>> second = 'warbler'	>>> first+second

The * operator also works on strings; it performs repetition. For example: 'Spam'*3 is
'SpamSpamSpam'. If one of the values is a string, the other has to be an integer.

semantics - the meaning of a program
semantic error - an error in a program that makes it do something other than what the 
programmer intended

Functions
In the context of programming, a function is a named sequence of statements that performs a
computation. When you define a function, you specify the name and the sequence of statement.

A module is a file that contains a collection of related functions.

>>> import math
This statement creates a module object named math. If you display the module object, you get
some information about it:
>>> math
<module 'math' (built-in)>

The module object contains the functions and variables defined in the module.
>>> math.log10(45) # dot notation
>>> math.sin(radians) # trigonometric functions take arguments in radians. To convert from
degrees to radians, divide by 180 and multiply by pi.
>>> radians = degrees/180 * math.pi # the expression math.pi gets the variable pi from the 
math module. The value is a floating-point approximation of pi, accurate to about 15 digitsa

Defining a function creates a function object, which has type function.

Flow of Execution
Execution always begins at the first statement of the program. Statements are run one at a 
time, in order from top to bottom. Function definitions do not alter the flow of execution 
of the progrm, but statements inside the function don't run until the function is called.

Parameters and Arguments
Inside the function, the arguments are assigned to variables called parameters. 
>>> def print_twice(bruce):
		print(bruce)
		print(bruce)

>>> print_twice(math.cos(math.pi))  # the argument is evaluated before the function is 
called, so in the example the expressions math.cos(math.pi) is only evaluated once.

Variables and Parameters are local: When you create a variable inside a function, it is 
local, which means that if only exists inside the function.

Programming is the process of gradually debugging a program until it does what you want.

traceback - a list of the functions that are executing, printed when an exception occurs

Encapsulation: Wrapping a piece of code up in a function is called encapsulation. One of the
benefits of encapsulation is that it attaches a name to the code, which serves as a kind of
documentation.

Generalization: Adding a parameter to a function is called generalization because it makes
the cuntion more general.

>>> import turtle as tl
>>> polygon(t, n=7, length=70) # these are called keyword arguments because they include the
parameter names as "keywords".

When we call a function, the arguments are assigned ot the parameters.

Interface: The interface of a function is a summary of how it is used: what are parameters?
What does the function do? And what is the return value? An interface is "clean" if it allow
the caller to do what they want without dealing with unnecessary details.

Refactoring: The process of rearranging a program to improve interfaces and facilitate code
reuse.

Development Plan: Is a process for writing programs. The process includes "encapsulation and
generalization".

docstring is a string at the beginning of a function that explains the interface.
	
	def polyline(t, n, length, angle):
		""" Draws n line segments with the given length and
			angle (in degrees) between them, t is a turtle.
		"""
		for i in range(n):
			t.fd(length)
			t.lt(angle)

By convention, all docstrings are triple quoted strings, also known as multiline strings
because the triple quotes allow the string to spin more than one line. It is terse, but it
contains the essential information someone would need to use this function. It explains
concisely what the function does (without getting into the details of how id does it). It
explains what effect each parameter has on the behaviour of the function and what type each
parameter should be (if it is not obvious).

method:	A function that is associated with an object and called using the dot notation.

When dealing with objects, functions are known as methods. Besides the terminology, methods
are invoked slightly differently than functions. When you call a function like len, you pass
the arguments in a comma separated list surrounded by parentheses affter the function name. 
When you invoke a method, you provide the name of the object the method is to act upon,
followed by a period, finally followed by the method name and the parenthesized list of 
additional arguments. Remember to provide empty parentheses if the method does not take any
arguments, so that python can distinguish a method call with no arguments from a referance
to a variable stored within the object.

Strings in python are immutable objects; this means that you can't change the value of a
string in place.

>>> str = 'institute of mathematical sciences'
>>> str.split()
['institute', 'of', 'mathematical', 'sciences']
>>> str = 'institute of mathematical  sciences'
>>> str.split(' ')
['institute', 'of', 'mathematical', ' ', 'sciences']
>>> str = 'institute-of-mathematical-sciences'
>>> str.split('-')
['institute', 'of', 'mathematical', 'sciences']	

Python offers a variety of so-called predicate methods, which take no arguments, and return 
1 if all the characters in a string are of a particular type, and 0 otherwise. These 
functions, whose use should be obvious from their names, include isalnum, isalpha, isdigit,
islower, isspace, istitle, and isupper.
