Created
May 28, 2014 19:42
-
-
Save paul-english/2c421e181b93d50f6b7c to your computer and use it in GitHub Desktop.
Intro to python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# A quick introduction to python for math students (Paul English <[email protected]>) | |
################################################################################ | |
# Python Setup | |
################################################################################ | |
# 1. Install python 2.7 (or 3.0, both should work well) | |
# 2. Install pip | |
# 3. Install numpy using the command line tool pip | |
# pip intall numpy | |
# 4. Use a specialized text editor like Sublime Edit or Emacs | |
# Run a python file by passing the file name to the python | |
# interpretor | |
# | |
# python euclid.py | |
################################################################################ | |
# Python Basics | |
################################################################################ | |
# You only need three things for a turing complete | |
# programming language: assignment, first class | |
# functions (definition and composition), | |
# and conditional branching. | |
# Assignment is done using the assignment operator "=". | |
# It's usually safer to use verbose variable names, | |
# in a complex program it's easy to confuse names that | |
# are too concise. | |
a_number = 1071 | |
some_smaller_number = 462 | |
# We use the def keyword to create a function with a name, | |
# parameters between parantheses, and a colon to represent | |
# a "block" (indented lines after a colon make up their own | |
# scope within a block) | |
def gcd_subtraction(a, b): | |
# Conditional branching is done using if/else, and a few others. | |
# Good code shouldn't nest if/else branches too deeply. Here | |
# we use the equality operator "==" to test equality. (Note: | |
# two equals signs are used to keep it distinct from the | |
# assignment operator, a common early mistake) | |
if a == b: | |
return b | |
else: | |
if b == 0: | |
return a | |
else: | |
if a != b: | |
if a > b: | |
# Recursive functions call themselves, and | |
# are synonymous with fixed point type | |
# operations. | |
return gcd_subtraction(a - b, b) | |
else: | |
return gcd_subtraction(a, b - a) | |
else: | |
return a | |
# We call a function and print the results by passing it | |
# arguments | |
print "GCD Subtraction", gcd_subtraction(a_number, some_smaller_number) | |
# Operations like division can simplify large conditional | |
# trees. "%" is the modulus operator, and it gives us a | |
# remainder. | |
def gcd_division(a, b): | |
if b == 0: | |
return a | |
else: | |
return gcd_division(b, a % b) | |
print "GCD Division", gcd_division(1071, 462) | |
# GCD is an associative operation. If GCD had accepted | |
# a dynamic number of arguments, then we would have | |
# GCD(a,b,c,d) == GCD(GCD(GCD(a,b),c),d) | |
# One way to have variable length parameters is to use | |
# arrays. | |
def gcd_reduce(numbers): | |
return reduce(gcd_division, numbers) | |
print "GCD Reduce (1071, 462):", gcd_reduce([1071, 462]) | |
print "GCD Reduce (1071, 462, 7):", gcd_reduce([1071, 462, 7]) | |
# Reduce is a catamorphism operation, and is often | |
# called fold left since it applies a function to | |
# successive arguments, and returns a single value, | |
# i.e. GCD(a,b,c,d) == GCD(GCD(GCD(a,b),c),d) | |
# We can abstract some of these ideas into a generalized | |
# fixed point operation. First we introduce the idea | |
# of an unamed function. | |
# Functions can be defined within other functions | |
# (they are hidden from the global scope), and we | |
# can pass them to other functions as arguments. | |
def fixed_point(data, f, max_steps): | |
# Using a lambda here introduces a closure | |
# where the inner function has access | |
# to the function f, and can still | |
# iterate on it's own. | |
def step(data, i): | |
next_value = f(data) | |
if next_value == data: | |
return next_value | |
else: | |
return step(next_value, i+1) | |
return step(data, max_steps) | |
# By abstracting the fixed point operation | |
# we can define GCD without introducing | |
# an explicit recursion. | |
def gcd_fixed(a, b): | |
def remainder(numbers): | |
a,b = numbers | |
if b == 0: | |
return [a, 0] | |
else: | |
return [b, a % b] | |
return fixed_point([a,b], remainder, 10)[0] | |
print "GCD Fixed", gcd_fixed(1071, 462) | |
def gcd(numbers): | |
return reduce(gcd_fixed, numbers) | |
print "GCD (1071, 462):", gcd([1071, 462]) | |
print "GCD (1071, 462, 7):", gcd([1071, 462, 7]) | |
# Now we have a simple GCD function, and most | |
# importantly an abstraction that can be | |
# applied to future computations. | |
################################################################################ | |
# Numpy | |
################################################################################ | |
# We can bring in core libraries or 3rd-party libraries using import. | |
# "as np" gives us some convenience when using numpy. | |
import numpy as np | |
# Matrices are multidimensional arrays, we wrap them in the numpy | |
# array function so we can perform matrix operations. | |
A = np.array([[1, 2], | |
[3, 4]]) | |
B = np.array([[10], | |
[3]]) | |
I = np.identity(2) | |
zeros = np.zeros([2,2]) | |
print "Scalar multiplication" | |
print A * 3 | |
print "Matrix multiplication (inner product)" | |
print np.dot(A, I) | |
print np.dot(A, B) | |
print np.dot(A, zeros) | |
################################################################################ | |
# STDIN & STDOUT | |
################################################################################ | |
# Anything you "print" will, by default go to STDOUT, | |
# thus your programs are set to pipe by default. | |
print # This is just a new line | |
print "This goes to stdout" | |
# To accept input we use a core python library. | |
import sys | |
# Sys requires us to access our input as though it were | |
# a file, reading one line at a time. We do this safely | |
# using the "with" and "open" keywords | |
stdin = sys.stdin | |
print "input: ", stdin.read() | |
stdin.close() | |
# Try it out at the command line, | |
# echo "My own input string" | python euclid.py | |
################################################################################ | |
# Lastly | |
################################################################################ | |
# Make use of documentation and search to solve most issues | |
# - The Python Documentation | |
# - The Numpy Documentation | |
# - Stackoverflow.com | |
print "Fin" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment