{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "![header](header.png)\n", "# Logic and flow control\n", "\n", "When programming, it is rare that our programs are so simple that they are merely a list of instructions. Often, we are required to perform an operation several times (with slight modification), or make a decision as to whether to perform one operation or another. These require the related notions of logic, and flow control.\n", "\n", "## Booleans\n", "\n", "So far we have met numbers, and briefly strings, as basic types of data in Python. We now introduce the so-called boolean types, named for the English mathematician George Boole. These are the basic atoms of logical reasoning: the condition of being True or False." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "this_is_true = True\n", "this_is_false = False" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pay close attention. These capitalized True and False words are neither strings, nor variables. They are examples of the special keywords that form part of the Python language, which are not allowed to be used as variables.\n", "\n", "Of course, we do not want to have to manually assign things to being True or False. We wish to have the computer do it for us! This is where logical expressions come in. Think of it this way: __mathematical expressions evaluate to a number; logical expressions evaluate to a boolean.__\n", "\n", "Firstly, operations with booleans. There are 3 basic operations we can use to combine booleans to give a new boolean. The simplest, is \"not\". Applying the \"not\" operation to a boolean reverses its value:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "print(not True)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(not not True)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(not False)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(not(False)) # you can use brackets in boolean expressions\n", " #like in mathematical expressions,\n", " # to make them easier to read or express order of application" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next operation is called \"or\". \"Or\" takes two booleans, and is considered True if either of its input booleans are True. You can think of it as \"one, the other, or both\"." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(True or False)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(True or True)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "print(False or False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The final operation is \"and\". \"And\" is considered True only if both inputs are True:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(True and True)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "print(True and False)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "print(False and False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that and, or, not are all keywords.\n", "\n", "Now, this may seem all very abstract. The real use of these logical operations is to combine logical expressions. Most of these other logical expressions will be comparisons between objects. Suppose I am writing a quiz application. When the player gives an answer, I must make a comparison between the answer they give, and the correct answer, to decide whether or not they score a point. Two simple kinds of comparison are the greater than/less than comparisons between numbers: " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "x = 5\n", "print(x < 6)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "print(x < 3)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(x > 2 and x < 7)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(x < 1 or x < 9)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "print(x >= 6) # greater than or equal!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To make a direct comparison for equality, we use a double equals ==, to distinguish it from the variable assignment symbol =:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(x == 5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To check whether two things are not equal, use !=" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "print(x != 5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can use the modulo (\"remainder\") operator to check whether a number is, say, even:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "print(x % 2 == 0) # no remainder when divided by 2 means it is even" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You may be surprised to find it is possible to compare lots of things, not just numbers. For example:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(\"cat\" < \"dog\") # because cat comes first in the dictionary!" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(\"cat\" != \"Cat\") # capitals matter!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we are thoroughly bored of booleans, let's put them to work by using them to control our program.\n", "\n", "## if-statements\n", "\n", "Now we start programming proper. Using if-statements, we can tell our program to do something only if a particular expression is True. For example:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "What is the capital of France? Paris\n", "Correct!\n" ] } ], "source": [ "# The next line of code pauses the program and waits for the user to type a message\n", "answer = input(\"What is the capital of France? \")\n", "if answer == \"Paris\" or answer == \"paris\":\n", " print(\"Correct!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The key part for us, of course, is the second and third line. Firstly, the second line. It's what is called an if-statement, and it announces its arrival with the keyword \"if\". Following \"if\" is a logical expression, of the kind we have looked at above. Finally, there is a colon.\n", "\n", "A colon at the end of a line in Python announces that we are starting a new block of code, and the line is called the header of the block. In the case of the if-statement, the block is all the code that should be executed, should the if statement evaluate to True. Following every header, that is, __whenenver a line ends with a colon, the next line should be indented by 4 spaces__. The use of indentation is quite perculiar to Python; other languages tend to use curly braces to denote code blocks.\n", "\n", "Every line following the if-statement that is indented will be executed only if the boolean expression comes out True. To end the code block, and resume the normal flow of the program, begin a line without indentation. Example:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Can confirm that 5 is greater than 3,\n", "Please carry on with your day\n", "\n", "The if-statement has ended now\n", "\n", "The second if-statement has ended now\n" ] } ], "source": [ "if 5 > 3:\n", " print(\"Can confirm that 5 is greater than 3,\")\n", " print(\"Please carry on with your day\")\n", " \n", "print(\"\")\n", "print(\"The if-statement has ended now\")\n", "print(\"\")\n", "\n", "if 2 > 3:\n", " print(\"If you are seeing this output, be very alarmed\")\n", " \n", "print(\"The second if-statement has ended now\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From now on, we will be encountering indentation a lot. The structure of a Python program is expressed using indentation, and the Python interpreter can be very picky about correct indentation. So always indent after a header! You might want to consider setting the Tab key to insert 4 spaces in your coding environment.\n", "\n", "Now, it seems reasonable that if we wish to execute some code if something is True, there should be an option to do something only if it fails to be True. For this, we turn to else." ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "What is the capital of France? Moscow\n", "Incorrect\n" ] } ], "source": [ "answer = input(\"What is the capital of France? \")\n", "if answer == \"Paris\" or answer == \"paris\":\n", " print(\"Correct!\")\n", "else:\n", " print(\"Incorrect\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hence, an if-else statement is like a fork in the road for the program. Now, if we want to set lots of little forks in the road, it might be tempting to do this:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "What is the capital of France? F\n", "Very Funny\n" ] } ], "source": [ "answer = input(\"What is the capital of France? \")\n", "if answer == \"Paris\" or answer == \"paris\":\n", " print(\"Correct!\")\n", "else:\n", " if answer == \"F\":\n", " print(\"Very Funny\")\n", " else:\n", " print(\"Incorrect!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Read the above example to ensure that you understand it, and then forget about it. Python has a neater solution, rolling the else: if... part into a single line:" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "What is the capital of France? F\n", "Very Funny\n" ] } ], "source": [ "answer = input(\"What is the capital of France? \")\n", "if answer == \"Paris\" or answer == \"paris\":\n", " print(\"Correct!\")\n", "elif answer == \"F\": # elif is short for \"else, if\"\n", " print(\"Very Funny\")\n", "else:\n", " print(\"Incorrect!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this way, you can set a whole chain of conditions to check for before doing the else block. That's pretty much all there is to if-statements. It is worth bearing in mind, however, that if your program is becoming a tangled mess of if, elif, else, with varying layers of depth of indentation, it's probably time to rethink your design. For example, we will soon meet a structure called a dictionary, which would allow us to store the possible answers to the quiz question alongside their responses from the program in a table." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Flow control: for-loops\n", "\n", "There are two kinds of loop in Python. A loop is a section of code that is repeated several times, usually with some variation.\n", "\n", "A for-loop is a loop that completes a task a certain number of times. In most programming languages, you simply specify \"do this 10 times\". In Python, you must \"iterate over\" something. Precisely what that means will be discussed in the more advanced articles. However, the intuition is straightforward enough: we __specify some kind of sequence, and perform a task for each term in the sequence__.\n", "\n", "Here is an example:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "H\n", "e\n", "l\n", "l\n", "o\n", " \n", "w\n", "o\n", "r\n", "l\n", "d\n", "!\n" ] } ], "source": [ "for letter in \"Hello world!\":\n", " print(letter)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's unpack it. Again, we have that pattern of keyword -- this time \"for\" -- followed by a statement and ending in a colon, all followed by an indented block. The indented block is the section of code that is to be repeated.\n", "\n", "Now, \"Hello world!\" is acting as the sequence -- it is a sequence of characters. What about a list of words?" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello\n", "World\n" ] } ], "source": [ "for word in [\"Hello\", \"World\"]:\n", " print(word)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The sequence here is a list, denoted by square braces (we'll see much more of lists in tutorials to come!). In the last two examples, \"letter\" and \"word\" are temporary variables we assign to each member of the list as we iterate through it. They can be anything -- letter and word were just chosen here to be clear and readable.\n", "\n", "The design philosophy here is that, when programming, if we want to do a task over and over again, we probably want to take a collection of data, such as a list, and perform an operation on each piece of data. That is what this is all about.\n", "\n", "Now, what if we really do want to do something 10 times, rather than work our way through a word or list? Then we have a function called range() which generates a sequences of numbers for us. Want to do something 10 times?" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Spam\n", "Spam\n", "Spam\n", "Spam\n", "Spam\n", "Spam\n", "Spam\n", "Spam\n", "Spam\n", "Spam\n" ] } ], "source": [ "for x in range(10):\n", " print(\"Spam\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note, we still had to specify a dummy variable x, but we didn't have to mention it in the code block. We just performed the task for each element of the sequence provided by the range() function which is" ] }, { "cell_type": "code", "execution_count": 30, "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 x in range(10):\n", " print(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## While-loops\n", "\n", "The other kind of loop we have at our disposal is called a while-loop. Instead of doing something a fixed number of times, the while-loop executes its contents until some condition is met. This makes them work a lot like if statements, since we are checking whether a certain logical expression evaluates to True, or False.\n", "\n", "While-loops come with a word of warning. Prudence is required when programming the loop. If the condition is never met, then the program may continue to execute forever, until it is halted by outside forces, such as an interrupt message from the keyboard (usually ctrl+c), or the computer freezes because the computations it is performing have got out of hand.\n", "\n", "As a familiar real-world example, a computer game is nothing but a while-loop. The loop consists of\n", "* getting input from the player via the keyboard or joypad,\n", "* updating the game state, \n", "* drawing the results on the screen.\n", "\n", "This loop is repeated possibly hundreds of times per second in the case of real-time games, or at the leisure of the player in turn-based games. The loop halts when the player wins, loses, or quits the game.\n", "\n", "The first example we will see for a while-loop is one that emulates a for-loop. In this case, a certain counter is started, and that counter is incremented each time the looping block is executed. When the counter reaches a certain point, the loop stops.\n" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Spam\n", "Spam\n", "Spam\n", "Spam\n", "Spam\n", "Spam\n", "Spam\n", "Spam\n", "Spam\n", "Spam\n" ] } ], "source": [ "counter = 0\n", "while counter < 10:\n", " print(\"Spam\")\n", " counter = counter + 1 # increment the counter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Of course, there is not much point in doing this. However, counters remain useful if they only increment under specific conditions, which requires use of an if-statement to decide when to increment the counter." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Find the 8th word containing an i\n", "\n", "words = [\"automatic\",\n", "\"nappy\",\n", "\"stem\",\n", "\"ink\",\n", "\"literate\",\n", "\"pink\",\n", "\"occur\",\n", "\"hat\",\n", "\"birthday\",\n", "\"sip\",\n", "\"hot\",\n", "\"plants\",\n", "\"acid\",\n", "\"damage\",\n", "\"delight\",\n", "\"legs\",\n", "\"terrible\",\n", "\"cute\",\n", "\"glove\",\n", "\"successful\",\n", "\"permit\",\n", "\"jolly\",\n", "\"shoes\",\n", "\"placid\",\n", "\"tendency\",\n", "\"bleach\",\n", "\"goofy\",\n", "\"telephone\",\n", "\"match\",\n", "\"sniff\",\n", "\"abortive\",\n", "\"hissing\",\n", "\"greasy\",\n", "\"daily\",\n", "\"cave\",\n", "\"basketball\",\n", "\"growth\",\n", "\"squeeze\",\n", "\"labored\",\n", "\"panoramic\"\n", "]\n", "total = 0\n", "while total < 8:\n", " \n", " total = total + 1\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The fizzbuzz challenge\n", "\n", "This is a classic programming exercise, appearing in many courses and even job interviews. The task is simple, but if you can solve it, you know you've got the hang of logic and flow control. Your task is to write a short program that prints out the numbers 1 to 100, but if the number is divisible by 3, to print \"Fizz\" instead; and if it is divisible by 5, print \"Buzz\"; and if it is divisible by both 3 and 5, print \"Fizzbuzz\". Everything you need to solve this challenge is contained in the above text, but you will need to design an algorithm that successfully combines these elements to produce the correct solution.\n", "\n", "Have a good go, but if you get stuck, see the video below for a solution:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "image/jpeg": "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\n", "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import YouTubeVideo\n", "YouTubeVideo(\"CzPpVurUSIM\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.1" } }, "nbformat": 4, "nbformat_minor": 1 }