http://git-wip-us.apache.org/repos/asf/incubator-sdap-nexus/blob/ff98fa34/esip-workshop/student-material/workshop1/3
 - Python Basics.ipynb
----------------------------------------------------------------------
diff --git a/esip-workshop/student-material/workshop1/3 - Python Basics.ipynb 
b/esip-workshop/student-material/workshop1/3 - Python Basics.ipynb
new file mode 100644
index 0000000..1150654
--- /dev/null
+++ b/esip-workshop/student-material/workshop1/3 - Python Basics.ipynb  
@@ -0,0 +1,1111 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "collapsed": true
+   },
+   "source": [
+    "# Tutorial Brief\n",
+    "This tutorial is an introduction to Python 3. This should give you the 
set of `pythonic` skills that you will need to proceed with this tutorial 
series.\n",
+    "\n",
+    "If you don't have the Jupyter installed, shame on you. No just kidding 
you can follow this tutorial using an online jupyter service:\n",
+    "\n",
+    "https://try.jupyter.org/\n";,
+    "\n",
+    "## Cell Input and Output"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "1+2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "1+1\n",
+    "1+2"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## The `print` function\n",
+    "\n",
+    "**Notice:** `print` is a function in Python 3. You should use parentheses 
around your parameter."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "print(1+2)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Variables\n",
+    "\n",
+    "There are many variable types in Python 3. Here is a list of the most 
common types:\n",
+    "\n",
+    "### Numerical Types:\n",
+    "- bool (Boolean)\n",
+    "- int (Integer/Long)\n",
+    "- float\n",
+    "- complex\n",
+    "\n",
+    "**Notice:** In Python 3 integer represents integer and long. Because 
there is no more long data type, you will not get `L` at the end of long 
integers."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "a = 4\n",
+    "b = 1.5\n",
+    "c = 
121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212\n",
+    "d = 1j\n",
+    "e = 1/3\n",
+    "f = True"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "a+b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "a*c"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "(b+d)*a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "a+f"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "type(1.5)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Other Value Types:\n",
+    "- str (String)\n",
+    "- list (Ordered Array)\n",
+    "- tuple (Ordered Immutable Array)\n",
+    "- dict (Unordered list of keys and values)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_name = \"Roshan\"\n",
+    "print(my_name)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list = [1,2,3,4,5]\n",
+    "my_list"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list + [6]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list += [6,7,8]\n",
+    "my_list"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list.append(9)\n",
+    "my_list"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_tuple = (1,2,3)\n",
+    "my_tuple"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_tuple + (4,5,6)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_dict = {\"name\":\"Roshan\", \"credit\":100}\n",
+    "my_dict"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_dict[\"name\"]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_dict[\"level\"] = 4\n",
+    "my_dict"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_dict.values()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_dict.keys()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Selecting / Slicing\n",
+    "\n",
+    "Use `len` function to measure the length of a list."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "len(my_list)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "To access a single value in a list use this syntax:\n",
+    "```python\n",
+    "list_name[index]\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list[0]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "To select multiple value from a list use this syntax:\n",
+    "\n",
+    "```python\n",
+    "index[start:end:step]\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list[1:2]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list[:3]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list[3:]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**Notice:** negative index selected from the end of the list"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list[-1]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list[-2]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You can use negative indexing in selecting multiple values."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list[-2:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list[:-2]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list[3:-1]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The third location in the index is the `step`. If the `step` is negative 
the the list is returned in descending order."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list[::2]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list[3::2]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_list[::-1]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Working with Strings\n",
+    "\n",
+    "You can select from a string like a list suing this syntax:\n",
+    "\n",
+    "```python\n",
+    "my_string[star:end:step]\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_name"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_name[0]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**Notice:** You can also use negative indexing."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "my_name[:2]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Unicode\n",
+    "\n",
+    "**Notice:** You can use unicode inside your string variables. Unlike 
Python 2, no need to use `u\"\"` to use unicode."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Sorted by most spoken languages in order\n",
+    "divide_by_zero = {\"zho\":\"你不能除以零\",\n",
+    "                  \"eng\":\"You cannot divide by zero\",\n",
+    "                  \"esp\":\"No se puede dividir por cero\",\n",
+    "                  \"hin\":\"आप शून्य से 
विभाजित नहीं किया जा सकता 
\\u2248\",\n",
+    "                  \"arb\":\"لا يمكن القسمة على 
صفر\"}\n",
+    "\n",
+    "print(divide_by_zero[\"hin\"])\n",
+    "type(divide_by_zero[\"hin\"])"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## String Formatting\n",
+    "\n",
+    "You can use this syntax to format a string:\n",
+    "\n",
+    "```python\n",
+    "some_variable = 50\n",
+    "x = \"Value: %s\" % some_variable\n",
+    "print(x) # Value: 50\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "first_name = \"Roshan\"\n",
+    "last_name = \"Rush\"\n",
+    "formatted_name = \"%s, %s.\" % (last_name, first_name[0])\n",
+    "print(formatted_name)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Other formatters could be used to format numbers:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "print(\"π ≈ %.2f\" % 3.14159)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "To find unicode symbols:\n",
+    "\n",
+    "http://www.fileformat.info/info/unicode/char/search.htm";
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "homeworks = 15.75\n",
+    "midterm = 22\n",
+    "final = 51\n",
+    "total = homeworks + midterm + final\n",
+    "\n",
+    "print(\"Homeworks: %.2f\\nMid-term: %.2f\\nFinal: %.2f\\nTotal: 
%.2f/100\" % (homeworks, midterm, final, total))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Using `format(*args, **kwargs)` function"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "url = \"http://{language}.wikipedia.org/\"\n";,
+    "url = url.format(language=\"en\")\n",
+    "url"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Mathematics"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "1+1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "4-5"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**Notice:** The default behavior of division in Python 3 is float 
division. To use integer division like Python 2, use `//`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "14/5"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "14//5"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "2*5"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "To raise a number to any power use down asterisk `**`. To represent 
$a^{n}$:\n",
+    "\n",
+    "```python\n",
+    "a**n\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "2**3"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "To calculate the remainder (modulo operator) use `%`. To represent $a 
\\mod b = r$:\n",
+    "\n",
+    "```python\n",
+    "a % b # Returns r\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "10 % 3"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You can "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You can use the `math` library to access a varaity of tools for algebra 
and geometry. To import a library, you can use one of these syntaxes:\n",
+    "\n",
+    "```python\n",
+    "import library_name\n",
+    "import library_name as alias\n",
+    "from module_name import some_class\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import math"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "n=52\n",
+    "k=1\n",
+    "math.factorial(n) / (math.factorial(k) * math.factorial(n-k))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Loops"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "for counter in [1,2,3,4]:\n",
+    "    print(counter)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### range\n",
+    "\n",
+    "In Python 3 `range` is a data type that generates a list of numbers.\n",
+    "\n",
+    "```python\n",
+    "range(stop)\n",
+    "range(start,stop[ ,step])\n",
+    "```\n",
+    "\n",
+    "**Notice:** In Python 2 `range` is a function that returns a list. In 
Python 3, `range` returns an iterable of type `range`. If you need to get a 
list you can use the `list()` function:\n",
+    "\n",
+    "```python\n",
+    "list(range(start,stop[, step]))\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "for counter in range(5):\n",
+    "    print(counter)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**Notice:** The list doesn't reach the `stop` value and stops one `step` 
before. The reason behind that is to make this syntax possible:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "list(range(1,10)) == list(range(1,5)) + list(range(5,10))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**Notice:** In Python 3 use use `==` to check if two values are equal. To 
check if two values are not equal use `!=` and don't use `<>` from Python 2 
because it is not supported any more in Python 3."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "for counter in range(1,5):\n",
+    "    print(counter)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "for counter in range(2,10,2):\n",
+    "    print(counter)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### While Loop"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "counter =1\n",
+    "while counter < 5:\n",
+    "    print(counter)\n",
+    "    counter += 1"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## If .. Else"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "if math.pi == 3.2:\n",
+    "    print(\"Edward J. Goodwin was right!\")\n",
+    "else:\n",
+    "    print(\"π is irrational\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "if math.sqrt(2) == (10/7):\n",
+    "    print(\"Edward J. Goodwin was right!\")\n",
+    "elif math.sqrt(2) != (10/7):\n",
+    "    print(\"Square root of 2 is irrational\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### If you like Math:\n",
+    "Fun story about pi where it was *almost* set by law to be equal to 
3.2!\n",
+    "\n",
+    "If you don't what is the \"pi bill\" you can read about it here:\n",
+    "http://en.wikipedia.org/wiki/Indiana_Pi_Bill\n";,
+    "\n",
+    "Or watch Numberphile video about it:\n",
+    "https://www.youtube.com/watch?v=bFNjA9LOPsg";
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "probability = 0.3\n",
+    "\n",
+    "if probability >= 0.75:\n",
+    "    print(\"Sure thing\")\n",
+    "elif probability >= 0.5:\n",
+    "    print(\"Maybe\")\n",
+    "elif probability >= 0.25:\n",
+    "    print(\"Unusual\")\n",
+    "else:\n",
+    "    print(\"No way\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Functions\n",
+    "\n",
+    "Functions are defined in Python using `def` keyword."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def get_circumference(r):\n",
+    "    return math.pi * r * 2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "get_circumference(5)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def binomilal_coef(n,k):\n",
+    "    \"\"\"\n",
+    "    This function returns the binominal coef\n",
+    "    \n",
+    "    Parameters:\n",
+    "    ===========\n",
+    "    n, k int\n",
+    "    \n",
+    "    return n!/(k!*(n-k)!)\n",
+    "    \"\"\"\n",
+    "    value = math.factorial(n)/(math.factorial(k)*math.factorial(n-k))\n",
+    "    return value\n",
+    "\n",
+    "\n",
+    "binomilal_coef(52,2)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**Notice:** Use can use SHIFT+TAB to show the docstring of a function."
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "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.1"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}

http://git-wip-us.apache.org/repos/asf/incubator-sdap-nexus/blob/ff98fa34/esip-workshop/student-material/workshop1/4
 - Student Exercise.ipynb
----------------------------------------------------------------------
diff --git a/esip-workshop/student-material/workshop1/4 - Student 
Exercise.ipynb b/esip-workshop/student-material/workshop1/4 - Student 
Exercise.ipynb
new file mode 100644
index 0000000..0ce1022
--- /dev/null
+++ b/esip-workshop/student-material/workshop1/4 - Student Exercise.ipynb       
@@ -0,0 +1,479 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Step 1: Notebook Setup\n",
+    "\n",
+    "The cell below contains a number of helper functions used throughout this 
walkthrough. They are mainly wrappers around existing `matplotlib` 
functionality and are provided for the sake of simplicity in the steps to 
come.\n",
+    "\n",
+    "Take a moment to read the descriptions for each method so you understand 
what they can be used for. You will use these \"helper methods\" as you work 
through this notebook below.\n",
+    "\n",
+    "If you are familiar with `matplotlib`, feel free to alter the functions 
as you please.\n",
+    "\n",
+    "## TODOs\n",
+    "\n",
+    "1. Click in the cell below and run the cell."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# TODO: Make sure you run this cell before continuing!\n",
+    "\n",
+    "%matplotlib inline\n",
+    "import matplotlib.pyplot as plt\n",
+    "\n",
+    "def show_plot(x_data, y_data, x_label, y_label):\n",
+    "    \"\"\"\n",
+    "    Display a simple line plot.\n",
+    "    \n",
+    "    :param x_data: Numpy array containing data for the X axis\n",
+    "    :param y_data: Numpy array containing data for the Y axis\n",
+    "    :param x_label: Label applied to X axis\n",
+    "    :param y_label: Label applied to Y axis\n",
+    "    \"\"\"\n",
+    "    plt.figure(figsize=(10,5), dpi=100)\n",
+    "    plt.plot(x_data, y_data, 'b-', marker='|', markersize=2.0, 
mfc='b')\n",
+    "    plt.grid(b=True, which='major', color='k', linestyle='-')\n",
+    "    plt.xlabel(x_label)\n",
+    "    plt.ylabel (y_label)\n",
+    "    plt.show()\n",
+    "    \n",
+    "def plot_box(bbox):\n",
+    "    \"\"\"\n",
+    "    Display a Green bounding box on an image of the blue marble.\n",
+    "    \n",
+    "    :param bbox: Shapely Polygon that defines the bounding box to 
display\n",
+    "    \"\"\"\n",
+    "    min_lon, min_lat, max_lon, max_lat = bbox.bounds\n",
+    "    import matplotlib.pyplot as plt1\n",
+    "    from matplotlib.patches import Polygon\n",
+    "    from mpl_toolkits.basemap import Basemap\n",
+    "\n",
+    "    map = Basemap()\n",
+    "    map.bluemarble(scale=0.5)\n",
+    "    poly = 
Polygon([(min_lon,min_lat),(min_lon,max_lat),(max_lon,max_lat),(max_lon,min_lat)],facecolor=(0,0,0,0.0),edgecolor='green',linewidth=2)\n",
+    "    plt1.gca().add_patch(poly)\n",
+    "    plt1.gcf().set_size_inches(10,15)\n",
+    "    \n",
+    "    plt1.show()\n",
+    "    \n",
+    "def show_plot_two_series(x_data_a, x_data_b, y_data_a, y_data_b, x_label, 
y_label_a, y_label_b, series_a_label, series_b_label):\n",
+    "    \"\"\"\n",
+    "    Display a line plot of two series\n",
+    "    \n",
+    "    :param x_data_a: Numpy array containing data for the Series A X 
axis\n",
+    "    :param x_data_b: Numpy array containing data for the Series B X 
axis\n",
+    "    :param y_data_a: Numpy array containing data for the Series A Y 
axis\n",
+    "    :param y_data_b: Numpy array containing data for the Series B Y 
axis\n",
+    "    :param x_label: Label applied to X axis\n",
+    "    :param y_label_a: Label applied to Y axis for Series A\n",
+    "    :param y_label_b: Label applied to Y axis for Series B\n",
+    "    :param series_a_label: Name of Series A\n",
+    "    :param series_b_label: Name of Series B\n",
+    "    \"\"\"\n",
+    "    fig, ax1 = plt.subplots(figsize=(10,5), dpi=100)\n",
+    "    series_a, = ax1.plot(x_data_a, y_data_a, 'b-', marker='|', 
markersize=2.0, mfc='b', label=series_a_label)\n",
+    "    ax1.set_ylabel(y_label_a, color='b')\n",
+    "    ax1.tick_params('y', colors='b')\n",
+    "    ax1.set_ylim(min(0, *y_data_a), max(y_data_a)+.1*max(y_data_a))\n",
+    "    ax1.set_xlabel(x_label)\n",
+    "    \n",
+    "    ax2 = ax1.twinx()\n",
+    "    series_b, = ax2.plot(x_data_b, y_data_b, 'r-', marker='|', 
markersize=2.0, mfc='r', label=series_b_label)\n",
+    "    ax2.set_ylabel(y_label_b, color='r')\n",
+    "    ax2.set_ylim(min(0, *y_data_b), max(y_data_b)+.1*max(y_data_b))\n",
+    "    ax2.tick_params('y', colors='r')\n",
+    "    \n",
+    "    plt.grid(b=True, which='major', color='k', linestyle='-')\n",
+    "    plt.legend(handles=(series_a, series_b), bbox_to_anchor=(1.1, 1), 
loc=2, borderaxespad=0.)\n",
+    "    plt.show()\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Step 2: List available Datasets\n",
+    "\n",
+    "Now we can interact with NEXUS using the `nexuscli` python module. The 
`nexuscli` module has a number of useful methods that allow you to easily 
interact with the NEXUS webservice API. One of those methods is 
`nexuscli.dataset_list` which returns a list of Datasets in the system along 
with their start and end times.\n",
+    "\n",
+    "However, in order to use the client, it must be told where the NEXUS 
webservice is running. The `nexuscli.set_target(url)` method is used to target 
NEXUS. An instance of NEXUS is already running for you and is available at 
`http://nexus-webapp:8083`.\n";,
+    "\n",
+    "## TODOs\n",
+    "\n",
+    "1. Import the `nexuscli` python module.\n",
+    "2. Call `nexuscli.dataset_list()` and print the results"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# TODO: Import the nexuscli python module.\n",
+    "\n",
+    "\n",
+    "# Target the nexus webapp server\n",
+    "nexuscli.set_target(\"http://nexus-webapp:8083\";)\n",
+    "\n",
+    "# TODO: Call nexuscli.dataset_list() and print the results\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Step 3: Run a Time Series\n",
+    "\n",
+    "Now that we can interact with NEXUS using the `nexuscli` python module, 
we would like to run a time series. To do this, we will use the 
`nexuscli.time_series` method. The signature for this method is described 
below:\n",
+    "\n",
+    "\n",
+    ">nexuscli.time_series(datasets, bounding_box, start_datetime, 
end_datetime, spark=False)  \n",
+    ">  \n",
+    ">Send a request to NEXUS to calculate a time series.  \n",
+    ">  \n",
+    "__datasets__ Sequence (max length 2) of the name of the dataset(s)  \n",
+    "__bounding_box__ Bounding box for area of interest as a 
`shapely.geometry.polygon.Polygon`  \n",
+    "__start_datetime__ Start time as a `datetime.datetime`  \n",
+    "__end_datetime__ End time as a `datetime.datetime`  \n",
+    "__spark__ Optionally use spark. Default: `False`\n",
+    ">  \n",
+    ">__return__ List of `nexuscli.nexuscli.TimeSeries` namedtuples\n",
+    "```\n",
+    "\n",
+    "As you can see, there are a number of options available. Let's try 
investigating [The 
Blob](https://en.wikipedia.org/wiki/The_Blob_%28Pacific_Ocean%29) in the 
Pacific Ocean. The Blob is an abnormal warming of the Sea Surface Temperature 
that was first observed in 2013.\n",
+    "\n",
+    "Generate a time series for the `AVHRR_OI_L4_GHRSST_NCEI` SST dataset for 
the time period 2013-01-01 through 2014-03-01 and a bounding box `-150, 40, 
-120, 55` (west, south, east, north).\n",
+    "\n",
+    "## TODOs\n",
+    "\n",
+    "1. Create the bounding box using shapely's `box` method\n",
+    "2. Plot the bounding box using the `plot_box` helper method\n",
+    "3. Generate the Time Series by calling the `time_series` method in the 
`nexuscli` module\n",
+    "  - __Hint__: `datetime` is already imported for you. You can create a 
`datetime` using the method `datetime(int: year, int: month, int: day)`\n",
+    "  - __Hint__: pass `spark=True` to the `time_series` function to speed up 
the computation\n",
+    "4. Plot the result using the `show_plot` helper method"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import time\n",
+    "import nexuscli\n",
+    "from datetime import datetime\n",
+    "\n",
+    "from shapely.geometry import box\n",
+    "\n",
+    "# TODO: Create a bounding box using the box method imported above\n",
+    "\n",
+    "# TODO: Plot the bounding box using the helper method plot_box\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Do not modify this line ##\n",
+    "start = time.perf_counter()#\n",
+    "############################\n",
+    "\n",
+    "\n",
+    "# TODO: Call the time_series method for the AVHRR_OI_L4_GHRSST_NCEI 
dataset using \n",
+    "# your bounding box and time period 2013-01-01 through 2014-03-01\n",
+    "\n",
+    "\n",
+    "# Enter your code above this line\n",
+    "print(\"Time Series took {} seconds to 
generate\".format(time.perf_counter() - start))\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# TODO: Plot the result using the `show_plot` helper method\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Step 3a: Run for a Longer Time Period\n",
+    "\n",
+    "Now that you have successfully generated a time series for approximately 
one year of data. Try generating a longer time series by increasing the end 
date to `2016-12-31`. This will take a little bit longer to execute, since 
there is more data to analyze, but should finish in under a minute.\n",
+    "\n",
+    "The significant increase in sea surface temperature due to the blob 
should be visible as an upward trend between 2013 and 2015 in this longer time 
series.\n",
+    "\n",
+    "## TODOs\n",
+    "1. Generate a longer time series from `2013-01-01` to `2016-12-31`\n",
+    "2. Plot the result using the `show_plot` helper method. Make sure you 
pass `spark=True` to the time_series function to speed up the analysis\n",
+    "\n",
+    "## Advanced (Optional)\n",
+    "1. For an extra challenge, try plotting the trend line.\n",
+    "  - __Hint__ `numpy` and `scipy` packages are installed and can be used 
by importing them: `import numpy` or `import scipy`\n",
+    "  - __Hint__ You will need to convert the TimeSeries.time array to 
numbers in order to generate a polynomial fit line. `matplotlib` has a built in 
function capable of doing this: `matplotlib.dates.date2num` and it's inverse 
`matplotlib.dates.num2date`\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import time\n",
+    "import nexuscli\n",
+    "from datetime import datetime\n",
+    "\n",
+    "from shapely.geometry import box\n",
+    "\n",
+    "bbox = box(-150, 40, -120, 55)\n",
+    "plot_box(bbox)\n",
+    "\n",
+    "# Do not modify this line ##\n",
+    "start = time.perf_counter()#\n",
+    "############################\n",
+    "\n",
+    "# TODO: Call the time_series method for the AVHRR_OI_L4_GHRSST_NCEI 
dataset using \n",
+    "# your bounding box and time period 2013-01-01 through 2016-12-31\n",
+    "# Make sure you pass spark=True to the time_series function to speed up 
the analysis\n",
+    "\n",
+    "\n",
+    "# Enter your code above this line\n",
+    "print(\"Time Series took {} seconds to 
generate\".format(time.perf_counter() - start))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# TODO: Plot the result using the `show_plot` helper method\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Step 4: Run two Time Series' and plot them side-by-side\n",
+    "\n",
+    "\n",
+    "The `time_series` method can be used on up to two datasets at one time 
for comparison. Let's take a look at another region and see how to generate two 
time series and plot them side by side.\n",
+    "\n",
+    "> Hurricane Katrina passed to the southwest of Florida on Aug 27, 2005. 
The ocean response in a 1 x 1 degree region is captured by a number of 
satellites. The initial ocean response was an immediate cooling of the surface 
waters by 2 degrees Celcius that lingers for several days. The SST drop is 
correlated to both wind and precipitation\n",
+    "data.\n",
+    "\n",
+    "> _A study of a Hurricane Katrina–induced phytoplankton bloom using 
satellite observations and model simulations\n",
+    "Xiaoming Liu, Menghua Wang, and Wei Shi1\n",
+    "JOURNAL OF GEOPHYSICAL RESEARCH, VOL. 114, C03023, 
doi:10.1029/2008JC004934, 2009\n",
+    
"http://shoni2.princeton.edu/ftp/lyo/journals/Ocean/phybiogeochem/Liu-etal-KatrinaChlBloom-JGR2009.pdf
 _\n",
+    "\n",
+    "Plot the time series for the `AVHRR_OI_L4_GHRSST_NCEI` SST dataset and 
the `TRMM_3B42_daily` Precipitation dataset for the region `-84.5, 23.5, -83.5, 
24.5` and time frame of `2005-08-24` through `2005-09-10`. Plot the result 
using the `show_plot_two_series` helper method and see if you can recognize the 
correlation between the spike in precipitation and the decrease in 
temperature.\n",
+    "\n",
+    "## TODOs\n",
+    "1. Create a bounding box for the region in the Gulf of Mexico that 
Hurricane Katrina passed through (`-84.5, 23.5, -83.5, 24.5`)\n",
+    "2. Plot the bounding box using the helper method plot_box\n",
+    "3. Generate the Time Series by calling the `time_series` method in the 
`nexuscli` module\n",
+    "4. Plot the result using the `show_plot_two_series` helper method"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import time\n",
+    "import nexuscli\n",
+    "from datetime import datetime\n",
+    "\n",
+    "from shapely.geometry import box\n",
+    "\n",
+    "# TODO: Create a bounding box using the box method imported above\n",
+    "\n",
+    "\n",
+    "# TODO: Plot the bounding box using the helper method plot_box\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Do not modify this line ##\n",
+    "start = time.perf_counter()#\n",
+    "############################\n",
+    "\n",
+    "# TODO: Call the time_series method for the AVHRR_OI_L4_GHRSST_NCEI 
dataset and the `TRMM_3B42_daily` dataset\n",
+    "# using your bounding box and time period 2005-08-24 through 
2005-09-10\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "# Enter your code above this line\n",
+    "print(\"Time Series took {} seconds to 
generate\".format(time.perf_counter() - start))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# TODO: Plot the result using the `show_plot_two_series` helper method\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Step 5: Run a Daily Difference Average (Anomaly) calculation\n",
+    "\n",
+    "Let's return to The Blob region. But this time we're going to use a 
different calculation, Daily Difference Average (aka. Anomaly plot). \n",
+    "\n",
+    "The Daily Difference Average algorithm compares a dataset against a 
climatological mean and produces a time series of the difference from that 
mean. Given The Blob region, we should expect to see a positive difference from 
the mean temperature in that region (indicating higher temperatures than 
normal) between 2013 and 2014.\n",
+    "\n",
+    "This time, using the `nexuscli` module, call the 
`daily_difference_average` method. The signature for that method is reprinted 
below:\n",
+    "\n",
+    ">Generate an anomaly Time series for a given dataset, bounding box, and 
timeframe.  \n",
+    ">  \n",
+    "__dataset__ Name of the dataset as a String  \n",
+    "__bounding_box__ Bounding box for area of interest as a 
`shapely.geometry.polygon.Polygon`  \n",
+    "__start_datetime__ Start time as a `datetime.datetime`  \n",
+    "__end_datetime__ End time as a `datetime.datetime`  \n",
+    ">      \n",
+    ">__return__ List of `nexuscli.nexuscli.TimeSeries` namedtuples\n",
+    "\n",
+    "Generate an anomaly time series using the `AVHRR_OI_L4_GHRSST_NCEI` SST 
dataset for the time period 2013-01-01 through 2016-12-31 and a bounding box 
`-150, 40, -120, 55` (west, south, east, north).\n",
+    "\n",
+    "## TODOs\n",
+    "\n",
+    "1. Generate the Anomaly Time Series by calling the 
`daily_difference_average` method in the `nexuscli` module\n",
+    "2. Plot the result using the `show_plot` helper method\n",
+    "\n",
+    "## Advanced (Optional)\n",
+    "\n",
+    "1. Generate an Anomaly Time Series for the [El Niño 3.4 
region](https://www.ncdc.noaa.gov/teleconnections/enso/indicators/sst.php) 
(bounding box -170, -5, -120, 5) from 2010 to 2015."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import time\n",
+    "import nexuscli\n",
+    "from datetime import datetime\n",
+    "\n",
+    "from shapely.geometry import box\n",
+    "\n",
+    "bbox = box(-150, 40, -120, 55)\n",
+    "plot_box(bbox)\n",
+    "\n",
+    "# Do not modify this line ##\n",
+    "start = time.perf_counter()#\n",
+    "############################\n",
+    "\n",
+    "\n",
+    "# TODO: Call the daily_difference_average method for the 
AVHRR_OI_L4_GHRSST_NCEI dataset using \n",
+    "# your bounding box and time period 2013-01-01 through 2016-12-31. Be 
sure to pass spark=True as a parameter\n",
+    "# to speed up processing.\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "# Enter your code above this line\n",
+    "print(\"Daily Difference Average took {} seconds to 
generate\".format(time.perf_counter() - start))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# TODO: Plot the result using the `show_plot` helper method\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Congratulations!\n",
+    "\n",
+    "You have finished this workbook.\n",
+    "\n",
+    "If others are still working, please feel free to modify the examples and 
play with the client module or go back and complete the \"Advanced\" challenges 
if you skipped them. Further technical information about NEXUS can be found in 
the [GitHub repository](https://github.com/dataplumber/nexus).\n",
+    "\n",
+    "If you would like to save this notebook for reference later, click on 
`File -> Download as...` and choose your preferred format."
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "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.1"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}


Reply via email to