{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Notebook-5: Truth & Conditions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Lesson Content \n", "\n", "- Comparisons\n", " - Booleans\n", " - \"Not equal\" operator\n", " - \"< > <= >=\" operators\n", "- Conditions pt.1\n", " - IF \n", " - ELSE \n", " - ELIF\n", "- Boolean Logic\n", " - AND\n", " - OR\n", " - NOT\n", "\n", "In this lesson we'll learn how to compare stuff (like numerical quantities but also words and strings) via *Comparison Operators*. \n", "\n", "We'll also see how to express logical concepts like: \" `if` this condition is `True`, then do something...\". These concepts will enable your code account for different possibilities and let it run to accordingly. They will also serve to perform assertions and to test if certain conditions have been met or not." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Comparisons\n", "----\n", "\n", "\n", "## Booleans\n", "\n", "The most basic form of comparison is to test if something is `True` of `False`. To do so we'll have to quickly introduce another *data type*, the **boolean**. \n", "\n", "Booleans are different from the numerical (*floats* and *integers*) or textual (*strings*) types we have seen so far because they have only two possible values once they are set: `True` or `False`." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "This statement is: 'True'\n" ] } ], "source": [ "myBoolean = True\n", "print(myBoolean)\n", "print(\"This statement is: '\" + str(myBoolean) + \"'\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note: did you see the `str()` around the `myBoolean` variable on the second `print` line? That's so that we can print out its value as part of a string." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Comparison Operators" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "How do we use booleans? Well, what is the 'answer' if I ask you \"Is it true or false than an elephant is bigger than a mouse?\" And remember too that in an early notebook we looked at how a computer 'thinks' -- it's all in terms of things being `True` or `False`. \n", "\n", "Note: just so that you know, sometimes people will use `1` and `0` in place of `True` and `False` because that's what's actually happening behind the scenes. It's the same thing _logically_ , but Python views sees `True` and `False` differently from `1` and `0` because the latter are numbers, while the former are _boolean_ data type.\n", "\n", "You will need these set of operators:\n", "\n", "| Operator | Meaning | Example |\n", "|:----------|:-------------------|:---------------------------------------------------------------|\n", "| `>` | Greater Than | `A>B` This returns `True` if value in `A` is larger than value in `B` |\n", "| `<` | Less Than | `A=` | Greater Equal Than | `A>=B` This returns `True` if value in `A` is larger than or equal to value in `B` |\n", "| `<=` | Less Equal Than | `A<=B` This returns `True` if avlue in `A` is smaller than or equal to value in `B` |\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here's an initial example (without a print statement)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "25 > 7" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And further examples (with print statements so that they are all printed, not just the last one)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "False\n", "False\n", "True\n", "False\n", "True\n" ] } ], "source": [ "print(7 >= 7)\n", "print(7 > 7)\n", "print(25 <= 7)\n", "print(25 <= 25.0)\n", "print(25 < 25.0)\n", "print(25 < 25.1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numerical comparisons are fairly straightforward, and you'll see that Python automatically does fairly sensible things:\n", "- Because it converts automatically between integers and floats, `25` and `25.0` are evaluated properly\n", "- As are 25 and 25.1 because the 'casting' of integers to floats turns `25` into `25.0` automatically\n", "\n", "But here are some slightly more complicated examples involving _string_ comparisons:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "simple comparison:\n", "False\n", "True\n", "something slightly trickier\n", "False\n", "False\n", "True\n", "trickier again\n", "True\n", "hmmmm...\n", "True\n" ] } ], "source": [ "print(\"simple comparison:\")\n", "print(\"A\" > \"B\")\n", "print(\"B\" > \"A\")\n", "\n", "print(\"something slightly trickier\")\n", "print(\"A\" > \"a\")\n", "print(\"A\" >= \"a\")\n", "print(\"A\" < \"a\")\n", "\n", "print(\"trickier again\")\n", "print(\"ab\" < \"abc\")\n", "\n", "print(\"hmmmm...\")\n", "print(\"James\" < \"Jane\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "_Why does Python think 'A' is less than 'a', and 'Aardvark' is less than 'Ant'?_\n", "\n", "When comparing `str` objects, Python uses character _unicodes_. [Unicode](https://www.unicode.org/) is a specification that aims to list every character used by human languages and give each character its own unique code. In Python, these codes are of type `int`. \n", "\n", "To see this in action, we can use the `ord` function to get Python to show us the unicode for a single character:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "65\n", "97\n" ] } ], "source": [ "print(ord(\"A\"))\n", "print(ord(\"a\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hopefully this output helps you to see why `print(\"A\" > \"a\")` returns `False`\n", "\n", "When there are multiple characters in a `string` object, Python compares each character in order. Suppose, as we do above, we have `str1` as \"James\" and `str2` as \"Jane\". The first two characters from `str1` and `str2` (J and J) are compared. Because they are equal, the second two characters are compared. Because they are also equal, the third two characters (m and n) are compared. And because m has smaller unicode value than n, `str1` is less than `str2`." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "109\n", "110\n" ] } ], "source": [ "str1 = \"James\"\n", "str2 = \"Jane\"\n", "\n", "#compare\n", "print(str1 < str2)\n", "\n", "#proof\n", "print(ord(\"m\"))\n", "print(ord(\"n\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hopefully this helps you to see why `print(\"James\" < \"Jane\")` returns `True`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### A challenge for you!\n", "\n", "In the next two challenges, we've deliberately left out or broken some code that _you_ need to fix!\n", "\n", "Fix this code so that it returns `True`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden", "solution2_first": true }, "outputs": [], "source": [ "first_variable = 87.0\n", "second_variable = 9\n", "\n", "print(first_variable % 80 ??? second_variable)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden" }, "outputs": [], "source": [ "first_variable = 87.0\n", "second_variable = 9\n", "\n", "print(first_variable % 80 < second_variable)\n", "\n", "#proof\n", "print(first_variable % 80)\n", "print(second_variable)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Fix this code so that it returns `False`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden", "solution2_first": true }, "outputs": [], "source": [ "print(\"Aardvark\" ??? \"Ant\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden" }, "outputs": [], "source": [ "print(\"Aardvark\" > \"Ant\")\n", "\n", "#proof\n", "print(ord(\"a\"))\n", "print(ord(\"n\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Testing for Equality\n", "\n", "So we've seen the comparison operators that you probably still remember from high-school maths. But sometimes we don't want to test for _difference_, we want to test if two things are _the same_. In your maths class you probably just wrote $$x = y$$ and moved on to the next problem, but remember: one equals sign is already being used to assign values to variables! As in:\n", "\n", "```python\n", "my_var = 1\n", "```\n", "\n", "To test if something is exactly equal we can use the *equality comparison operator*, which is two equals signs together (*==*). This equality comparison returns `True` if the contents of two variables/results of two calculations are equal. That's a bit of a mouthful, but all we're saying is that we compare the left-hand side (LHS) of the equality operator (`==`) with the right-hand side (RHS) to see if they evaluate to the same answer.\n", "\n", "**A _lot_ of new programmers make the mistake of writing `=` in their code when they wanted `==`**, and it can be hard to track this one down. So always ask yourself: am I comparing two things, or assigning one to the other?\n", "\n", "Run the following code and check you understand why the output produced is as it is." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# This (=) assigns a value to a variable\n", "british_capital = \"London\"\n", "french_capital = \"Paris\"\n", "\n", "# This (==) compares two variables\n", "print(british_capital == french_capital)\n", "\n", "# This is probably a mistake\n", "british_capital = french_capital\n", "print(british_capital)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### A challenge for you!\n", "\n", "Before you run the code in each cell, try to think through what _you_ expect each one to print out!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Is this True?\n", "2 == 34" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# How about this?\n", "7 == 7" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# How about this?\n", "\"Foo\" == \"Foo\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# And this?\n", "\"Foo\" == \"Bar\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden", "solution2_first": true }, "outputs": [], "source": [ "# And this?\n", "10 % 3 == 3 / 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden" }, "outputs": [], "source": [ "#this may help interpret the result here\n", "print(10 % 3)\n", "print(3 / 3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Testing for Inequality\n", "\n", "What if you want to check if two things are *different* rather than equal? Well then you'll need to use the *Not Equal (!=)* operator, which returns `True` when there's no equality between the conditons you are comparing. \n", "\n", "Check you understand the output when running the following code" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Reset the variables to their 'defaults'\n", "british_capital = \"London\"\n", "french_capital = \"Paris\"\n", "\n", "# This time python is going to print True,\n", "# since we are comparing different things\n", "# using the Not Equal operator!\n", "print(british_capital != french_capital)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "# Conditions\n", "\n", "OK, so now we've seen comparisons and booleans, but why? Where are we going with this? Think back to the first notebook and the example of what is happening inside a computer: _if_ the user has clicked on the mouse _then_ we need to do something (e.g. change the colour of the button, open the web link, etc.). Everything that we've done up until now basically happened on a single line: _set_ this variable, _set_ that variable, print out the result of the _comparison_. \n", "\n", "Now we're going to step it up a level.\n", "\n", "To check a condition you will need to use a *statement* (i.e. [everything that makes up one or more lines of code line](https://stackoverflow.com/questions/4728073/what-is-the-difference-between-an-expression-and-a-statement-in-python) ) to see `if` that condition is True/False, in which case do one thing, or `else` do something else...\n", "\n", "Let's see that in action!\n", "\n", "## IF condition\n", "\n", "Let's start with a basic `if` statement. In Python you write it:\n", "\n", "```python\n", "if conditon-to-check:\n", " statement\n", "```\n", "\n", "So an `if` condition starts with the word `if` and ends with a colon (`:`).\n", "\n", "The statement is the code that we want the computer to run _if_ the `condition-to-check` comes out `True`. **However**, notice that the next line – the `statement` line – is indendented. This is Python's way to define a *block of code*. \n", "\n", "A **block of code** means that we can run several lines of code _if_ the condition is True. As long as the code is indented then Python will treat it as code to run _only_ if the condition is True.\n", "\n", "Let's see a few examples. Run the following code cell and see if you can understand the output produced (given the code in the cell)." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "> Condition #1\n", "> Condition #3\n", " My var: 6\n", "Done.\n" ] } ], "source": [ "# Condition 1\n", "if 2 > 1:\n", " print(\"> Condition #1\")\n", " \n", "# Condition 2\n", "if 1 > 2: \n", " print(\"> Condition #2\")\n", " \n", "# Condition 3\n", "if \"Foo\" == \"Foo\":\n", " print(\"> Condition #3\")\n", " myVar = 1 + 5\n", " print(\" My var: \" + str(myVar))\n", " \n", "# Condition 4\n", "if \"Foo\" != \"Foo\":\n", " print(\"> Condition #4\")\n", " myVar = 1 + 5\n", " print(\" My var: \" + str(myVar))\n", " \n", "print(\"Done.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See how that works? Only conditions \\#1 and \\#3 were printed out, \\#2 and \\#4 were skipped over entirely!\n", "\n", "Let's take these in order:\n", "1. 2 _is_ greater than 1, so the `condition-to-check` returns True and Python then looks at the next line to see what it should do next.\n", "2. 1 _is not_ greater than 2, so the `condition-to-check` returns False. Python then skips the next _two_ indented lines which form part of the _code block_. It's the indentation that tells Python they're still part of the same code block. That _entire code block_ would only be executed _if_ the `condition-to-check` had been True.\n", "3. \"Foo\" is the same as \"Foo\", so this condition is True. Python then runs the next three lines because the indentation tells Python that they are all part of the same code block. Notice that we can even do things like set new variables in a code block.\n", "4. \"Foo\" is _still_ the same as \"Foo\", but we were testing if they were _not equal_ (`!=`) and so this condition is False. This time Python skips over the three lines and moves straight to the last print statement.\n", "5. Notice that the last print (`\"Done.\"`) always runs, no matter what the previous conditions were, because it is _not indented_ and so is not part of a _code block_.\n", "\n", "Let's see another example (run the code and check you understand the result)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "london_population = 8600000\n", "paris_population = 2200000 \n", "\n", "if london_population > paris_population:\n", " print(\"London is larger than Paris\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note: Other languages such as C/C++ use curly braces `{...}` around a block, just in case you find other languages in examples when Googling for help.\n", "\n", "Sidenote: How much should you indent? Although the [official specification](https://www.python.org/dev/peps/pep-0008/#tabs-or-spaces) specifies *4 spaces*, quite a few people indent using *one tab* instead. Technically, there is no difference _as long as you are consistent_ (See [this discussion](http://stackoverflow.com/questions/1125653/python-4-whitespaces-indention-why)). This apparently trivial issue is the sort of thing that leads to all kinds of heated argument (like whether you prefer Mac OSX or Windows; OSX is better, obviously). It's such a famous aspect of the programming world that it even featured in an episode of the sit-com [Silicon Valley](https://en.wikipedia.org/wiki/Silicon_Valley_(TV_series)): \n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### A challenge for you!\n", "\n", "Think about what the following code will print, _before_ running it:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "london_population = 8600000\n", "\n", "if london_population > 2000000:\n", " print(str(london_population) + \" is more than 2 million people\")\n", "\n", "if london_population < 10000000:\n", " print(str(london_population) + \" is less than 10 million people\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Complete the missing code, while also fixing the broken bits (_HINT:_ Remember the position of colons and indentation is important in Python!):" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden", "solution2_first": true }, "outputs": [], "source": [ "if (london_population % 8000000) == 600000 ???\n", "print(\"Good job\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden" }, "outputs": [], "source": [ "if (london_population % 8000000) == 600000:\n", " print(\"Good job\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ELSE condition\n", "\n", "Of course, only being able to use _if_ would be pretty limiting. Wouldn't it be handy to be able to say \"_if_ x is True: do one thing; otherwise do something else\". Well you can! When you want to run a different block of code depending on whether something is True or not, then you can use the `else` statement (_only_ following a first `if`).\n", "\n", "Here's an example:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "newyork_population = 8400000 \n", "\n", "if london_population < newyork_population:\n", " largest_city = \"New York\" \n", "else:\n", " largest_city = \"London\"\n", " \n", "print(\"The largest city is \" + largest_city)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see from the example above, the `if: else:` statement allows us to account for multiple outcomes when checking the _logic_ of a condition.\n", "\n", "Notice how the `else` syntax is similar to the `if` statement: use the colon, and indent.\n", "\n", "Also pay attention to the fact that not *all* of our code has run. Only the block after the `else` was run. So:\n", "- _if_ returned False (London's population is not less than that of New York)\n", "- So the _else_ block ran instead.\n", "\n", "This is why the `largestCity` variable was set to \"London\" and not \"New York\". After the `if: else:` sequence the code goes back to its normal flow, and all the remaining lines will be executed.\n", "\n", "The `if: else:` statement is like a fork in the road: you can take one road, or the other, but not both at the same time." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### A challenge for you!\n", "\n", "Fix the code below so that it prints out `London's population is above my threshold`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden", "solution2_first": true }, "outputs": [], "source": [ "mythreshold = 1000000\n", "if london_population <= mythreshold ???\n", " print(\"London's population is below my threshold\")\n", "???:\n", " print(\"London's popuation is above my threshold\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden" }, "outputs": [], "source": [ "mythreshold = 1000000\n", "if london_population <= mythreshold:\n", " print(\"London's population is below my threshold\")\n", "else:\n", " print(\"London's popuation is above my threshold\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ELIF condition\n", "\n", "Once again: so far, so good. But what if you need to have multiple forks? Well, then you can use a sequence of *statements* that sounds like \"IF this happens do this, ELSE IF this second condition holds do that, ELSE IF a third condition is true perform this other ELSE do finally this...\"\n", "\n", "The operator we are going to use is `elif`, the lazy version of `ELSE IF`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Like so:\n", "myUpperBoundary = 12000000\n", "myLowerBoundary = 2000000\n", "\n", "if london_population < myUpperBoundary:\n", " print(\"London is below my upper threshold.\")\n", "\n", "elif london_population > myLowerBoundary:\n", " print(\"London is above my lower threshold.\")\n", "\n", "elif london_population != 340000: \n", " print(\"London population is not equal to 340,000.\")\n", " \n", "else:\n", " print(\"How did I get here?\")\n", " \n", "print(\"And now back to normal code execution.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Why didn't the output look like this:\n", "
\n",
    "London is below my upper threshold.\n",
    "London population is not equal to 340,000.\n",
    "How did I get here?\n",
    "And now back to normal code execution.\n",
    "
\n", "\n", "This a tricky one: the _first_ thing that evaluates to `True` (that London is below the upper threshold) is the one that 'wins'. Computers are also lazy in their own way: since it found that the answer to the first `elif` was True it didn't bother to look at the second `elif` and the `else`, it _only_ ran the _one_ code block." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### A challenge for you!\n", "\n", "Complete the missing bits so that the logically correct print statement is output:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden", "solution2_first": true }, "outputs": [], "source": [ "london_population = 10\n", "??? london_population <= 9:\n", " print(\"First case is true\")\n", "??? london_population > 99: \n", " print(\"Second case is true\")\n", "??? london_population == 4:\n", " print(\"Third case is true\")\n", "??? print(\"Well, looks like none of the above statements were true!\")\n", "\n", "print(\"And now back to normal code execution.\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden" }, "outputs": [], "source": [ "london_population = 10\n", "if london_population <= 9:\n", " print(\"First case is true\")\n", "elif london_population > 99: \n", " print(\"Second case is true\")\n", "elif london_population == 4:\n", " print(\"Third case is true\")\n", "else: print(\"Well, looks like none of the above statements were true!\")\n", "\n", "print(\"And now back to normal code execution.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Boolean Logic\n", "----\n", "\n", "The very logical Prof. George Boole, circa 1860:\n", "\n", "![Photo of Boole](https://upload.wikimedia.org/wikipedia/commons/c/ce/George_Boole_color.jpg \"Boole\")\n", "\n", "Boolean logic and [Boolean algebra](https://en.wikipedia.org/wiki/Boolean_algebra) have to do with _set theory_ but also lie at the heart of the modern computer! Remember that in notebook 1 we saw that a computer works by combining `AND`, `OR`, `XOR` and `NAND` circuits to produce ever more complex calculations? Well, we also use this a lot in programming!\n", "\n", "In Python there are [three boolean logic opertors](https://docs.python.org/2/library/stdtypes.html#boolean-operations-and-or-not), these are (in ascending order of priority): `or`, `and`, and `not`.\n", "\n", "We'll look at these in more detail in a second, but here's the 'cheat sheet':\n", "- OR: _if either A OR B are True_ then run the following code block...\n", "- AND: _if A AND B are True_ then run the following code block...\n", "- NOT: _if NOT(A) is True_ (where A is _False_) then run the following code block...\n", "\n", "It might help you to take a look at these Venn diagrams (source: [Wikimedia Commons](https://en.wikipedia.org/wiki/File:Vennandornot.svg)) that express the same three operations in graphical form. Imagine that _x_ and _y_ are both `conditions-to-test`... The left one is _AND_ because it is only the combination of _x AND y_ that is red; the centre one is _OR_ because it represents any combination of _x OR y_ being red; the rightmost is _NOT_ because it is the opposite of _x_ that iss red.\n", "\n", "![Venn](https://upload.wikimedia.org/wikipedia/commons/thumb/a/ae/Vennandornot.svg/640px-Vennandornot.svg.png \"Venn Diagram\")\n", "\n", "OK, let's look at it in Python.\n", "\n", "## AND \n", "\n", "The `and` operator (just like in plain English!) is used when two conditions must both be True at the same time. So it has _two_ arguments and returns `True` if, and only if, both of them are `True`. Otherwise it returns `False`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "condition1 = 2 < 4 # True\n", "condition2 = (6/3) == 2 # Also True\n", "\n", "if (condition1) and (condition2): # Both are true\n", " print(\"1. Both conditions are true!\")\n", "else:\n", " print(\"1. Mmm... something's wrong!\")\n", " \n", "if condition1 and 6.0/5 == 1:\n", " print(\"2. Both conditions are true!\")\n", "else:\n", " print(\"2. Mmm... something's wrong!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## OR \n", "\n", "The `or` operator is used when we don't care which condition is True, as long as one of them is! So if *either* (or *both*!) conditions are `True`, then the operator returns `True`. Only if _both_ are `False` does it evalute to `False`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "condition1 = 2 < 4 # True\n", "condition2 = (6/3) != 2 # False\n", "\n", "if (condition1) or (condition2):\n", " print(\"1. Both conditions are true!\")\n", "else:\n", " print(\"1. Mmm... something's wrong!\")\n", "\n", "if 2 > 4 and 6.0/5 == 1:\n", " print(\"2. Both conditions are true!\")\n", "else:\n", " print(\"2. Mmm... something's wrong!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### A challenge for you!\n", "\n", "Try to change the values of conditions and see the different outcomes, but first you'll need to fix the Syntax Errors and the Exceptions!" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden", "solution2_first": true }, "outputs": [], "source": [ "condition1 = 2 < 4\n", "condition2 ??? (6/3) != 2\n", "\n", "if (condition1) ??? (condition2):\n", " print(\"Either one or two conditions are true!\")\n", "elif:\n", "print(\"mmh..they must both be false\"\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden" }, "outputs": [], "source": [ "condition1 = 2 < 4\n", "condition2 = (6/3) != 2\n", "\n", "if (condition1) or (condition2):\n", " print(\"Either one or two conditions are true!\")\n", "else:\n", " print(\"mmh..they must both be false\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## NOT \n", "\n", "Lastly, the `not` operator allows you to reverse (or invert, if you prefer) the value of a Boolean. So it turns a `True` into a `False` and vice-versa." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Like so:\n", "conditionInverted = not (2 == 2) # not turns True into False\n", "print(conditionInverted)\n", "\n", "# And:\n", "conditionInverted = not (\"Foo\" == \"Bar\") # not turns False into True\n", "print(conditionInverted)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### A challenge for you!\n", "\n", "Can you guess the result of this code _before_ you run it?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "if not conditionInverted:\n", " print(\"I'm True\")\n", "elif not (4%3 != 1):\n", " print(\"2\")\n", "else:\n", " print(\"99\" == str(99)+1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Code (Applied Geo-Example)\n", "---\n", "\n", "The aim of the excercise is to build a program that allows a user to choose a given London borough from a list, and get in return both its total population and a link to a OpenStreetMap that pin points its location.\n", "\n", "We are going to introduce a function called `input` that, as the name implies, takes an input from the user (interactively, that is!). We'll use it to interact with the user of our program. The input is going to be saved in a variable called `user_input`.\n", "\n", "I've provided a basic scaffolding of the code. It covers the case where the user choses the City borough, or provides an invalid input. Complete the script so that the three other boroughs can be found by the user.\n", "\n", "HINT: You will need to use `elif` statements to check for the various cases that use user might input.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden", "solution2_first": true }, "outputs": [], "source": [ "# variable with the City borough's total population (in thousands)\n", "city_of_London = 7.375\n", "# City borough's map marker\n", "city_coords = \"http://www.openstreetmap.org/?mlat=51.5151&mlon=-0.0933#map=14/51.5151/-0.0933\"\n", "\n", "# Other boroughs\n", "# camden = 220.338\n", "# camden_coords = \"http://www.openstreetmap.org/?mlat=51.5424&mlon=-0.2252#map=12/51.5424/-0.2252\"\n", "# hackney = 246.270\n", "# hackney_coords = \"http://www.openstreetmap.org/?mlat=51.5432&mlon=-0.0709#map=13/51.5432/-0.0709\"\n", "# lambeth = 303.086\n", "# lambeth_coords = http://www.openstreetmap.org/?mlat=51.5013&mlon=-0.1172#map=13/51.5013/-0.1172\n", "\n", "# Let's ask the user for some input\n", "# and store his answer\n", "user_input = input(\"\"\"\n", "Choose a neighbourhood by type the corresponding number:\n", "1- City of London\n", "2- Lambeth\n", "3- Camden\n", "4- Hackney\n", "\"\"\")\n", "\n", "# Arbitrarily assign case 1 to City of London borough\n", "\n", "if (user_input == '1'): \n", " choosen_borough = city_of_London\n", " borough_coordinates = city_coords \n", " # print the output\n", " # notice we are casting the user answer to string\n", " print(\"You have choosen number : \"+ str(user_input))\n", " print(\"The corresponding borough has a population of \"+ str(choosen_borough) +\" thousand people\")\n", " print(\"Visit the borough clicking here: \" + borough_coordinates)\n", " # ---------------\n", " # add more cases here...\n", " # ---------------\n", "else:\n", " print(\"That's not in my system. Please try again!\")\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden" }, "outputs": [], "source": [ "# variable with the City borough's total population (in thousands)\n", "city_of_London = 7.375\n", "# City borough's map marker\n", "city_coords = \"http://www.openstreetmap.org/?mlat=51.5151&mlon=-0.0933#map=14/51.5151/-0.0933\"\n", "\n", "# Other boroughs\n", "camden = 220.338\n", "camden_coords = \"http://www.openstreetmap.org/?mlat=51.5424&mlon=-0.2252#map=12/51.5424/-0.2252\"\n", "hackney = 246.270\n", "hackney_coords = \"http://www.openstreetmap.org/?mlat=51.5432&mlon=-0.0709#map=13/51.5432/-0.0709\"\n", "lambeth = 303.086\n", "lambeth_coords = \"http://www.openstreetmap.org/?mlat=51.5013&mlon=-0.1172#map=13/51.5013/-0.1172\"\n", "\n", "# Let's ask the user for some input\n", "# and store his answer\n", "user_input = input(\"\"\"\n", "Choose a neighbourhood by type the corresponding number:\n", "1- City of London\n", "2- Lambeth\n", "3- Camden\n", "4- Hackney\n", "\"\"\")\n", "\n", "# Arbitrarily assign case 1 to City of London borough\n", "\n", "if (user_input == '1'): \n", " choosen_borough = city_of_London\n", " borough_coordinates = city_coords \n", " # print the output\n", " # notice we are casting the user answer to string\n", " print(\"You have choosen number : \"+ str(user_input))\n", " print(\"The corresponding borough has a population of \"+ str(choosen_borough) +\" thousand people\")\n", " print(\"Visit the borough clicking here: \" + borough_coordinates)\n", "elif(user_input == '2'): \n", " choosen_borough = lambeth\n", " borough_coordinates = lambeth_coords \n", " # print the output\n", " # notice we are casting the user answer to string\n", " print(\"You have choosen number : \"+ str(user_input))\n", " print(\"The corresponding borough has a population of \"+ str(choosen_borough) +\" thousand people\")\n", " print(\"Visit the borough clicking here: \" + borough_coordinates)\n", "elif(user_input == '3'): \n", " choosen_borough = camden\n", " borough_coordinates = camden_coords \n", " # print the output\n", " # notice we are casting the user answer to string\n", " print(\"You have choosen number : \"+ str(user_input))\n", " print(\"The corresponding borough has a population of \"+ str(choosen_borough) +\" thousand people\")\n", " print(\"Visit the borough clicking here: \" + borough_coordinates)\n", "elif(user_input == '4'): \n", " choosen_borough = hackney\n", " borough_coordinates = hackney_coords \n", " # print the output\n", " # notice we are casting the user answer to string\n", " print(\"You have choosen number : \"+ str(user_input))\n", " print(\"The corresponding borough has a population of \"+ str(choosen_borough) +\" thousand people\")\n", " print(\"Visit the borough clicking here: \" + borough_coordinates) \n", " \n", "else:\n", " print(\"That's not in my system. Please try again!\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Credits!\n", "\n", "#### Contributors:\n", "The following individuals have contributed to these teaching materials: \n", "- [James Millington](https://github.com/jamesdamillington)\n", "- [Jon Reades](https://github.com/jreades)\n", "- [Michele Ferretti](https://github.com/miccferr)\n", "- [Zahratu Shabrina](https://github.com/zarashabrina)\n", "\n", "#### License\n", "The content and structure of this teaching project itself is licensed under the [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 license](https://creativecommons.org/licenses/by-nc-sa/4.0/) , and the contributing source code is licensed under [The MIT License](https://opensource.org/licenses/mit-license.php).\n", "\n", "#### Acknowledgements:\n", "Supported by the [Royal Geographical Society](https://www.rgs.org/HomePage.htm) (with the Institute of British Geographers) with a Ray Y Gildea Jr Award.\n", "\n", "#### Potential Dependencies:\n", "This notebook may depend on the following libraries: None" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.10.12" } }, "nbformat": 4, "nbformat_minor": 4 }