• Variables and expressions are good for one time operations, but functions allow us to reuse the same computation many times.
• A program is a sequence of operations written in a file.
• A number of operations in a program simply define functions.
• A number of operations use these functions.
• A good program separates these out very carefully.

# Basic program structure¶

• Programmers have developed some conventions over time to make programs easy to read. We will use the same in this class.
• Here is an example.
```"""
Computes the current in a given circuit and prints the result.

"""

def electric_current(voltage,resistance):
""" Returns the electric current given voltage and resistance.
Assumes that the units are compatible. """

current = float(voltage)/resistance
return current

## This is another comment
## Main code starts here. Let's define our variables first.
v = 220   # voltage in volts
r = 10    # resistance in ohms
print v, "volts", r, "ohms"
print "results in", electric_current(v,r), "amps of current"
```
• The program starts with a `comment` in quotes that describes the purpose of the program. The comment is not executed.
• This is a good place to put your pseudo code.
• Then, a number of functions will be defined that will be later used in the program. All functions should have a clear purpose.
• The function only uses variables that are in its arguments or are explicitly assigned a value within the function. For example, `current` above is a variable local to the function.
• Then, the actual code of the program starts after all functions. The code typically calls these functions to do its work and print some results.
• The code often defines some variables, like `v` and `r` above to compute what it needs to compute.
• It is a great idea to assign values to these variables all together, if possible, right after all the functions so that they are easy to locate.
• If you want, explain what the variables stand for.
• Do programs written in other formats work? Sure. But, they are hard to understand and debug. We will be very insistent that you use this format.
• This will also prepare you for more strict languages like C, C++.

# What happens when you run a program?¶

• It goes through each statement from the very beginning to the end.
• If the statement is a function definition, then it is remembered.
• If the statement calls a function or executes an expression, it is evaluated.
• What happens if your program only has function definitions?
```"""
Contains functions for converting temperature from fahrenheit to celcius,
and from celcius to fahrenheit.

"""

def to_celcius(fahrenheit):
""" Returns the celcius equivalent of a temperature in fahrenheit. """

return (5.0/9) * (fahrenheit-zero_fahrenheit)

def to_fahrenheit(celcius):
""" Returns the celcius equivalent of a temperature in fahrenheit. """

return (9.0/5) * celcius + zero_fahrenheit

zero_fahrenheit = 32
```
• This program does not do anything, but contains functions that can be used in other programs. This is a module!

# What is a Module?¶

• A collection of Python variables, functions and objects, all stored in a file

• We’ll define the notion of an object soon, but strings, ints and floats are all (built-in) objects.
• Modules allow code to be shared across many different programs.

• Before we can use a module, we need to import it:

```>>> import module_name
```
• Importing makes the functions in the module available for use.

• Python has many, many modules to accomplish many different tasks, ranging from manipulating images to accessing Twitter feeds.

• We see that all our comments become a documentation for our modules.
• Top comments are for the whole module, and the first comment after function definition is the function documentation.
• All the functions in class notes are documented in the same way to make it easy for you to understand and reuse them.
• Your modules may also use other modules.
• Make sure you put functions that share a common purpose into a single file.

# Testing¶

• Testing is the most important part of writing a program. Almost no complex program is bug free the first time.
• If you change your code, you might fix a bug in one place, but introduce a bug elsewhere.
• Best way to write programs is to divide it into small parts, functions, test them carefully and build on them.
• Testing is not a one-time process, it continues as you change your program.
• We will start with a simple method for testing in this lecture, but learn more sophisticated ways to do this in the future.

# Testing means expectations¶

• You write functions to compute something specific. Given a certain input, it should return a specific output.
• Testing should involve coming up with a set of input/output cases that can tell whether your function works correctly.
• What are good test values?
• Common values: input values you expect to be used in your program and you know what the output should be
• Values that can possibly cause errors in your program: strange input values that can cause issues such as very high and very low values, sometimes called edge cases.
• Let us try do think of some good test cases for the following function:
```def entropy(p1,p2):
x = float(p1)/(p1+p2)
y = -x * math.log(x) - (1-x) * math.log(1-x)
return y
```

# Writing test code¶

• Instead of manually typing in each test case, you can write a simple program to test your functions.
• Write your functions into a module, like the `temperate.py` module.
• Now, write code that checks the functions in this module by printing the expected output and the output returned by the function side by side.
```import temperature as tempt

print 'input: 32 F, expected output: 0 C, returned output:', tempt.to_celcius(32)
print 'input: 0 C, expected output: 32 F, returned output:', tempt.to_fahrenheit(0)
print 'input: 10 C, expected output: 10 C, returned output:', \
tempt.to_celcius(tempt.to_fahrenheit(10)), 'returned'
```
• Should we change these test cases?

• Note that:

• the backslash, `\`, is a way to tell the current statement is continuing in the next line.

• `print()` function prints the result of different

expressions. When you have multiple expressions seperated with a comma, print separates them with a space.

# Exercise Set 3¶

1. Using the `math` module and the `math.sqrt()` function, write a module that computes the length of the hypotenuse, given the length of the other edges given by the theorem:

2. List a number of good test cases for this function. Discuss in class how the function should work for these test cases.