{ "metadata": { "name": "variables" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Python, IPython, and the basics\n", "\n", "\n", "* * * * *\n", "\n", "**Based on Lecture Materials By: Milad Fatenejad, Katy Huff, Joshua R. Smith, Tommy Guy, Will Trimble, and many more**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Introduction\n", "\n", "This lecture is on basic programming in python. In order to do the examples, we are going to use an environment called IPython Notebook. I expect this lecture to be interactive, so stop me at any point if you have questions. The correct power dynamic is that people are the masters and the machines are servants. The computer is a hammer; it exists to help us get things done. We can hammer nails with the handle, with the claw of the hammer; some of us even hammer nails with bricks. But when you learn what part of the hammer works best with nails, and have some experience swinging it, you spend less time worrying about the hammering and more time worrying about your furniture." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So now would be a good time to roll out [PEP 20, The Zen of Python](http://www.python.org/dev/peps/pep-0020/)\n", "\n", "> Beautiful is better than ugly. \n", "> Explicit is better than implicit. \n", "> Simple is better than complex. \n", "> Complex is better than complicated. \n", "> Flat is better than nested. \n", "> Sparse is better than dense. \n", "> Readability counts. \n", "> Special cases aren't special enough to break the rules. \n", "> Although practicality beats purity. \n", "> Errors should never pass silently. \n", "> Unless explicitly silenced. \n", "> In the face of ambiguity, refuse the temptation to guess. \n", "> There should be one-- and preferably only one --obvious way to do it. \n", "> Although that way may not be obvious at first unless you're Dutch. \n", "> Now is better than never. \n", "> Although never is often better than *right* now. \n", "> If the implementation is hard to explain, it's a bad idea. \n", "> If the implementation is easy to explain, it may be a good idea. \n", "> Namespaces are one honking great idea -- let's do more of those! " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here are some links to tutorials and reference material.\n", "\n", "* [Dive into Python](http://www.diveintopython.net/toc/index.html)\n", "* [Software Carpentry's Python Lectures](http://software-carpentry.org/4_0/python/)\n", "* [IPython: A System for Interactive Scientific Computing](http://dx.doi.org/10.1109/MCSE.2007.53)\n", "* [How to Think Like a Computer Scientist](http://www.greenteapress.com/thinkpython/thinkpython.html)\n", "* [Google's python class](https://developers.google.com/edu/python/)\n", "* [The python documentation](http://docs.python.org/2.7/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python environments\n", "\n", "You can run python commands in a handful of ways; you can create executable scripts, you can run the python interpreter, you can run IPython, or you can run IPython notebook. IPython is an alternative to the built-in Python interpreter with some nice features. IPython notebook gives you interactive access to the python interpreter from within a browser window, and it allows you to save your commands as a \"notebook\".\n", "\n", "Let's give the built-in interpreter a spin just this once. Open a **Terminal** window, which starts your default shell. Type " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " python " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And you should see python start up. Type " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " print \"Fresh out of parrots\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note the black-and-white wallpaper.\n", "\n", "Escape from python with \n", "\n", " quit()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "\n", "\n", "\n", "IPython has more useful features for interactive use than the standard python interpreter, but it works in the same way--it is interactive, and you get there from the command line. IPython Notebook uses javascript to allow you to enter python commands in your browser and show you the result in the browser. We'll use it from here on out." ] }, { "cell_type": "code", "collapsed": true, "input": [ "print \"hello world\"" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Navigating in IPython Notebook\n", "\n", "The box above is called the input cell; commands you put here will be fed to the python interpreter one at a time when you press **Shift-ENTER**. \n", "\n", "The output of the command, or the error message, appears below the line you entered it on.\n", "\n", "The panel which may appear on the left has some notebook options; you can minimize the panel by double-clicking on the bar separating the windows. " ] }, { "cell_type": "code", "collapsed": true, "input": [ "print \"Try and tell that to the young people\"\n", "print \"of today--they won't believe you.\"" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you hit **ENTER** only, IPython Notebook gives you another line in the current cell. \n", "\n", "This allows you to compose multi-line commands and submit them to python all at once. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Up and down arrows will allow you to move the cursor to different cells in the notebook, including these cells containing text (which you can edit in your browser). \n", "\n", "Only the cells for which you press Shift-ENTER or Control-ENTER will be executed by the python interpreter. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can enter the same line over and over again into the interpreter. It's weird, but it's life. " ] }, { "cell_type": "code", "collapsed": true, "input": [ "i = 0" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Shift-ENTER** executes and moves to the next cell. \n", "\n", "**Control-ENTER** (**Cmd-ENTER** on Macs) executes the cell and does *not* move to the next cell. \n", "\n", "Try entering this cell a few times: " ] }, { "cell_type": "code", "collapsed": true, "input": [ "i = i + 1\n", "print i" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you want to create new empty cells, you can use Insert -> Insert Cell Below or use the Insert Cell Below button at the top of the notebook." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Getting Help\n", "\n", "\n", "\n", "IPython has some nice help features. Let's say we want to know more about the integer data type. There are at least two ways to do this task:" ] }, { "cell_type": "code", "collapsed": true, "input": [ "help(int)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "which displays a scrolling text help, or" ] }, { "cell_type": "code", "collapsed": true, "input": [ "int?" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Which displays a shorter help summary in the magic pane at the bottom of the screen. You can minimize the magic pane when it gets in your way." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you wanted to see all the built-in commands available for something, use the `dir` command. Check out all of the methods of the object \"Hello world\", which are shared by all objects of the str type." ] }, { "cell_type": "code", "collapsed": true, "input": [ "dir(\"Hello world\")" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There's a method that looks important -- `.swapcase()`. Let's see what it does: " ] }, { "cell_type": "code", "collapsed": true, "input": [ "\"Hello world\".swapcase()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hrm. Ahem." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Executing code in files\n", "\n", "If your code is in a file, you can execute it from the IPython shell with the **%run** command. Execute `hello.py` like so" ] }, { "cell_type": "code", "collapsed": true, "input": [ "%run hellp.py" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Ooops.* We misspelled **hello.py**, and python is giving us an error message. Change the line above to hello.py, hit **Shift-ENTER**, and see what it does." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Clearing IPython\n", "\n", "\n", "\n", "To clear everything from IPython, use the %reset command." ] }, { "cell_type": "code", "collapsed": true, "input": [ "mystring = \"And three shall be the count.\" \n", "print mystring" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "%reset" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "print mystring" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that the error message contains a recap of the input that caused the error (with an arrow, no less!) It is objecting that `mystring` is not defined, since we just reset it.\n", "\n", "## Variables\n", "\n", "All programming languages have variables, and python is no different. To create a variable, just name it and set it with the equals sign. One important caveat: variable names can only contain letters, numbers, and the underscore character. Let's set a variable." ] }, { "cell_type": "code", "collapsed": true, "input": [ "experiment = \"current vs. voltage\"" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "print experiment" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "voltage = 2" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "current = 0.5" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "print voltage, current" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This last line shows us a piece of the syntax of the `print` command: if we give `print` comma-separated variables, it prints them with a space between them." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Types and Dynamic Typing\n", "\n", "Like most programming languages, things in python are typed. Data types reflect the way that the data is ultimately stored as ones and zeroes and affect the operations that are permitted on the data. We have already defined three different variables: `experiment`, `voltage`, and `current`. They are stored in three different data types: `string`, `integer`, and `float`. \n", "\n", "* `string` data types are for lists of consecutive characters, such as text. \n", "* `int` data types are exact representations of the integers. \n", "* `float` data types, short for floating point numbers, are inexact representations of numbers that are internally stored in scientific notation.\n", "\n", "There are many other data types, but these are fundamental.\n", "\n", "You can inspect the type of a variable by using the `type` command." ] }, { "cell_type": "code", "collapsed": true, "input": [ "type(experiment)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "type(voltage)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "type(current)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Why should you care about data types? In some cases, **failing to pay attention to the data types will cause wrong answers**." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python is a dynamically typed language (unlike, say, C++). \n", "\n", "Dynamic typing means that you don't have to declare the type of a variable \n", "when you define it; Python just figures out the fundamental data type based \n", "on how you set the variable. Lets say you set a variable. Sometime later you \n", "can just change the type of data assigned to a variable and Python is \n", "perfectly happy about that. \n", "\n", "Here's an example of dynamic typing. What's the type of data assigned to `voltage`?" ] }, { "cell_type": "code", "collapsed": true, "input": [ "type(voltage)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lets assign a value of 2.7 (which is clearly a float) to `voltage`. What happens to the type?" ] }, { "cell_type": "code", "collapsed": true, "input": [ "voltage = 2.7" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "type(voltage)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can even now assign a string to the variable `voltage` and python would be happy to comply." ] }, { "cell_type": "code", "collapsed": true, "input": [ "voltage = \"2.7 volts\"" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "type(voltage)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I'll let you ruminate on the pros and cons of this construction while I change the value of voltage back to an `int`:" ] }, { "cell_type": "code", "collapsed": true, "input": [ "voltage = 2" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Coersion\n", "\n", "It is possible to coerce (a fancy and slightly menacing way to say \"convert\") certain types of data to other types. For example, its pretty straightforward to coerce numerical data to strings." ] }, { "cell_type": "code", "collapsed": true, "input": [ "voltage_string = str(voltage)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "current_string = str(current)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "voltage_string" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "type(voltage_string)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you might imagine, you can go the other way in certain cases. Lets say you had numerical data in a string." ] }, { "cell_type": "code", "collapsed": true, "input": [ "resistance_string = \"4.0\"" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "resistance = float(resistance_string)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "resistance" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "type(resistance)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What would happen if you tried to coerce `resistance_string` to an int? What about coercing resistance to an int? Consider the following:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "resistance_string = \"4.2 Ohms\"" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Do you think you can coerce that string to a numerical type?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise\n", "\n", "Assign three variables, called `versionnumber`, `numberofpythons`, and `thenumberten` with the values 2, 6, and \"ten\" with the types float, int, and string respectively." ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This cell prints the values, so you can check if the values are what you expect:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print versionnumber\n", "print numberofpythons\n", "print thenumberten" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Test your work. Run the following three expressions. If all three evaluate as `True` you have set the data types correctly." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print type(versionnumber) == float\n", "print type(numberofpythons) == int\n", "print type(thenumberten) == str" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## On Being Precise with floats and ints\n", "Let's say you had some voltage data that looks like the following\n", "\n", " 0\n", " 0.5\n", " 1\n", " 1.5\n", " 2\n", "\n", "Obviously, if you just assigned this data individually to a variable, you'd end up with the following types\n", "\n", " 0 -> int\n", " 0.5 -> float\n", " 1 -> int\n", " 1.5 -> float\n", " 2 -> int\n", "\n", "But what if you wanted all of that data to be floats on its way in? You could assign the variable and then coerce it to type float:" ] }, { "cell_type": "code", "collapsed": true, "input": [ "voltage = float(1)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But that's ugly. If you want what is otherwise an integer to be a float, just add a period at the end" ] }, { "cell_type": "code", "collapsed": true, "input": [ "voltage = 1.0" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "type(voltage)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This point becomes important when we start operating on data in the next section.\n", "\n", "\n", "\n", "## Data Operations\n", "\n", "\n", "\n", "What's the point of data if we aren't going to do something with it? Let's get computing." ] }, { "cell_type": "code", "collapsed": true, "input": [ "a = 1" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "b = 2" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "c = a + b" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "c" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "type(a), type(b), type(c)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So we got a value of three for the sum, which also happens to be an integer. Any operation between two integers is another integer. Makes sense.\n", "\n", "\n", "\n", "So what about the case where a is an integer and b is a float?" ] }, { "cell_type": "code", "collapsed": true, "input": [ "a = 1" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "b = 2.0" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "c = a + b" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "c" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "type(a), type(b), type(c)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can do multiplication on numbers as well." ] }, { "cell_type": "code", "collapsed": true, "input": [ "a = 2" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "b = 3" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "c = a * b" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "c" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "type(a), type(b), type(c)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Also division." ] }, { "cell_type": "code", "collapsed": true, "input": [ "a = 1" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "b = 2" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "c = a / b" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "c" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**ZING!**\n", "\n", "This is why type is important. Dividing two integers returnes an integer: this operation calculates the integer part of the quotient and discards the remainder.\n", "\n", "If everything was a float, the division is what you would expect." ] }, { "cell_type": "code", "collapsed": true, "input": [ "a = 1.0" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "b = 2.0" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "c = a / b" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "c" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "type(a), type(b), type(c)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are operations that can be done with strings." ] }, { "cell_type": "code", "collapsed": true, "input": [ "firstname = \"Johann\"" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "lastname = \"Gambolputty\"" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When concatenating strings, we must explicitly use the concatenation operator `+` which takes two strings and creates one longer string." ] }, { "cell_type": "code", "collapsed": true, "input": [ "fullname = firstname + lastname" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "print fullname" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "fullname = firstname + \" \" + lastname" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "print fullname" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are other operations defined on string data. Use the `dir` command to find them. One example I'll show is the `.upper()` method. Lets take a look at the documentation." ] }, { "cell_type": "code", "collapsed": true, "input": [ "str.upper?" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So we can use it to upper-caseify a string. " ] }, { "cell_type": "code", "collapsed": true, "input": [ "fullname.upper()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You have to use the parenthesis at the end because upper is a method of the string class.\n", "\n", "\n", "\n", "For what its worth, you don't need to have a variable to use the `.upper()` method, you could use it on the string itself." ] }, { "cell_type": "code", "collapsed": true, "input": [ "\"Johann Gambolputty\".upper()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What do you think should happen when you take upper of an int? What about a string representation of an int?\n", "\n", "\n", "\n", "That wraps up this lesson. We tried out the IPython shell and got some experience with ints, floats, and strings. Along the way we talked about some philosophy and how programming is like hammering. \n", "\n", "\n", "\n", "## Miscellaneous scraps\n", "\n", "## Pasting\n", "\n", "\n", "\n", "You can paste things into the IPython console by copying text from your machine with **ctrl+c** and typing **%paste** at the IPython prompt. The **%paste** is necessary syntax for multi-line clipboard deposits." ] }, { "cell_type": "code", "collapsed": true, "input": [ "%paste # Use ctrl-c in the browser %paste in the terminal" ], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }