{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction to Python Programming" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## 1. Getting Started" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Running Python in the Jupyter Notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python itself normally exists just to run programs that you have written, but it can also be run in an interactive environment. The Jupyter Notebook is an Interactive Development Environment which lets you write and run code, and add text and documentation to your project. The Jupyter Notebook is included as part of the default Anaconda installation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To launch the Jupyter Notebook on a Mac or Linux machine: Open up a terminal, and type `jupyter notebook` followed by enter. On a Windows machine Click on the \"Jupyter Notebook\" icon in the \"Start\" menu or form the \"Anaconda Navigator\". This should launch a browser, with the Notebook session running inside. To close the Jupyter Notebook on a Mac or Linux machine: Open the terminal window which is running the notebook, press \"Control\" and \"c\" keys simultaneously, and subsequently type \"\n", "y\" to confirm you want to exit." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `In[1]` is the Python prompt and it should have a flashing cursor. As is traditional under these circumstances, the first thing you should do is get Python to print out the text \"Hello, World\". To do this, type the command below at the prompt and press return (control+return in the notebook)." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello, World\n" ] } ], "source": [ "print('Hello, World')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Barring the odd typing mistake you have just run your first Python script. Here, 'print' is a Python function that tells the interpreter that you want it to output the things which follow in the brackets. The 'Hello, World' is a _string_ and is what you want the `print` function to print out." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Playing with Python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The Python Shell is a great way to experiment with Python. It’s something that I return to every time I find myself thinking “I wonder what happens if you do this?” or “What’s the best way to do that?”. You can’t break anything by trying something out and if you do make a mistake, at least you will get an error message that you might be able to decode. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can play around with Python in the notebook's code cells (we have left some blank ones for you to try out your own commands in) and execute the cell once you are done typing. The output of your commands will appear underneath. If you have made a mistake, or you want to try something else, you can edit the code in the cell and execute it again when you're done." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You are not limited in what you can do at the prompt. You can load modules, look at them to see what they do, play with them. I could also check the documentation for the modules I wanted to use by typing `help()`. There is a lot of information in there and you will find yourself using it again and again." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The Jupyter Notebook has some very helpful features that can make things easier while you learn the basics of Python. For example, it enables tab-completion for e.g. variable, function, and file names, gives hints about required & optional arguments for functions, and has improved command history interaction." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Evaluating Expressions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The Python shell can also be used to evaluate expressions, allowing you either to perform calculations interactively, or more usually to check more complicated expressions interactively before putting them in your programs. The Python shell allows you to do all of the normal operations, in pretty much the way you would expect." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Have a go with some expressions, such as: " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "scrolled": true }, "outputs": [], "source": [ "3 * 4 # Multiplication" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "7 + 10 # Addition" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "7 - 10 # Subtraction " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "10 / 3 # Division" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So far, so good, but don’t limit yourself to the examples here. Try some of your own and make sure you understand the results. There are a few other operators, though, which you might not be as familiar with. Try these:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "10 % 3 # Modulus (remainder)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "2 ** 10 # Exponentiation (2 to the power of 10)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Again, as expected. Division also works:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "10 / 7" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python can handle some very large numbers. For example, it can easily deal with raising 2 to the power of 32:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "2 ** 32 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python can deal with numbers slightly larger than this too, so" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "2 ** 64" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and even" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "2 ** 1024" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "work just fine. You can go even higher, so raising to the power of 100,000" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "2 ** 100000" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "is quite OK. Though I must admit that I haven’t actually checked that the 30103 digits of this result are correct." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some of these operators don’t just work on numbers, `+` and `*` can be used on strings as well. Strings are just sequences of characters enclosed in quotation marks like the 'Hello, World' above. Python doesn’t mind if you use single or double quotes as long as you don’t mix them. \"Addition\", `+`, concatenates two (or more) strings together to return a new longer string. \"Multiplication\", actually repetition, `*`, takes a number and a string and repeats the string that many times in a new string: " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "'Hello, ' + \"world!\" " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "'Hello ' * 8 " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "9 * 'Hello...'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### _Exercise 1.1_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Try to use expressions that you would use in your normal work and see if they give the results you expect. Explore using brackets to group sub-expressions (things in brackets are always evaluated before everything else). Before you move on to the next section, which of the following expressions would correctly calculate the hypotenuse of a right-angled triangle, with sides length 12 and 5?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "a)\n", "```Python\n", "(12*2 + 5*2)/2\n", "```\n", "b)\n", "```Python\n", "(12**2 + 5**2)**0.5\n", "```\n", "c)\n", "```Python\n", "(12^2 + 5^2)^0.5\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Using Variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So far, we have just been playing with what Python calls values. When you are writing programs, it’s useful to be able to give names to the values that we are dealing with so that once we do a calculation or string manipulation we can refer to the results later. We do this with an assignment statement, which looks like this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You’ll notice that, when this line is executed, Python doesn’t return anything. This is also true if you capture the result of one of the expressions that we tried above:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "y = 10.0 / 7" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To look at the values, just type the names of the variables that you have created:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "More normally, you would probably output the results using the `print` statement we started with:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "print(x, y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As well as being on the left of an assignment operation, variable names can be used in the expressions as well, so" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = x + y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "replaces the value currently referred to by `x` with the new value obtained from adding the values of `x` and `y`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Variables that refer to numbers are fine and are incredibly useful, but they are also one of the less interesting types of Python data. This is because they only have a value. Some variables are much more interesting, and string variables are a good example. To assign a string to a variable you follow the same basic syntax as before:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "s = 'The quick brown fox jumps over the lazy dog'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "print(s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Again, you can just type the variable name or use it in a `print` statement, but what makes a variable containing a string more interesting is that it is one of Python’s object data types. This means that it doesn’t just passively hold the value of the string, it also knows about things you can do to the string. For example:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "s.upper()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `.` here indicates that the method is part of the string `s`, and the brackets indicate that we want to execute it. Here the brackets are empty, but later we will be using them to pass information into the methods. There are many things that strings can do with themselves, and if you look at the [Python cheat sheet](https://github.com/zencore/2019-Biocuration-Module-2/blob/master/webinars/CheatSheet.pdf), you will see what they all are. Try using them on the string, for example: " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "s.capitalize()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "s.title()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you look at `s` itself after any of these, you’ll see it hasn’t changed, these object methods simply return a new version of the string with the appropriate transformation done to it which you can then store in another variable (or back in `s`) if you want to. This is because a string cannot be changed in place (in technical terms, it is _immutable_), only explicitly overwritten with a new value. So, to save the new version of the string, you can type the following:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "s = s.title()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can use almost any combination of letters and numbers in the variable names, but you can’t start a variable name with a number. You can’t include spaces (a space is one of the ways that Python can tell that the name is finished) but you can include underscore characters. Variable names can also begin with underscore, but these tend to be used under special circumstance which you will discover once you start learning about object-oriented programming." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### _Exercise 1.2_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use the .count() method on the string “The quick brown fox jumps over the lazy dog” to count the occurrences of the word “the”." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "s = \"The quick brown fox jumps over the lazy dog\" \n", "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If this returns 1, how could you persuade it that it should be 2?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once you have that sorted out, try" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`s.split()`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and see if you can understand what it has done." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Lists " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The last exercise returned a result which you might think looks unusual. My interpreter gave me:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "s = \"The quick brown fox jumps over the lazy dog\"\n", "s.split()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This result is in the form of a _list_ object. A list is exactly what you might expect based on the name. It’s a set of values (which can be numbers, strings, objects or even lists, but that is a bit advanced for now) that are kept in a specific order. You can create a new list using the same format as the result above:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "shopping = ['bread', 'potatoes', 'eggs', 'flour', 'rubber duck', 'pizza', 'milk']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Like strings, lists are a type of object, and so they also have some methods associated with them, which you can use. However, unlike strings, these methods mostly change the list in place, rather than returning a new list. So, when you type" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "shopping.sort()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python doesn’t return a value, but if you look at the list, you will see that the order of the items has changed." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "shopping" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This means that unlike strings, lists are _mutable_, and individual items and sets of items can be changed in place. If you decide you want to add items to the list, you can do it with the `.append()` method:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "shopping.append('mayonnaise')\n", "shopping" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you feel it’s important enough to go at the top of the list, you can use `.insert()` to insert the new item at a particular point and shuffle everything else up:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "shopping.insert(0, 'mayonnaise')\n", "shopping" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Removing items from the list is just as easy - you use `.pop()` to do that. If you don’t give it an index, it will remove the last item in the list, otherwise `pop` removes the item with the index you specify and shuffles everything else up one position to close the gap. Give it a try, to remove one of the \"mayonnaise\" items in the shopping list. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Sequences" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The two object types that we have talked about so far share a number of properties. Both strings and lists consist of ordered pieces of data. In the case of strings this is simple characters. In lists, the elements of the list can be of any object type." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For both lists and strings we might want to refer to a particular item or range of items in a string or list and we can do this easily:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "words = s.split()\n", "print(words[3]) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You will see that \"fox\" is actually the fourth word and this is just one of the things that computers do that you have to get used to. The first element in a sequence has an index of 0, so" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "print(words[0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "gives you the first item in the list. This is referred to as zero-based indexing or offset numbering. Its origins are in programming languages where variables actually refer to the memory location of the start of the list, and now has just become a tradition. Negative indices are assumed to be relative to the end of the array, so" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "words[-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "yields the final element in the list, in this case \"dog\". Of course, if we knew how long the sequence was, we could just use the number of the last element. For any sequence data type, `len()` will tell us how many elements it has:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "len(words)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "len(s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So, since the sequences are indexed from zero, the last element, i.e. `words[-1]`, is the same as `words[len(words)-1]`. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### _Exercise 1.3_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are a few quirks to sequence indexing (apart from starting at 0), and we have tried to summarise these on the [Python Cheat Sheet](https://github.com/zencore/2019-Biocuration-Module-2/blob/master/webinars/CheatSheet.pdf). Have a go with a few of the \"Indices and Slices\" and make sure you understand how they work. Then, instead of trying them on a list, try them on a string. Now, if you are really adventurous, try to print the third letter of the fourth word in the `words` list." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your command(s) here or use the IPython shell..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### _Exercise 1.4_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Below is a set of commands working with a list of cities. First, the list is extended by adding 'Athens' onto the end, and then 'Nairobi' - the third element in the list - is assigned to the variable `kenya`. Some of the code has been removed (replaced with `---`). Fill in the blanks in the code block to make it work." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cities = ['Winnipeg', 'Guangzhou', 'Nairobi', 'Santiago', 'Glasgow']\n", "cities.---('Athens') # add 'Athens' onto the end of the list\n", "kenya = cities[---] # access the third entry in the cities list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Summary" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Python can be used to calculate the results of a wide range of expressions, and print out the results.\n", "* Like in all programming languages, variables can be used to store the results of calculations or simple values that we might need to use later.\n", "* Variables refer to values. The values can be numbers (integer and floating point), strings or lists. You will discover soon that there are other data types as well.\n", "* Some data types are objects, which have methods associated with them. These methods perform common tasks on the values of the objects.\n", "* Some data types are sequences, which let us access individual elements at will.\n", "* Sequence data types allow us to step through the values in them, but to do that we need to take some first steps towards writing real programs." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### _Debugging Exercise_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The lines below have mistakes in them, which produce errors when they are run. Try to identify the problems in the code, and fix them so that they run without error." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "cake flavours = ['chocolate', 'coffee', 'carrot', 'vanilla']\n", "cake_flavours.append('lemon')\n", " print(cake_flavours)" ] } ], "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.0" } }, "nbformat": 4, "nbformat_minor": 1 }