{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Basics of Python Programming\n", "-------------------------------------------------------------------\n", "\n", "Kushal Keshavamurthy Raviprakash\n", "\n", "kushalkr2992@gmail.com\n", "\n", "This notebook is a part of the [Python for Earth and Atmospheric Sciences](https://github.com/Kushalkr/Python_for_Earth_and_Atmospheric_Sciences) workshop." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Python and the Shell\n", "-------------------------------------------------------------------\n", "We are going to use the interactive python shell first to write simple commands.\n", "\n", "To do this:\n", "1. Open the terminal if you are using MacOSX/Linux or the Anaconda Propmt if you are using Windows.\n", "2. Type `python` and press `Enter`. You will see the python prompt `>>>` with some details about the version of python etc...\n", "3. Once you are running the interactive python shell, type `print(\"Hello World!\")` and press the `Enter` key.\n", "\n", "**NOTE** : Here I am using something called the IPython shell(**I**nteractive **P**ython shell). It works just the same as the python shell. Later on, we will move to IPython rather than the regular Python shell.\n", "\n", "Now you have succesfully run your first python program. Albeit an extremely simple one.\n", "\n", "The interactive python shell in its simplest form, can be used as a calculator. For example:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello World!\n" ] } ], "source": [ "print(\"Hello World!\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 + 1" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "7" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 + 5" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "11 - 1" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 * 5" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "8" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2**3" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2/2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Operators\n", "-------------------------------------------------------------------\n", "Here are some common operators in python:\n", "\n", "#### Mathematical operators:\n", "| Operation | Symbol | Symbol name |\n", "|:---------------|:----------:|----------------:|\n", "|Brackets | `( )` | Parantheses |\n", "|exponentiation | `**` | double-asterisk|\n", "|Multiplication | `*` | asterisk |\n", "|Modulo | `%` | Percent |\n", "|Floor Division | `//` | double-slash |\n", "|Float Division | `/` | slash |\n", "|Addition | `+` | plus |\n", "|Subtraction | `-` | minus or hyphen |\n", "\n", "\n", "\n", "#### Relational Operators:\n", "| Operation | Symbol |\n", "|:-----------------------|:----------:|\n", "|Greater than | `>` | \n", "|Lesser than | `<` | \n", "|Greater than or equal to| `>=` | \n", "|Lesser than or equal to | `<=` |\n", "|Equal to | `==` |\n", "|not Equal to | `!=` |\n", "|Object Identity | `is` |\n", "|Negated Object Identity | `is not` |\n", "\n", "#### Logical Operators:\n", "| Operation | Symbol |\n", "|:-----------------------|:--------:|\n", "|Logical AND | `and` | \n", "|Logical OR | `or` | \n", "|Logical NOT | `not` |\n", "\n", "The logical operators typically return a boolean value or type i.e `True` or `False`. In Python, `False`, numeric zero, `None`, empty objects are all treated as `False`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's print something" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello World!\n", "Hello Again\n", "I love printing!\n" ] } ], "source": [ "print('Hello World!')\n", "print('Hello Again')\n", "print('I love printing!')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "User input can be obtained using the `input` function." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Enter your name: Kushal\n", "Hello, Kushal\n", "\n" ] } ], "source": [ "name = input(\"Enter your name: \")\n", "print(\"Hello,\", name)\n", "print(type(name))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Writing Python Scripts\n", "-------------------------------------------------------------------\n", "To make our lives easier, we python multiple commands of python inside a file with an extension of `.py`. This file with the `.py` extension is called a python script.\n", "\n", "\n", "For the first few programs, I would like you to get used to using just a text editor and a terminal to write your programs and later move to an IDE(Integrated Development Environment) such as spyder (**S**cientific **PY**thon **D**evelopment **E**nvi**R**onment).\n", "\n", "I will be using the [Atom](https://atom.io) text editor to write my python scripts.\n", "\n", "[Atom](https://atom.io) is a cross-platform text-editor which is a very stable and supports python.\n", "\n", "You can download and install Atom by from [Atom.io](https://atom.io{:target=\"_blank\"}).\n", "\n", "**Note**: I will be using `jupyter-notebook` the entire duration of the workshop (I like to have my code and execution is the same place). My recommendation is to use `jupyter-notebook` unless you really need to use a text editor and a terminal because you can do everything with `jupyter-notebook` that can be done with a text editor and a terminal and in some cases, more.\n", "\n", "If you do decide to use a text editor and a terminal, the following steps are for you.\n", "\n", "Once you fire up the atom editor, it should look like this:\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 1\n", "-------------------------------------------------------------------\n", "1. Create a new file called `ex1.py` and put in all the commands you entered in the previous section on the interactive shell into it.\n", "\n", "2. In the terminal, go to the directory where the ex1.py file is saved and type `python ex1.py`.
Did you find anything fishy? What do you think happened?\n", "\n", "3. What would you do if I want you to get the output to print only certain lines in that file without deleting any of the lines in the file?\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Solution" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello World!\n", "Hello World!\n", "Hello Again\n", "I love printing!\n", "2\n", "7\n", "10\n", "10\n", "8\n", "1.0\n" ] } ], "source": [ "# %load scripts/basics_of_python/ex1.py\n", "# Remove the \"#\" from the above line and hit Ctrl/Cmd + Enter in jupyter-notebook\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Comments\n", "-------------------------------------------------------------------\n", "In the previous exercise, in order to print only certain lines of the code, we insert the octothorpe or hash or pound symbol (**#**) at the beginning of the line that you don't want to print. \n", "\n", "Try it out.\n", "\n", "-------------------------------------------------------------------" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Python code is usually stored in text files with the file ending \"`.py`\":\n", "\n", " myprogram.py\n", "\n", "* Every line in a Python program file is assumed to be a Python statement, or part thereof. \n", "\n", " * The only exception is comment lines, which start with the character `#` (optionally preceded by an arbitrary number of white-space characters, i.e., tabs or spaces). Comment lines are usually ignored by the Python interpreter.\n", "\n", "\n", "* To run our Python program from the command line we use:\n", "\n", " $ python myprogram.py\n", "\n", "* On UNIX systems it is common to define the path to the interpreter on the first line of the program (note that this is a comment line as far as the Python interpreter is concerned):\n", "\n", " #!/usr/bin/env python\n", "\n", " If we do, and if we additionally set the file script to be executable, we can run the program like this:\n", "\n", " $ myprogram.py\n", " \n", "**NOTE** : The material in this cell was obtained from [Lectures on Scientific Computing with Python](http://github.com/jrjohansson/scientific-python-lectures)\n", "\n", "Also, if your text encoding is different or if you are from another country, you may get errors about ASCII encodings. To take care of that, it is advised to insert\n", "\n", " # -*- coding: utf-8 -*-\n", " \n", "at the beginning of all your your `\".py\"` files." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Variables\n", "-------------------------------------------------------------------\n", "According to Wikipedia:\n", "> In computer programming, a variable or scalar is a storage location paired with an associated symbolic name (an identifier), which contains some known or unknown quantity of information referred to as a value. \n", "\n", "All it means is that a variable is a location in memory which has a value associated with it and you can access this location by the specific name provided to that location called the *variable name*.\n", "\n", "Creating and using variables of different types are shown below:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Datatypes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Integers\n", "-------------------------------------------------------------------" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 2\n", "type(a)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = 3\n", "type(b)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = a + b\n", "type(c)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5\n" ] } ], "source": [ "print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Float\n", "-------------------------------------------------------------------\n", "\n", "Floats are short for floating point numbers. This means that real numbers such as 3.141592654, 0.1, 73.0000005 etc... are floating point numbers.\n", "\n", "**NOTE** : Floats, just like integers don't have infinite precision i.e the computer can only store values with finite (still enormously large) precision." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "float" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 3.\n", "type(a)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "float" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = 7.0\n", "type(b)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "float" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = a + b\n", "type(c)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10.0\n" ] } ], "source": [ "print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Boolean\n", "-------------------------------------------------------------------\n", "Boolean variables are variables that can have only one of two values: `True` or `False`.\n", "\n", "Boolean variables are used extensively with conditional statements, relational operators and logical operators.\n", "\n", "Let's try out a few." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "a = 10;b = 5\n", "print(a>b)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(a > 10) and (b > 1)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(a > 10) or (b > 1)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "not(a > 10) and (b > 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Moving the parantheses around could get you different results with the same expression.\n", "\n", "__Tip__: Make (correct) use of parantheses in long expression for better code readability." ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "not(a) > (10 and (b > 1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Strings\n", "-------------------------------------------------------------------\n", "\n", "Strings are a sequence of characters where each character is of the type \"string\". In other words, individual characters are strings of length 1.\n", "\n", "**NOTE** :\n", "* You can have strings of length 0 also called \"empty strings\".\n", "* Strings are immutable (I will discuss this is detail in the following sections)." ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "str" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = \"Hello\"\n", "type(a)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "b = \" World\"\n", "print(type(b))" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "str" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = a + b\n", "type(c)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello World\n" ] } ], "source": [ "print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some operations are not possible and Python throws an error. Let us try one such operation." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "unsupported operand type(s) for +: 'int' and 'str'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'2'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mprint\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'int' and 'str'" ] } ], "source": [ "a = 5\n", "b = '2'\n", "c = a + b\n", "print (c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But some might be allowed and it can be confusing." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'22222'" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a * b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you noticed, I used the same variable names and the same addition operation but Python still did something different for each kind of input. This is called [operator overloading](https://en.wikibooks.org/wiki/C%2B%2B_Programming/Operators/Operator_Overloading) (It is a concept from object-oriented programming which I will touch upon later).\n", "\n", "Python uses [duck typing](https://en.wikipedia.org/wiki/Duck_typing). It is basically a test for whether an operator is possible on a a certain type of variable." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Objects and Methods\n", "-------------------------------------------------------------------\n", "\n", "Everything in python is what we call an object. Variables, data types, classes, functions, are all objects.\n", "\n", "In python, you can access an object's methods or attributes using the dot (.) notation.\n", "\n", "An object's attributes are variables or information about an object that is particular to that object. Similarly, methods are default functions that can be used only with that object.\n", "\n", "For now, our objects will just be variables.\n", "\n", "Let us try some things." ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello\n", "WORLD\n" ] } ], "source": [ "a = \"hello\"\n", "b = \"world\"\n", "print(a.capitalize())\n", "print(b.upper())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here, the variables `a` and `b` are both strings. In Python, string objects have built-in methods such as:\n", "* upper() - returns the string with all characters in uppercase.\n", "* lower() - returns the string with all characters in lowercase.\n", "* capitalize() - capitalizes every first letter of every word of the string.\n", "* count() - returns the number of times something is repeated in the string.\n", "\n", "To get to know the available methods for an objects, in the interactive shell, type `dir(object)` where `object` is the name of your object or variable." ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['__add__',\n", " '__class__',\n", " '__contains__',\n", " '__delattr__',\n", " '__dir__',\n", " '__doc__',\n", " '__eq__',\n", " '__format__',\n", " '__ge__',\n", " '__getattribute__',\n", " '__getitem__',\n", " '__getnewargs__',\n", " '__gt__',\n", " '__hash__',\n", " '__init__',\n", " '__init_subclass__',\n", " '__iter__',\n", " '__le__',\n", " '__len__',\n", " '__lt__',\n", " '__mod__',\n", " '__mul__',\n", " '__ne__',\n", " '__new__',\n", " '__reduce__',\n", " '__reduce_ex__',\n", " '__repr__',\n", " '__rmod__',\n", " '__rmul__',\n", " '__setattr__',\n", " '__sizeof__',\n", " '__str__',\n", " '__subclasshook__',\n", " 'capitalize',\n", " 'casefold',\n", " 'center',\n", " 'count',\n", " 'encode',\n", " 'endswith',\n", " 'expandtabs',\n", " 'find',\n", " 'format',\n", " 'format_map',\n", " 'index',\n", " 'isalnum',\n", " 'isalpha',\n", " 'isdecimal',\n", " 'isdigit',\n", " 'isidentifier',\n", " 'islower',\n", " 'isnumeric',\n", " 'isprintable',\n", " 'isspace',\n", " 'istitle',\n", " 'isupper',\n", " 'join',\n", " 'ljust',\n", " 'lower',\n", " 'lstrip',\n", " 'maketrans',\n", " 'partition',\n", " 'replace',\n", " 'rfind',\n", " 'rindex',\n", " 'rjust',\n", " 'rpartition',\n", " 'rsplit',\n", " 'rstrip',\n", " 'split',\n", " 'splitlines',\n", " 'startswith',\n", " 'strip',\n", " 'swapcase',\n", " 'title',\n", " 'translate',\n", " 'upper',\n", " 'zfill']" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(a)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "String variables can be combined with other types. For example: " ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I am 25 years old\n" ] } ], "source": [ "a = \"I am \"\n", "b = 25\n", "c = \" years old\"\n", "# we can use a number inside strings by forcing it to be a string, like so\n", "print(a + str(b) + c) # the forcing of one data type to another data type is called type casting\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also format your output in a preferred format." ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I am 25 years old\n", "I am 25 years old\n" ] } ], "source": [ "age = 25\n", "print(\"I am %s years old\" % (str(age))) # Old format\n", "# OR\n", "print(\"I am {} years old\".format(age)) # New format" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For more information on formatting your output, refer [pyformat.info](https://pyformat.info/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's try one of the methods of strings" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = \"hello\"\n", "a.count('l')" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5\n", "5\n" ] } ], "source": [ "print(len(a)) # Returns the length of the string a\n", "print(len(\"hello\")) # this is the same thing as above" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As defined earlier, a string is a sequence of characters. Since it is a sequence, python allows us to access each element of the string. The method by which we can access individual elements of a string is called *__indexing__*.\n", "\n", "Indexing basically means that each character is given an index (number) according to its position in the string. For example, in the string \"Python\", the letter P has index 0, the letter y has index 1 and so on.\n", "\n", "Accessing a value at a particular index is done by *string*[*__index__*] where *string* is your string or the name of the variable contatining the string and index is the position of the character you require.\n", "\n", "**NOTE** : Indexing starts at 0 in Python instead of 1." ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": true }, "outputs": [], "source": [ "lang = \"Python\"" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'P'" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lang[0]" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'y'" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lang[1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here's something awesome:" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'n'" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lang[-1]" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'o'" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lang[-2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Mutability\n", "-------------------------------------------------------------------\n", "\n", "Before we move on, I would like to introduce the concept of mutability.\n", "\n", "Mutability means \"the ability to change\".\n", "\n", "In python, there are few datatypes that can be changed and few that cannot. The data types which can be changed are called *mutable* and the datatypes which cannot be changed are called *immutable*.\n", "\n", "In python, lists and dictionaries (both of which you will see later) are *mutable* datatypes. Whereas numbers, strings and tuples(also covered subsequently) are *immutable* datatypes." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Examples:" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'str' object does not support item assignment", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mlang\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"C\"\u001b[0m \u001b[0;31m# I cannot change Python to Cython\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'str' object does not support item assignment" ] } ], "source": [ "lang[0] = \"C\" # I cannot change Python to Cython" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But, one workaround is:" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Cython'" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lang =\"Cython\" # Reassigning the string\n", "lang" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another workaround is:" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Python'" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lang.replace(\"C\",\"P\") # Using the replace() method." ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Cython'" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Here's another method\n", "lang = \"C\" + \"ython\"\n", "lang" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**NOTE** : We will introduce **slicing** in the next few sections and the same rules for slicing of lists can be applied to strings since each character is a string by itself." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Lists\n", "-------------------------------------------------------------------\n", "Till now we've looked at some simple datatypes such as integers, floating point numbers, booleans and strings. It becomes inconvenient when you have lots of variables. Python has a separate datatype called a list which is basically a sequence of values (could be integers, strings etc..)\n", "\n", "**NOTE** : \n", "* Lists are mutable.\n", "* Lists can contain multiple types of data." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can create a list by putting values separated by commas (`,`) enclosed with square brackets (`[]`). a generic list would look like this:\n", " \n", " [value1, value2, value3,....]\n", " \n", "Let's create some lists." ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 'Panda', 3.14, True] \n" ] } ], "source": [ "lst = [1, \"Panda\", 3.14, True]\n", "print(lst, type(lst))" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[1, 'Panda', 3.14, True], [1, 'hey']]" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# We can have lists within lists\n", "m = [lst, [1,\"hey\"]]\n", "m" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Hello', 'Everyone', 1, 'Panda', 3.14, True]" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Lists can also be created like this\n", "n = list([\"Hello\", \"Everyone\"] + lst)\n", "n" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": true }, "outputs": [], "source": [ "n = list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Accessing values within lists is by indexing." ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "[1, 'Panda', 3.14, True]" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For accessing values inside lists which are themselves inside lists," ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.14" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m[0][2] # Accesses 3rd value of the 1st list inside m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Slicing\n", "-------------------------------------------------------------------\n", "\n", "Multiple values inside a list can be accessed thorugh slicing.\n", "\n", "Slicing generally follows the form [ *start* : *end-1* : *skip* ]" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Panda', 3.14, True]" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lst[1:4]" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "[1, 'Panda', 3.14]" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lst[:-1] # Returns elements from first through last but but one element" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[3.14, True]" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lst[2:] # Returns elements from 3rd through last elements" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 'Panda', 3.14, True]" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lst[:] # return all elements" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 3.14]" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lst[:-1:2] # Returns every 2nd element" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's list the attributes and methods of the list `lst`." ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['__add__',\n", " '__class__',\n", " '__contains__',\n", " '__delattr__',\n", " '__delitem__',\n", " '__dir__',\n", " '__doc__',\n", " '__eq__',\n", " '__format__',\n", " '__ge__',\n", " '__getattribute__',\n", " '__getitem__',\n", " '__gt__',\n", " '__hash__',\n", " '__iadd__',\n", " '__imul__',\n", " '__init__',\n", " '__init_subclass__',\n", " '__iter__',\n", " '__le__',\n", " '__len__',\n", " '__lt__',\n", " '__mul__',\n", " '__ne__',\n", " '__new__',\n", " '__reduce__',\n", " '__reduce_ex__',\n", " '__repr__',\n", " '__reversed__',\n", " '__rmul__',\n", " '__setattr__',\n", " '__setitem__',\n", " '__sizeof__',\n", " '__str__',\n", " '__subclasshook__',\n", " 'append',\n", " 'clear',\n", " 'copy',\n", " 'count',\n", " 'extend',\n", " 'index',\n", " 'insert',\n", " 'pop',\n", " 'remove',\n", " 'reverse',\n", " 'sort']" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(lst)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let me add some elements to the list `lst`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here's one way of doing that:" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 'Panda', 3.14, True, 'Valar', 'Morghulis']" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lst.append(\"Valar\")\n", "lst.append(\"Morghulis\")\n", "lst" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here's another way of adding items to lists:" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 'Panda', 3.14, True, 'Valar', 'Morghulis', 'Valar', 'Dohaeris']" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lst + [\"Valar\",\"Dohaeris\"] # You can add multiple items this way\n", "# In this method, you will also need to assign it back to the original \n", "# list if you want to retain the additions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is yet another way of adding multiple items to the list." ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 'Panda', 3.14, True, 'Valar', 'Morghulis', 'Valar', 'Dohaeris']" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lst.extend((\"Valar\", \"Dohaeris\")) # The extend() method only takes in an iterable as argument\n", "lst" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 2\n", "-------------------------------------------------------------------\n", "In a file called ex2.py, create a list having the strings `\"Luke\", \"Leia\"` and `\"Obiwan\"`. Create another list with contents `\"Yoda\", \"Vader\"` and `\"Death Star\"`. Create a third list with contents `\"Storm Trooper\"` and `\"R2D2\"`.\n", "* \n", " 1. Combine all 3 lists into a single list.\n", " 2. Remove all the elements belonging to the Empire i.e \"Vader\", \"Death Star\" and \"Storm Trooper\".\n", "\n", "**HINT** : Look up the `remove()` method of lists or the `pop()` method or the built-in `del` command in Python. I recommend you create the list and perform the removal of elements using all 3 possibilities.\n", "\n", "* Create a variable called `address` with your address as a list i. e.\n", " 1. Put all tokens (each word/number) as indiviadual elements in lists.\n", " 2. Write code to calculate the sum of the numerical parts.\n", " 3. What should I do if I want to change one of the elements in the list? (say change it from 'East' to 'North'?) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Solution" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Method 1: Using del\n", "Before: ['Luke', 'Leia', 'Obiwan', 'Yoda', 'Vader', 'Death Star', 'Storm Trooper', 'R2D2']\n", "After: ['Luke', 'Leia', 'Obiwan', 'Yoda', 'R2D2'] \n", "\n", "Method 2: Using remove()\n", "Before: ['Luke', 'Leia', 'Obiwan', 'Yoda', 'Vader', 'Death Star', 'Storm Trooper', 'R2D2']\n", "After: ['Luke', 'Leia', 'Obiwan', 'Yoda', 'R2D2'] \n", "\n", "Method 3: Using pop()\n", "Before: ['Luke', 'Leia', 'Obiwan', 'Yoda', 'Vader', 'Death Star', 'Storm Trooper', 'R2D2']\n", "After: ['Luke', 'Leia', 'Obiwan', 'Yoda', 'R2D2'] \n", "\n", "48409\n", "[1001, 'North', '10th', 'street', 'GY428', 'Bloomington', 'IN', 47408]\n" ] } ], "source": [ "# %load scripts/ex2.py\n", "#!/usr/bin/env python3\n", "\n", "\"\"\"\n", "@author: Kushal Keshavamurthy Raviprakash\n", "\"\"\"\n", "\n", "a = [\"Luke\", \"Leia\", \"Obiwan\"]\n", "b = [\"Yoda\", \"Vader\", \"Death Star\"]\n", "c = [\"Storm Trooper\", \"R2D2\"]\n", "\n", "# Solution:\n", "\n", "d = a + b + c # concatenating the list items.\n", "\n", "# Method 1: using del\n", "print(\"Method 1: Using del\")\n", "print(\"Before: \", d)\n", "del d[4], d[4], d[4]\n", "# Err what?! yeah that's right. because 4 is the index \"Vader\"\n", "# in the list d. but when you delete \"Vader\", \"Death Star\"\n", "# occupies index 4 and same happens to \"Storm Trooper\".\n", "print(\"After: \",d,\"\\n\")\n", "\n", "# Method 2: Using the remove(method)\n", "d = a + b + c # Resetting list d\n", "print(\"Method 2: Using remove()\")\n", "print(\"Before: \", d)\n", "d.remove('Vader')\n", "d.remove('Death Star')\n", "d.remove('Storm Trooper')\n", "print(\"After: \",d,\"\\n\")\n", "\n", "# Method 3: Using the pop() method\n", "d = a + b + c # Resetting list d\n", "print(\"Method 3: Using pop()\")\n", "print(\"Before: \", d)\n", "d.pop(4)\n", "d.pop(4)\n", "d.pop(4)\n", "print(\"After: \",d,\"\\n\")\n", "\n", "# Part two of the exercise\n", "\n", "address = [1001, \"East\", \"10th\", \"street\", \"GY428\", \"Bloomington\", \"IN\", 47408]\n", "\n", "print(address[0] + address[-1])\n", "address[1] = \"North\"\n", "print(address)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tuples\n", "-------------------------------------------------------------------\n", "tuples are exactly like lists except they are [immutable](#Mutability).\n", "\n", "Here are some tuples and some methods." ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2, 'flash', [3.14, ('a', 'b')])" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = (2,'flash', [3.14, (\"a\",\"b\")])\n", "a" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[0]" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'flash'" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[1]" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[3.14, ('a', 'b')]" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[2]" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.14" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[2][0]" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('a', 'b')" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[2][1]" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'a'" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[2][1][0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's try modifying the tuple" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'tuple' object does not support item assignment", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" ] } ], "source": [ "a[0] = 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "you get a type error because tuples are immutable. However, like strings, you can create new tuples with the existing values along with the additions or deletions. For example:" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(2, 'flash', [3.14, ('a', 'b')])\n", "(3, 'flash', [3.14, ('a', 'b')])\n" ] } ], "source": [ "print(a)\n", "a = (3,) + a[1:]\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dictionaries\n", "-------------------------------------------------------------------\n", "\n", "Dictionaries are collections of elements just like lists and tuples. The difference is that dictionaries are not ordered and are not referenced by position (index) but by *keys*.\n", "\n", "The *keys* are generally strings or integers. and the values, like lists and tuples, can be anything.\n", "\n", "**NOTE** : Dictionaries are very important because most of the times, as we'll see later, Atmospheric Science/ Earth Science data in NetCDF format are stored in dictionaries." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dictionaries are delimited by \"`{}`\" just like lists are delimited by \"`[]`\" and tuples by \"`()`\"" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'address': {'Pin': 47408,\n", " 'city': 'Bloomington',\n", " 'state': 'IN',\n", " 'street': '1001, E10th street, GY428'},\n", " 'age': 25,\n", " 'name': 'Kushal'}" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "info = {'name': \"Kushal\", 'age': 25, 'address': {'street': \"1001, E10th street, GY428\", 'city': \"Bloomington\", 'state': \"IN\", 'Pin': 47408}}\n", "info" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dictionaries are accessed by *keys*. " ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Kushal\n", "25\n" ] } ], "source": [ "print(info['name'])\n", "print(info['age'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "this is much more intuitive than using `info[0]` and `info[1]`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Collections within dictionaries are referenced by indices if the collections are list/tuples and keys if the collections are dictionaries." ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "47408" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "info['address']['Pin']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dictionaries are [mutable](#Mutability)." ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'address': {'Pin': 47408,\n", " 'city': 'Bloomington',\n", " 'state': 'IN',\n", " 'street': '1001, E10th street, GY428'},\n", " 'age': 24,\n", " 'name': 'Kushal'}" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "info['age'] = 24\n", "info" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have built-in methods for dictionaries as well." ] }, { "cell_type": "code", "execution_count": 75, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "dict_keys(['name', 'age', 'address'])" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "info.keys()" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dict_values(['Kushal', 24, {'street': '1001, E10th street, GY428', 'city': 'Bloomington', 'state': 'IN', 'Pin': 47408}])" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "info.values()" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dict_items([('name', 'Kushal'), ('age', 24), ('address', {'street': '1001, E10th street, GY428', 'city': 'Bloomington', 'state': 'IN', 'Pin': 47408})])" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "info.items()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 3\n", "-------------------------------------------------------------------\n", "In a file called ex3.py, create a variable of the dictionary type called `myaddress` having the strings `\"street\", \"city\", \"state\"` and `\"PIN\"` as keys and whatever you want for the values for each key .\n", "* \n", " 1. Combine all the fields into a single string variable called `fulladdress`.\n", " 2. print all the keys in the dictionary onto the screen.\n", " 3. replace the PIN in the dictionary with a Pin/zip code of your choice.\n", " \n", "**NOTE** : Values must be strings for this exercise only, but can be anything in general." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Solution" ] }, { "cell_type": "code", "execution_count": 78, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'street': '1001 E10th Street, GY428', 'city': 'Bloomington', 'state': 'IN', 'PIN': '47408'}\n", "1001 E10th Street, GY428BloomingtonIN47408\n", "dict_keys(['street', 'city', 'state', 'PIN'])\n" ] } ], "source": [ "# %load scripts/basics_of_python/ex3.py\n", "#!/usr/bin/env python3\n", "\n", "\"\"\"\n", "@author: Kushal Keshavamurthy Raviprakash\n", "\"\"\"\n", "\n", "myaddress = {'street':\"1001 E10th Street, GY428\", 'city':\"Bloomington\",\n", " 'state':\"IN\", 'PIN':\"47408\"}\n", "print(myaddress)\n", "\n", "fulladdress = myaddress['street'] + \\\n", "myaddress['city'] + \\\n", "myaddress['state'] + myaddress['PIN']\n", "\n", "print(fulladdress)\n", "\n", "print(myaddress.keys())\n", "myaddress['PIN'] = \"47405\"\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Control Structures\n", "-------------------------------------------------------------------" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Branching\n", "-------------------------------------------------------------------\n", "\n", "We learnt how to perform some actions using operators and some datatypes in the previous sections but, sometimes we come across the need for performing some action if a condition is met and a different action if some other condition is met. This is possible by what is called *__Branching__*.\n", "\n", "In Python, branching is performed by using the `if-elif-else` construct.\n", "\n", "### Indentation :\n", "Indentation (tabs or spaces) in Python is what tells you where a particular *block* of code (body of code viz. if-statement, function, loop, etc...) is starting or ending. If your code is not indented properly, you might encounter a lot of errors.\n", "\n", "the basic construct is as follows:\n", "```python\n", "if (conditional statements):\n", " commands\n", "elif (conditional statements):\n", " commands\n", "else:\n", " commands\n", "```\n", "\n", "**NOTE** : The indentation is generally 4 spaces. (Personally, I use 2 spaces).\n", "\n", "Let us try out some if-statements:" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a is greater\n" ] } ], "source": [ "a = 7 ; b = 3\n", "if (a > b):\n", " print('a is greater')\n", "else:\n", " print('b is greater')" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "c is the largest.\n" ] } ], "source": [ "a = 7 ; b = 3; c = 10\n", "if ((a > b) and (a > c)):\n", " print('a is the largest')\n", "elif ((b > a) and (b > c)):\n", " print('b is the largest.')\n", "else:\n", " print('c is the largest.')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "you can use `if-statements` inside `if-statements`." ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "c is the largest.\n" ] } ], "source": [ "a = 7 ; b = 3; c = 10\n", "if (a >= b):\n", " if (a >= c):\n", " print('a is the largest')\n", " else:\n", " print('c is the largest.')\n", "elif (b >= c):\n", " print('b is the largest.')\n", "else:\n", " print('b is the largest.')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Iteration\n", "-------------------------------------------------------------------\n", "\n", "Iterating means to repeat something and computers are really good at doing it efficiently. In Python, the iteration control structures are called loops. We will discuss few loops in this section." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### While loop\n", "\n", "the `while` loop, in Python, has the syntax:\n", "```python\n", " while (conditional):\n", " commands\n", " increment\n", "```" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n" ] } ], "source": [ "i = 0\n", "while(i<10):\n", " print(i)\n", " i = i + 1 # This can also be written as i+=1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### For loop\n", "\n", "the `for` loop is used for looping a particular number of times or through iterables such as `lists, tuples, dictionaries` and a particular iterable called `range` which generates a sequence of numbers. The `for` loop has the following syntax:\n", "\n", "```python\n", " for variable in iterable:\n", " commands\n", "```\n", "Let's do a few examples:" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n" ] } ], "source": [ "for i in range(10):\n", " print(i)" ] }, { "cell_type": "code", "execution_count": 84, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Bloomington\n", "Boston\n", "San Francisco\n", "Maryland\n", "Boulder\n", "Seattle\n" ] } ], "source": [ "cities = ['Bloomington', 'Boston', 'San Francisco', 'Maryland', 'Boulder', 'Seattle']\n", "for city in cities:\n", " print(city)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`for` loops can be used with dictionaries in conjunction with a function called `zip`." ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "lion : carnivore\n", "zebra : herbivore\n", "cheetah : carnivore\n", "giraffe : herbivore\n" ] } ], "source": [ "animals = {'lion': \"carnivore\", 'zebra': \"herbivore\", 'cheetah': \"carnivore\", 'giraffe': \"herbivore\"}\n", "for animal, foodtype in zip(animals.keys(), animals.values()):\n", " print('{0:s} : {1:s}'.format(animal, foodtype))" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "lion : carnivore\n", "zebra : herbivore\n", "cheetah : carnivore\n", "giraffe : herbivore\n" ] } ], "source": [ "for animal, foodtype in animals.items():\n", " print('{0:s} : {1:s}'.format(animal, foodtype))" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "lion carnivore\n", "zebra herbivore\n", "cheetah carnivore\n", "giraffe herbivore\n" ] } ], "source": [ "for key in animals:\n", " print(key, animals[key])" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "H\n", "e\n", "l\n", "l\n", "o\n" ] } ], "source": [ "a = \"Hello\"\n", "for i in a:\n", " print(i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have seen different ways of accessing collections. Let's move on to writing functions of our own." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Functions\n", "-------------------------------------------------------------------\n", "Most of the times you will need to reuse some code and it is not worth the time to repeat the entire code everytime it is required. So, we put our code into *functions* that can be called every time we need to use that particular code.\n", "\n", "the syntax for functions in Python is as follows:\n", "```python\n", " def function_name (parameters):\n", " commands\n", " return values\n", "```\n", "\n", "Let's write a couple of functions of our own:" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "12.56" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def area(r):\n", " return 3.14 * r**2\n", "\n", "area(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can have multiple function definitions in one file." ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The area of the triangle is: 16.0\n", "The area of the rectangle is: 32\n" ] } ], "source": [ "def area_triangle(base, height):\n", " area = 0.5 * base * height\n", " return area\n", "\n", "def area_rectangle(width, height):\n", " area = width * height\n", " return area\n", "\n", "print(\"The area of the triangle is: \", area_triangle(4, 8))\n", "print(\"The area of the rectangle is: \", area_rectangle(4,8))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 4\n", "-------------------------------------------------------------------\n", "\n", "Write functions for the conversion of temperature from Fahrenheit to Celsius and vice versa. The relationships are as follows:\n", "$$\n", "\\begin{align*}\n", "C &= \\frac{5}{9}\\left(F - 32\\right) \\\\\n", " F &= \\left(\\frac{9}{5}C\\right) + 32 \n", "\\end{align*}\n", "$$\n", "\n", "You need two functions called `f2c` and `c2f`. Put both the functions in a file called `ex4.py`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Solution" ] }, { "cell_type": "code", "execution_count": 91, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f2c(f):\n", " return ((5/9.) * (f - 32))\n", "\n", "def c2f(c):\n", " return ((9/5.)*c + 32)" ] }, { "cell_type": "code", "execution_count": 92, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "22.22222222222222\n", "80.6\n" ] } ], "source": [ "print(f2c(72))\n", "print(c2f(27))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Modules\n", "-------------------------------------------------------------------\n", "\n", "We now know how to define functions that can be defined and reused in a file. But, what if you want to use the functions you defined in a file in another program?\n", "\n", "Python allows you to make use of pre-written functions and some other things through what are known as modules. Modules are basically definitions of functions and few other things put into a file. They can be \"**imported**\" wherever needed.\n", "\n", "The name of the module is the name of the file with the functions you have saved without the `.py` suffix\n", "\n", "Similarly, a collection of modules is called a package. Eg. Numpy, Scipy, matplotlib etc..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's turn the exercise 4 solution into a module.\n", "\n", "Since our file name here is ex4.py, our module will be called ex4.\n", "\n", "You can directly import a file as module if you have the file in the same directory as the code you are running. If otherwise, you will have to append the path as shown below." ] }, { "cell_type": "code", "execution_count": 96, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import sys\n", "sys.path.append('scripts/basics_of_python/') #My file is inside the directory scripts/" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above commands are telling python to look inside the `basics_of_python/` directory inside my `scripts/` directory. The reason being, python does not look inside that folder by default." ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "89.6" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import ex4\n", "\n", "ex4.c2f(32)" ] }, { "cell_type": "code", "execution_count": 100, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "12.222222222222223" ] }, "execution_count": 100, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ex4.f2c(54)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are lots of modules already available for use with python. We will also look at some of them (Numpy, Scipy, matplotlib, etc...)\n", "\n", "Before that, here's a sample to show the different ways of importing modules:" ] }, { "cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[b'-r--r--r-- 1 ftp ftp 830 Mar 13 1997 README',\n", " b'drwxrwxr-x 17 ftp ftp 4096 Aug 30 2016 pub',\n", " b'-rw-r--r-- 1 ftp ftp 26 Oct 03 2013 robots.txt']" ] }, "execution_count": 107, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import urllib\n", "file_list = urllib.request.urlopen('ftp://ftp.unidata.ucar.edu/')\n", "html = file_list.read()\n", "html.splitlines()" ] }, { "cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[b'-r--r--r-- 1 ftp ftp 830 Mar 13 1997 README',\n", " b'drwxrwxr-x 17 ftp ftp 4096 Aug 30 2016 pub',\n", " b'-rw-r--r-- 1 ftp ftp 26 Oct 03 2013 robots.txt']" ] }, "execution_count": 108, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from urllib import *\n", "file_list = request.urlopen('ftp://ftp.unidata.ucar.edu/')\n", "html = file_list.read()\n", "html.splitlines()" ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[b'-r--r--r-- 1 ftp ftp 830 Mar 13 1997 README',\n", " b'drwxrwxr-x 17 ftp ftp 4096 Aug 30 2016 pub',\n", " b'-rw-r--r-- 1 ftp ftp 26 Oct 03 2013 robots.txt']" ] }, "execution_count": 109, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from urllib.request import urlopen\n", "file_list = urlopen('ftp://ftp.unidata.ucar.edu/')\n", "html = file_list.read()\n", "html.splitlines()" ] }, { "cell_type": "code", "execution_count": 110, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[b'-r--r--r-- 1 ftp ftp 830 Mar 13 1997 README',\n", " b'drwxrwxr-x 17 ftp ftp 4096 Aug 30 2016 pub',\n", " b'-rw-r--r-- 1 ftp ftp 26 Oct 03 2013 robots.txt']" ] }, "execution_count": 110, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import urllib as ul\n", "file_list = ul.request.urlopen('ftp://ftp.unidata.ucar.edu/')\n", "html = file_list.read()\n", "html.splitlines()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A (very) Brief Introduction to Object-oriented Programming (OOP)\n", "-------------------------------------------------------------------\n", "\n", "Until now, almost every concept we have looked at, pertains to **procedural programming**.\n", "* Procedural programming is a programming paradigm wherein, some kind of data is provided to a procedure (function) and the procedure performs some kind of operation on the data and returns some data.\n", "* In this paradigm, data and functions are two separate entities." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Object-oriented programming on the other hand, is a different kind of programming philosophy wherein an object has both data and functions attached to it. The data are called **attributes** and the functions are called **methods**.\n", "\n", "In the real world, everything is a replica of a type or class. For example, individual people, though they possess different characteristics, are of the **type** or **class** humans beings since all humans are made up of DNA, have cells in their body, have a brain etc... and each individual is said to be an **instance** of the human **class**." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Syntax for objects:\n", "\n", "* The syntax for referring to an object's attribute is to put a dot `(.)` after the object name followed by the name of the attribute. Example: `a.year`\n", "\n", "* Similarly, the syntax to refer to an object's method is to again use the the dot `(.)` after the object name and within parantheses `()`, the arguments to the method if any. Example: `a.run()`" ] }, { "cell_type": "code", "execution_count": 121, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'HELLO'" ] }, "execution_count": 121, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = \"hello\"\n", "a.upper()" ] }, { "cell_type": "code", "execution_count": 122, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Hello'" ] }, "execution_count": 122, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.capitalize()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Defining your own class\n", "-------------------------------------------------------------------\n", "\n", "Classes are blueprints for creating objects by defining initial attributes and methods that will be attached to the instances. For example, the class `string` contains the definition of the `isupper()` method which we can see in the string \"Hello\" as well as the string \"everyone\".\n", "\n", "Here are some rules for creating your own classes:\n", "\n", "* The definition of a new class begins with the keyword `class`.\n", "* All classes **should** have an `__init__` method. The reason is, the `__init__` method is called whenever a new object of the class is created and all your initializations go into this method.\n", "* The `__init__` method can take in arguments that are then used to define attributes while initializing the object.\n", "* Methods are defined similar to functions, using the `def` keyword.\n", "* The instance(copy) of the class is called **`self`** within the class definition.\n", "\n", "All this theory is a lot to digest!\n", "\n", "Let's try some examples:" ] }, { "cell_type": "code", "execution_count": 138, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Person(object):\n", " \n", " def __init__(self, name):\n", " self.name = name\n", " \n", " def talk(self):\n", " if self.name.capitalize() == \"Batman\":\n", " print(\"I'm Batman!\")\n", " else:\n", " print(\"Hello! My name is {0:s}\".format(self.name))\n", " print(\"I am your friend.\")" ] }, { "cell_type": "code", "execution_count": 141, "metadata": { "collapsed": true }, "outputs": [], "source": [ "person1 = Person(\"Peter\")\n", "person2 = Person(\"Batman\")" ] }, { "cell_type": "code", "execution_count": 142, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello! My name is Peter\n", "I am your friend.\n" ] } ], "source": [ "person1.talk()" ] }, { "cell_type": "code", "execution_count": 143, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I'm Batman!\n" ] } ], "source": [ "person2.talk()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above class is a really basic example of a class. There are so many concepts such as **inheritance**, **polymorphism** etc..., that I haven't discussed in here.\n", "I want to keep it simple for the beginners. Once you are familiar with some python, there are lots of resources to learn the advanced concepts." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## File Input/Output (I/O)\n", "-------------------------------------------------------------------\n", "\n", "In the field of Earht and Atmospheric Sciences, more often than not, we need to read in data from a file and then perform some operation on the data and then write out the results to a file.\n", "\n", "We will look at input/output with text files.\n", "\n", "Python intefaces with files of any kind through **file objects**.\n", "\n", "File objects are instantiated (created) using the built-in **`open`** statement." ] }, { "cell_type": "code", "execution_count": 149, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Thundercats pok pok\n", "aesthetic pug cred\n", "brunch bespoke normcore\n", "tousled venmo kombucha\n", "Poutine hashtag cray\n", "biodiesel hot chicken\n", "vice helvetica, retro post-ironic\n", "everyday carry pop-up\n", "tbh pok pok. \n", "\n", "\n" ] } ], "source": [ "fname = open('data/foo.txt', 'r')\n", "data = fname.read()\n", "fname.close()\n", "print(data)\n", "print(type(data))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The **`open`** statement has different modes in which it interacts with files:\n", "* `'r'` - read mode (cannot write or modify the file)\n", "* `'w'` - write mode (can write to file)\n", "* `'r+'` - read and write mode. File pointer is at the beginning of the file\n", "* `'w+'` - write and read mode. Overwrites if file exists or new file is created if it doesn't.\n", "* `'a'` - append mode. File pointer is at the end of the file if file exists or new file is created if it doesn't\n", "\n", "There are other modes of file access, but these are the most common ones that we are likely to use." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**NOTE** : It is very important that you use the `close()` method and close the file after you are done using the data. There are chances that the file can be tampered with, if it is not closed properly." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's try some methods with the file object and put them into a list." ] }, { "cell_type": "code", "execution_count": 156, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Thundercats pok pok\n", "\n", "['aesthetic pug cred\\n', 'brunch bespoke normcore\\n', 'tousled venmo kombucha\\n', 'Poutine hashtag cray\\n', 'biodiesel hot chicken\\n', 'vice helvetica, retro post-ironic\\n', 'everyday carry pop-up\\n', 'tbh pok pok. \\n']\n", "\n" ] } ], "source": [ "fname = open('data/foo.txt', 'r')\n", "data = fname.readline()\n", "print(data)\n", "data = fname.readlines()\n", "print(data)\n", "print(type(data))\n", "fname.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "the `readline()` method produces a string whereas the `readlines()` method produces a list of strings with each line in the file as one element of the list." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's write a file and save it as `baz.txt`." ] }, { "cell_type": "code", "execution_count": 173, "metadata": { "collapsed": true }, "outputs": [], "source": [ "data = ['a b c d e\\n', 'f g h i j\\n', 'k l m n o\\n', 'p q r s t\\n', 'u v w x y\\n', 'z']\n", "f = open('baz.txt', 'w')\n", "for line in data:\n", " f.write(line)\n", "f.close()" ] }, { "cell_type": "code", "execution_count": 176, "metadata": { "collapsed": true }, "outputs": [], "source": [ "data = ['a b c d e\\n', 'f g h i j\\n', 'k l m n o\\n', 'p q r s t\\n', 'u v w x y\\n', 'z']\n", "f = open('baz.txt', 'w')\n", "f.writelines(data)\n", "f.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Further Reading\n", "-------------------------------------------------------------------\n", "* [Learn Python 3 The Hard Way](https://learnpythonthehardway.org/python3/) (Recommended for absolute beginners)\n", "* [Dive into Python 3](http://www.diveintopython3.net)\n", "* [Google Python Class](https://developers.google.com/edu/python/)\n", "* [Official Python 3 Tutorial](https://docs.python.org/3/tutorial/index.html)" ] } ], "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.4" }, "toc": { "colors": { "hover_highlight": "#DAA520", "navigate_num": "#000000", "navigate_text": "#333333", "running_highlight": "#FF0000", "selected_highlight": "#FFD700", "sidebar_border": "#EEEEEE", "wrapper_background": "#FFFFFF" }, "moveMenuLeft": true, "nav_menu": { "height": "512px", "width": "252px" }, "navigate_menu": true, "number_sections": false, "sideBar": true, "threshold": 4, "toc_cell": false, "toc_section_display": "block", "toc_window_display": false, "widenNotebook": false } }, "nbformat": 4, "nbformat_minor": 2 }