{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "255a85ee-bde5-46d6-bcd0-863af671c858"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# ASTR 212: Week 1 - Python Intro"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "0673cd39-5c02-412a-8eba-657c61bbc5a5"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# 1. Install\n",
    "\n",
    "Let's start by installing Python - the primary programming language we'll be using for this course - and the associated Anaconda distribution. Go to\n",
    "\n",
    "https://www.anaconda.com/download/\n",
    "\n",
    "and download the Python 3.6 Version. \n",
    "\n",
    "If you already have 2.7, make an environment where you update to Python 3.6. \n",
    "\n",
    "(*Side Note: Ask about familiarity with the terminal, give brief intro if needed*)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "a35ba5a4-6913-4d03-a8da-139133332186"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# 2. Getting Started with Python"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "ecb49234-720c-4cd5-9711-b31eebbfbb7a"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "What is Python? (going off of Downey, *Think Python* http://www.greenteapress.com/thinkpython/thinkpython.pdf, but see also https://docs.python.org/3/tutorial/)\n",
    "\n",
    "First, we should define the term **computer program**.\n",
    "\n",
    "A **program** is a series of commands given to the computer which specify a computational task. The **language** in which one writes a program determines what commands one uses. As scientists, the utility of computer programs comes from the fact that they allow us to perform computations on much more numerical data than we ever could by hand."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Values and Types\n",
    "\n",
    "*Values* are basic things a program works with, such as numbers and symbols. Each value has an associated *type* which determines how the program is allowed to deal with the value and the type of computations it can be used to perform."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "32"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "\"a string\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "type(32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "type(\"a string\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "type(32.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "type(\"32\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lists are arguably the most basic Python *compound* data type, in that they represent a grouping of individual values. One designates a list with square brackets and commas in between individual list elements"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "[1, 2, 3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "type([1, 2, 3])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python can be used like a calculator on numerical types"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "32 + 24"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "24/35"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Variables\n",
    "\n",
    "Probably the most immediately powerful aspect of programming languages generally is their ability to define and manipulate **variables**, or names that refer to values. This concept is familiar from math, but variables in Python can represent non-numerical types such as strings and lists. \n",
    "\n",
    "Variables are created with *assignment statements*, which are structured \"[variable name] = [value]\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "str1 = \"a string\"\n",
    "x = 32.\n",
    "y = 200."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can then perform any computational task on these variables as we would their values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "x + y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "print(str1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Stylistic Notes:\n",
    "* Variable names should be informative, but not too long (try <15 characters)\n",
    "* Must begin with a letter, can contain letters and numbers, as well as the underscore character '_'. Can use either underscores (variable_name) or camelCase to include multiple words in variable name. \n",
    "* *Cannot* be a python **keyword**, a small set of commands that determine program structure or perform a specific task fundamental to the language. These are:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import keyword\n",
    "print(keyword.kwlist)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## Operations\n",
    "\n",
    "As seen above, Python contains a set of built-in **operations** which perform basic computations like arithmetic. Specifically, $+$, $-$, $*$, $/$ and $**$ represent addition, subtraction, multiplication, division, and exponentiation (NOT ^). Standard PEMDAS rules of precedence apply - when in doubt, use parentheses.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Exercise: verify these operations, as well as their order of precedence, for yourself with variables representing numerical values**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# insert code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Operations on Strings, Lists\n",
    "\n",
    "If a value has is a string, it you can't generally apply mathematical operations on it "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "'2'/'1'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*However*, not true for addition, which is links strings in a process called **concatenation**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "A = 'the'\n",
    "B = 'string'\n",
    "C = A + B\n",
    "print(C)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "and multiplication, which results in **repetition**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "print(C*3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In practice, however, there are much more powerful methods for manipulating and formatting strings in Python, which we will get to shortly."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Control Flow Tools\n",
    "\n",
    "Python contains several key *control flow* statements (which make up many of the language-protected keywords) that determine the logical progression of the code's execution. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### if/elif/else"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "x = 0\n",
    "if x < 0:\n",
    "    print('x is Negative')\n",
    "elif x > 0:\n",
    "    print('x is Positive')\n",
    "else:\n",
    "    print('x is 0')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that \"if\" statements require a **logical expression**, a statement that python can evaluate as \"True\" or \"False\":"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "1 == 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "1 == 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "'a' == 'b'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "'a' == 'a'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "'a' = 'a'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### for (and range)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "Nloop = 10\n",
    "list_val = [0, 1, 2, 3, 4]\n",
    "for i in list_val:\n",
    "    i2 = i**2\n",
    "    print(i2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "A_list = [2., 3., 5., 6., 9., 20.]\n",
    "for j in A_list:\n",
    "    ratio = j/200.\n",
    "    print(ratio)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### while"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "i = 22\n",
    "while i > 0:\n",
    "    i = i - 1\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Functions** allow the user to define a piece of code that takes input, performs a specified (ideally simple and easily-stated, more on this later) task, and returns an output. These are *immensely* useful tools for structuring your program - most of your code should be apportioned into functions which are utilized (\"called\") throughout the process of your analysis. This makes the logical flow maximally transparent and thus facilitates quicker debugging."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def fib(n): # write Fibonacci series up to n\n",
    "    \"\"\"Print a Fibonacci series up to n.\"\"\"\n",
    "    a = 0\n",
    "    b = 1\n",
    "    nit = 0\n",
    "    while a < n:\n",
    "        print(a)\n",
    "        a_next = b\n",
    "        b_next = a + b\n",
    "        a = a_next\n",
    "        b = b_next\n",
    "        nit = nit + 1\n",
    "    return nit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "print('fib up to 2000')\n",
    "fib2000 = fib(2000)\n",
    "print(fib2000)\n",
    "print('fib up to 10000')\n",
    "fib10000 = fib(10000)\n",
    "print(fib10000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Things to note:\n",
    "* definition statement: \"def [name]([arguments])\"\n",
    "* docstring\n",
    "* indentation\n",
    "* return statement"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. Python Libraries"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Probably Python's greatest strength as a scientific programming language - besides it's readability and consequently (relatively) mild learning-curve - is the immense toolkit of analysis routines that have already been developed in the form of publicly available *code libraries* or *packages*. \n",
    "\n",
    "Anaconda gives you access to or easy installation of effectively all such packages that are potentially useful for scientific analysis. Effectively, these libraries consist of functions someone has already written to perform a specific task. This is useful because it obviates the need to re-invent the wheel of much scientific data analysis. Although it is often useful or even necessary to develop your own implementations of publicly available analysis routines, ones in standard packages such as Numpy, Scipy and Matplolib have been thoroughly tested and optimized. \n",
    "\n",
    "Libraries you will find **IMMENSELY** useful throughout your research:\n",
    "\n",
    "* NumPy: http://www.numpy.org/ - great for dealing with large amounts of data, basic data/statistical analysis\n",
    "* SciPy: https://www.scipy.org/ - fundamental library for scientific computing \n",
    "* MatPlotLib: https://matplotlib.org/ - plotting library.\n",
    "\n",
    "There are many others, but we will begin by exploring these. \n",
    "\n",
    "To give yourself access to a library’s functions use the \"import\" command\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import scipy\n",
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## NumPy Arrays"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "A = np.array([1, 2, 3])\n",
    "B = np.array([7, 22, 1])\n",
    "\n",
    "print(A[0])\n",
    "print(A[0:1])\n",
    "print(A[:])\n",
    "print(A[-1])\n",
    "\n",
    "C = A*B\n",
    "print(C)\n",
    "D = A/B\n",
    "print(D)\n",
    "print(D[3])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Figures with Matplotlib\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "fig = plt.figure()\n",
    "plt.plot(1, 1, '.')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "x = np.linspace(0., 1., 100)\n",
    "y = x\n",
    "\n",
    "fig = plt.figure()\n",
    "plt.plot(x, y)\n",
    "plt.xlabel('x')\n",
    "plt.ylabel('y')\n",
    "plt.title('y = x')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "x = np.linspace(0., 1., 100)\n",
    "y = x\n",
    "\n",
    "fig = plt.figure()\n",
    "ax = plt.subplot(111)\n",
    "ax.plot(x, y)\n",
    "ax.set_xlabel('x')\n",
    "ax.set_ylabel('y')\n",
    "ax.set_title('y = x')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "x = np.linspace(0., 1., 100)\n",
    "y1 = x\n",
    "y2 = -1.*x\n",
    "\n",
    "fig, ax = plt.subplots(1, 2, figsize = (8, 4))\n",
    "ax[0].plot(x, y1)\n",
    "ax[0].set_xlabel('x')\n",
    "ax[0].set_ylabel('y1')\n",
    "ax[0].set_title('y = x')\n",
    "\n",
    "ax[1].plot(x, y2)\n",
    "ax[1].set_xlabel('x')\n",
    "ax[1].set_ylabel('y2')\n",
    "ax[1].set_title('y = -x')\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Exercise: Plot a sinusoid**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# insert code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Exercise: Plot a histogram of normally-distributed random numbers**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# insert code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Exercise: Add normally-distributed scatter to your sinusoid, plot with origional, include separate pannel for residuals.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# insert code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Exercise: Make a \"heat map\" of a 2D function of your choosing. Add contours**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# insert code here"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [sims_analysis_env]",
   "language": "python",
   "name": "Python [sims_analysis_env]"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
