simplelist = [1,3.4,['a',5],"somethin'",("bar","foo")]

for thing in simplelist:
    print thing
print "\n" #Add an extra new line
print "This is after the loop"

"""
Explanation: Loops, functions and conditional statements
This far, python has worked more or less like an advanced calculator. One of the strong advantages of using a programming language for mathematics is the possibility to write your own functions and to get the computer to repeat a task many times. We will start with the second bit.
Loops
In mathematics we often define objects using indexes over a cenrain domain. We might sum the integers from $0$ to $n$ or define a sequence $(\frac{1}{k})_{k = 1}^N$. How do we do this in python? We use loops for this. A loop is a set of instructions that tell the interpreter to repeat some code until a condition is met. The most common ones in python are the for-loop and the while-loop. We will look at the for-loop, there is plenty documentation on while-loops on the web. The basic structure of the for-loop is this:
for ELEMENT in LIST:
    do this
    and do this
this is not performed in the loop

What it means is that ELEMENT takes of each value in LIST and the indented code is excecuted for each step. After ELEMENT has taken on each value of LIST the loop is finished and the iterpreter goes to the next line of code. Here is an example:
End of explanation
"""


anotherList = [[1,2],[3,2],[3,4]]
for first in anotherList:
    for second in first: #first is a list so it can be used in a loop
        print second

"""
Explanation: Notice that the indentation is crucial. This is how python knows that certain lines of code belong to the loop. The standard is to use four spaces for indentation and I strongly urge you to do the same, but as long as the indentation is consistent within each block the code will run. Blocks of code can be conditions, loops or functions and they can be within other blocks of code.
End of explanation
"""


simpletuple = (2,3,"2")
for i in simpletuple:
    print i

some_string = "Dust tastes good"
for i in some_string:
    print i

"""
Explanation: while lists are the most common to loop over, you can loop over any object that is ordered.
End of explanation
"""


range(10)

range(1,11) #instead create a list from 1 up to but not including 11

"""
Explanation: Often you want to just repeat the code a certain amount of times or do it from, say, $0$ to $n$. To do this we can use the range function.
End of explanation
"""


solution = 1
for i in range(1,55):
    solution = solution * i
print solution

"""
Explanation: To use this to find the factorial of $54$ we could write
End of explanation
"""


sequence = []
for i in range(1,15):
    sequence.append(1.0/i)
print sequence

"""
Explanation: We can also use loops to create lists. Here is an example of the sequence $(\frac{1}{n})_{n=1}^{14}$
End of explanation
"""


sequence = [1.0/i for i in range(1,15)]
print sequence

"""
Explanation: There is another way to create the same list which might be a bit easier for mathematicians to write and to read. You can create it like this:
End of explanation
"""


def some_function(x, y):
    theResult = 2*x + y - x*y
    return theResult

"""
Explanation: Functions
We have already used several functions in python. They work very much the same as functions behave in mathematics. For example, if we have the function $f(x,y) = 2x + y - xy$ we expect it to demand to values for $x$ and $y$ and return $2x + y - xy$ as a single value. In python, the structure of a function is as follows:
def FUNCTION(VARIABLES):
    the function does
    several things
    and usually ends with
    return RESULT

Which means that if we want to define the function above we simply write. Remember that the code of the function has to be indented!
End of explanation
"""


theResult = some_function(3,1)
print theResult

"""
Explanation: The return statement means that the function will return that as the answer. It is not neccessary to include it as some functions might print things instead, but it is very common for it to be included. If we wish to use the function we simply write
End of explanation
"""


def factorial(x):
    result = 1
    for i in range(1, x + 1): # Remember that range(a,b) creates the list [a, a + 1, ..., a - 1]
        result *= i
    return result

def choose(n, k):
    result = factorial(n)/(factorial(k)*factorial(n - k))
    return result

print choose(10,5)

"""
Explanation: A function can call other functions and can even call on itself. If we wanted to create a function that calculated
${n\choose k} = \frac{n!}{k!(n-k)!}$ we could first define a function that calculated the factorial which we use to calculate the original function
End of explanation
"""


import math

math.factorial(5)

"""
Explanation: Importing libraries
Even though there are many functions in python from the start, there are many more we might need. The function factorial does not exist in python from the start which meant we had to write it, and it is the same with many other useful functions. Most of these have actually already been written by someone else. To include them we need to import the library that they are in. A library can be seen as a set of functions and when we import the library we make the functions available to the interpreter. The function factorial exists in the library math which we can import and use the function from there. To use a function from a library we first have to state the library and then that function with a dot in between
LIBRARY.FUNCTION
End of explanation
"""


from math import cos, pi
cos(2*pi)

"""
Explanation: We can also import specific functions from a library by writing
End of explanation
"""


4 > 3

7 == 1

4 >= 4

4 != 4

"""
Explanation: Notice that in this case we do not use the function by first friting the name of the library.
Conditional statements
Conditional statements are often called if-statements. You write them as follows:
if CONDITION:
    do this
elif ANOTER_CONDITION:
    do that
else:
    this should be done

the interpreter goes through each statement until it finds a condition that is true and executes the code in that statement. After that, the interpreter goes past the other elif and else statements. If None of the statementents are true it executes the code in the else part. When using if-statements we need to know some things about relational symbols first. These are <, >, ==, and !. < means less than, > means greater than, == means equal (not the same as = which is assignment) and ! means not.
End of explanation
"""


if 3 > 6:
    print "{} is larger than {}".format(3, 6)
elif 3 < 5:
    print "{} is smaller than {}".format(3, 5)
elif 3 != 12:
    print "{} is not equal to {}".format(3, 12)
else:
    print "Tomatopaste"

"""
Explanation: As you can see some can be combined to mean greater than or equal and not equal. Try it out and see which combinations work and which don't. Using these we can write some simple conditional statements:
End of explanation
"""


