{ "cells": [ { "cell_type": "markdown", "id": "dbd5aa33", "metadata": {}, "source": [ "--- \n", " \n", "\n", "

Department of Data Science

\n", "

Course: Tools and Techniques for Data Science

\n", "\n", "---\n", "

Instructor: Muhammad Arif Butt, Ph.D.

" ] }, { "cell_type": "markdown", "id": "04d0e813", "metadata": {}, "source": [ "

Lecture 2.9

" ] }, { "cell_type": "markdown", "id": "b4bce6fd", "metadata": {}, "source": [ "\"Open" ] }, { "cell_type": "markdown", "id": "c0ed614c", "metadata": {}, "source": [ "## _if-else.ipynb_" ] }, { "cell_type": "markdown", "id": "85ce601a", "metadata": {}, "source": [ "## Learning agenda of this notebook\n", "There are scenarios is programming, where we need to make a decision and based on that decision we want the flow of execution to move to one block of code or the other. In Python this decision making is done using `if...else` statements.\n", "1. Python Indentation\n", "2. Branching with `if`, `else`, and `elif`\n", " - `if` statement\n", " - `if...else` statement\n", " - Ternary operator\n", " - Nested `if...else` statement\n", " - Ladder of `if...elif...else`\n", "3. The `pass` statement" ] }, { "cell_type": "markdown", "id": "f1e3dcfe", "metadata": {}, "source": [ "## 1. Python Expression, Statements and Indentation\n", "\n", "> **Expressions and Statements**: An expression is some code that evaluates to a value. As a rule of thumb, an expression is anything that can appear on the right side of the assignment operator `=`. On the contrary a statement is an instruction that can be executed. \n", "\n", "> **Python Indentation**:\n", ">- Most programming languages like C, C++, Java use braces { } to define a block of code. \n", ">- Python use indentation to tell the interpreter that the group of statements belongs to a particular block of code. \n", ">- Whitespace is used for indentation in Python. All statements with the same distance to the right belong to the same block of code. If a block has to be more deeply nested, it is simply indented further to the right. \n", ">- Python uses 4 spaces as indentation by default. However, the number of spaces is up to you, but a minimum of 1 space has to be used. \n", ">- Pressing `Tab` in a Jupyter notebook cell, will indent the code by 4 spaces, and pressing `Shift+Tab` will reduce the indentation by 4 spaces. " ] }, { "cell_type": "code", "execution_count": 1, "id": "56fdda25", "metadata": {}, "outputs": [ { "ename": "IndentationError", "evalue": "unexpected indent (3710409203.py, line 2)", "output_type": "error", "traceback": [ "\u001b[0;36m File \u001b[0;32m\"/var/folders/1t/g3ylw8h50cjdqmk5d6jh1qmm0000gn/T/ipykernel_28197/3710409203.py\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m b = 6 # Giving an extra extra space without the need of a block will flag an error\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m unexpected indent\n" ] } ], "source": [ "a = 5\n", " b = 6 # Giving an extra extra space without the need of a block will flag an error" ] }, { "cell_type": "code", "execution_count": 3, "id": "411afb08", "metadata": {}, "outputs": [ { "ename": "SyntaxError", "evalue": "invalid syntax (1217326361.py, line 1)", "output_type": "error", "traceback": [ "\u001b[0;36m File \u001b[0;32m\"/var/folders/1t/g3ylw8h50cjdqmk5d6jh1qmm0000gn/T/ipykernel_29767/1217326361.py\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m if (2 == 2)\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" ] } ], "source": [ "if (2 == 2)\n", "print('True Statement') # Not doing an indentation also flags an error" ] }, { "cell_type": "code", "execution_count": 12, "id": "e31827bd", "metadata": {}, "outputs": [], "source": [ "Arif_butt1 = 45" ] }, { "cell_type": "code", "execution_count": null, "id": "ae08eded", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "3773a242", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "3be400a2", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "c5cea553", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "3a39551f", "metadata": {}, "source": [ "## 2. Branching with `if`, `else` and `elif`\n", "One of the most powerful features of programming languages is *branching*: the ability to make decisions and execute a different set of statements based on whether one or more conditions are true." ] }, { "cell_type": "markdown", "id": "5f2e034e", "metadata": {}, "source": [ "### a. `if` Statement\n", " \n", "\n", "In Python, branching is implemented using the `if` statement, which is written as follows:\n", "\n", "```\n", "if condition:\n", " statement1\n", " statement2\n", "statement(s)\n", "```\n", "\n", "- The `condition` can be a value, variable or expression. \n", "- If the condition evaluates to `True`, then the statements within the *`if` block* are executed. \n", "- Notice the four spaces before `statement1`, and `statement2`, which inform Python interpreter that these statements are associated with the `if` statement above. \n", "- This technique of structuring code by adding spaces is called *indentation*.\n" ] }, { "cell_type": "code", "execution_count": 3, "id": "63b134c0", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The \"if\" statement\n", "******************\n", "\n", "The \"if\" statement is used for conditional execution:\n", "\n", " if_stmt ::= \"if\" assignment_expression \":\" suite\n", " (\"elif\" assignment_expression \":\" suite)*\n", " [\"else\" \":\" suite]\n", "\n", "It selects exactly one of the suites by evaluating the expressions one\n", "by one until one is found to be true (see section Boolean operations\n", "for the definition of true and false); then that suite is executed\n", "(and no other part of the \"if\" statement is executed or evaluated).\n", "If all expressions are false, the suite of the \"else\" clause, if\n", "present, is executed.\n", "\n", "Related help topics: TRUTHVALUE\n", "\n" ] } ], "source": [ "help('if')" ] }, { "cell_type": "code", "execution_count": 4, "id": "ecdea0c7", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Truth Value Testing\n", "*******************\n", "\n", "Any object can be tested for truth value, for use in an \"if\" or\n", "\"while\" condition or as operand of the Boolean operations below.\n", "\n", "By default, an object is considered true unless its class defines\n", "either a \"__bool__()\" method that returns \"False\" or a \"__len__()\"\n", "method that returns zero, when called with the object. [1] Here are\n", "most of the built-in objects considered false:\n", "\n", "* constants defined to be false: \"None\" and \"False\".\n", "\n", "* zero of any numeric type: \"0\", \"0.0\", \"0j\", \"Decimal(0)\",\n", " \"Fraction(0, 1)\"\n", "\n", "* empty sequences and collections: \"''\", \"()\", \"[]\", \"{}\", \"set()\",\n", " \"range(0)\"\n", "\n", "Operations and built-in functions that have a Boolean result always\n", "return \"0\" or \"False\" for false and \"1\" or \"True\" for true, unless\n", "otherwise stated. (Important exception: the Boolean operations \"or\"\n", "and \"and\" always return one of their operands.)\n", "\n", "Related help topics: if, while, and, or, not, BASICMETHODS\n", "\n" ] } ], "source": [ "help('TRUTHVALUE')" ] }, { "cell_type": "markdown", "id": "8c3cb597", "metadata": {}, "source": [ "In Python the following values evaluate to `False` (they are often called *falsy* values):\n", "1. The value `False` itself\n", "2. The integer `0`\n", "3. The float `0.0`\n", "4. The empty value `None` \n", "5. The empty text `\"\"`\n", "6. The empty list `[]`\n", "7. The empty tuple `()`\n", "8. The empty dictionary `{}`\n", "9. The empty set `set()`\n", "10. The empty range `range(0)`\n", "\n", "Everything else evaluates to `True` (a value that evaluates to `True` is often called a *truthy* value).\n", "\n", "The **None** type includes a single value `None`, used to indicate the absence of a value. `None` has the type `NoneType`. It is often used to declare a variable whose value may be assigned later or as a return value of functions that do not return a value" ] }, { "cell_type": "code", "execution_count": 5, "id": "3a5c1e7a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This will always execute\n" ] } ], "source": [ "# Example:\n", "x = 2\n", "if (x == 1): # you can put parenthesis around condition, but it is OK if you dont\n", " print('This will execute, only if the condition is true')\n", "print('This will always execute')" ] }, { "cell_type": "code", "execution_count": null, "id": "9561a5c4", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "59bdac9b", "metadata": {}, "source": [ "### b. `if...else` statement\n", " \n", "\n", "- The simple `if` statement shown above tells us that if a condition is True it will execute a block of statements and if the condition is False it won’t. \n", "- But what if we want to do something else if the condition is false. \n", "- Here comes the `else` statement. We can use the `else` statement with `if` statement to execute a block of code when the condition is False. It is written as follows:\n", "\n", "```\n", "if condition:\n", " statement1\n", " statement2\n", "else:\n", " statement3\n", " statement4\n", "remaining statement(s)\n", "```\n", "\n", "If `condition` evaluates to `True`, the statements in the `if` block are executed. If it evaluates to `False`, the statements in the `else` block are executed." ] }, { "cell_type": "code", "execution_count": 6, "id": "de994e5c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "enter a number: 5\n", "Odd\n", "Bye\n" ] } ], "source": [ "# Example 1: Take input from user by using the input function and decide if the number is even or odd\n", "x = input(\"enter a number: \")\n", "# by default the type returned by input() is string, so don't forget to type cast it\n", "x = int(x)\n", "if(x%2 == 0):\n", " print(\"Even\")\n", "else:\n", " print(\"Odd\")\n", "print(\"Bye\")" ] }, { "cell_type": "markdown", "id": "8226e32c", "metadata": {}, "source": [ "> The `input()` function allows a user to insert a value into a program. It returns a string value, which can be casted to any data type as per the requirement." ] }, { "cell_type": "code", "execution_count": 7, "id": "c8198dab", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a is smaller than b.\n", "i'm in else Block\n", "i'm neither in the if-block, nor in the else-block\n" ] } ], "source": [ "#Example 2:\n", "a = 5\n", "b = 10\n", "if (a > b):\n", " print('a is greater than b.')\n", " print (\"i'm in if Block\")\n", "\n", "else:\n", " print('a is smaller than b.')\n", " print (\"i'm in else Block\")\n", "print (\"i'm neither in the if-block, nor in the else-block\")\n" ] }, { "cell_type": "markdown", "id": "c42be9c2", "metadata": {}, "source": [ "### c. Python Ternary Opertor\n", "- The Python ternary operator is a type of conditional expression that evaluates a statement. \n", "- This is different from the `if..else` structure mentioned above, because it is not a control structure that directs the flow of program execution. It rather acts more like an operator that defines an expression.\n", "```\n", "rv = if else \n", "```" ] }, { "cell_type": "code", "execution_count": 1, "id": "9df530a4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'adult'" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Example 1: Let us assign a specific value to variable rv (adult or child), depending on a condition\n", "age = 19\n", "rv = 'adult' if age>= 18 else 'child'\n", "rv" ] }, { "cell_type": "code", "execution_count": null, "id": "300cb28b", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 9, "id": "a378d4b2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The number 3 is odd.\n" ] } ], "source": [ "# Example 2: Let us assign a specific value to variable parity (even or odd), depending on a condition\n", "a_number = 3\n", "parity = 'even' if a_number % 2 == 0 else 'odd'\n", "print('The number {} is {}.'.format(a_number, parity))" ] }, { "cell_type": "markdown", "id": "029e6291", "metadata": {}, "source": [ "### d. Nested `if...else` Statement\n", "Python allows us to nest `if` statements within `if` statements. i.e, we can place an if statement inside another if statement.\n", " " ] }, { "cell_type": "markdown", "id": "29d45c29", "metadata": {}, "source": [ "> The `input()` function allows a user to insert a value into a program. It returns a string value, which can be casted to any data type as per the requirement." ] }, { "cell_type": "code", "execution_count": 10, "id": "5a9faf7f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Please enter your age: 21\n", "Do you have National ID card? Y/N: y\n", "Welcome, you can vote\n" ] } ], "source": [ "# Example:\n", "age = float(input(\"Please enter your age: \"))\n", "if (age >= 18):\n", " rv = input(\"Do you have National ID card? Y/N: \")\n", " if ((rv == 'Y') or (rv == 'y')):\n", " print(\"Welcome, you can vote\")\n", " else:\n", " print(\"Since you donot have CNIC, so you cannot vote.\")\n", "else:\n", " print(\"You are too young to vote\")" ] }, { "cell_type": "markdown", "id": "0e3a37bb", "metadata": {}, "source": [ "> Nested `if`, `else` statements are often confusing to read and prone to human error. It's good to avoid nesting whenever possible, or limit the nesting to 1 or 2 levels." ] }, { "cell_type": "markdown", "id": "5e1ebc20", "metadata": {}, "source": [ "\n", "\n", "### e. Ladder of `if`...`elif`...`else` Statements\n", "\n", "- Python also provides an `elif` statement (short for \"else if\") to chain a series of conditional blocks. \n", "- The conditions are evaluated one by one from top to bottom. \n", "- For the first condition that evaluates to `True`, its associated block of statements is executed. \n", "- The remaining conditions and statements are not evaluated at all. \n", "- So, in an `if`, `elif`, `elif`... chain, at most one block of statements is executed, the one corresponding to the first condition that evaluates to `True`. " ] }, { "cell_type": "code", "execution_count": 11, "id": "5b7deacb", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Enter your subject marks: 87\n", "Letter Grade A\n" ] } ], "source": [ "# Example 1:\n", "y = input(\"Enter your subject marks: \")\n", "# by default the type is string, so we need to convert the type first\n", "y = int(y)\n", "if (y >= 85):\n", " print(\"Letter Grade A\")\n", "elif((y >= 80) and (y<85)):\n", " print(\"Letter Grade A-\")\n", "elif((y >= 77) and (y<80)):\n", " print(\"Letter Grade B+\")\n", "elif((y >= 73) and (y<77)):\n", " print(\"Letter Grade B\")\n", "else:\n", " print(\"Bad Grade\")" ] }, { "cell_type": "code", "execution_count": 12, "id": "476d5ee8", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "15 is divisible by 3\n" ] } ], "source": [ "# Example 2: Remember in an if-elif ladder at most one block of statements is executed\n", "a_number = 15\n", "if (a_number % 2 == 0):\n", " print('{} is divisible by 2'.format(a_number))\n", "elif a_number % 3 == 0:\n", " print('{} is divisible by 3'.format(a_number))\n", "elif a_number % 5 == 0:\n", " print('{} is divisible by 5'.format(a_number))\n", "elif a_number % 7 == 0:\n", " print('{} is divisible by 7'.format(a_number))" ] }, { "cell_type": "markdown", "id": "a27f3521", "metadata": {}, "source": [ ">- Note that the message `15 is divisible by 5` is not printed because the condition `a_number % 5 == 0` isn't evaluated, since the previous condition `a_number % 3 == 0` evaluates to `True`. \n", ">- This is the key difference between using a chain of `if`, `elif`, `elif`... statements vs. a chain of `if` statements, where each condition is evaluated independently.\n", ">- This is shown below" ] }, { "cell_type": "code", "execution_count": null, "id": "97bd9e5a", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 13, "id": "835ccec2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "15 is divisible by 3\n", "15 is divisible by 5\n" ] } ], "source": [ "# Example 3:\n", "a_number = 15\n", "if a_number % 2 == 0:\n", " print('{} is divisible by 2'.format(a_number))\n", "if a_number % 3 == 0:\n", " print('{} is divisible by 3'.format(a_number))\n", "if a_number % 5 == 0:\n", " print('{} is divisible by 5'.format(a_number))\n", "if a_number % 7 == 0:\n", " print('{} is divisible by 7'.format(a_number))" ] }, { "cell_type": "code", "execution_count": 14, "id": "6d11c2f1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All checks failed!\n", "73 is not divisible by 2, 3 or 5\n" ] } ], "source": [ "# Example 4: You can also include an `else` statement at the end of a chain of `if`, `elif`... statements. \n", "# This code within the `else` block is evaluated, when none of the conditions hold true.\n", "a_number = 73\n", "if a_number % 2 == 0:\n", " print('{} is divisible by 2'.format(a_number))\n", "elif a_number % 3 == 0:\n", " print('{} is divisible by 3'.format(a_number))\n", "elif a_number % 5 == 0:\n", " print('{} is divisible by 5'.format(a_number))\n", "else:\n", " print('All checks failed!')\n", " print('{} is not divisible by 2, 3 or 5'.format(a_number))" ] }, { "cell_type": "code", "execution_count": 15, "id": "10b0fbff", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The number 12 is not divisible by 5\n" ] } ], "source": [ "# Example 5: Conditions can also be combined using the logical operators `and`, `or` and `not`. \n", "a_number = 12\n", "if a_number % 3 == 0 and a_number % 5 == 0:\n", " print(\"The number {} is divisible by 3 and 5\".format(a_number))\n", "elif not a_number % 5 == 0:\n", " print(\"The number {} is not divisible by 5\".format(a_number))" ] }, { "cell_type": "markdown", "id": "5aa7fd27", "metadata": {}, "source": [ "## 3. The `pass` statement (Do nothing)\n", "The `pass` statement is generally used as a placeholder i.e. when the user does not know what code to write. So user simply places pass at that line. So user can simply place pass where empty code is not allowed, like in loops, function definitions, class definitions, or in if statements." ] }, { "cell_type": "code", "execution_count": 16, "id": "21fb029f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The \"pass\" statement\n", "********************\n", "\n", " pass_stmt ::= \"pass\"\n", "\n", "\"pass\" is a null operation — when it is executed, nothing happens. It\n", "is useful as a placeholder when a statement is required syntactically,\n", "but no code needs to be executed, for example:\n", "\n", " def f(arg): pass # a function that does nothing (yet)\n", "\n", " class C: pass # a class with no methods (yet)\n", "\n" ] } ], "source": [ "help('pass')" ] }, { "cell_type": "code", "execution_count": 17, "id": "3a631e5c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I will place code when the condition is true, later :)\n" ] } ], "source": [ "# A simple example of pass:\n", "x = 6\n", "if x < 0:\n", " pass\n", "print(\"I will place code when the condition is true, later :)\")" ] }, { "cell_type": "code", "execution_count": null, "id": "8c58ef44", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "57782dfd", "metadata": {}, "source": [ "## Check your Concepts\n", "\n", "Try answering the following questions to test your understanding of the topics covered in this notebook:\n", "\n", "1. What is branching in programming languages?\n", "2. What is the purpose of the `if` statement in Python?\n", "3. What is the syntax of the `if` statement? Give an example.\n", "4. What is indentation? Why is it used?\n", "5. What is an indented block of statements?\n", "6. How do you perform indentation in Python?\n", "7. What happens if some code is not indented correctly?\n", "8. What happens when the condition within the `if` statement evaluates to `True`? What happens if the condition evaluates for `false`?\n", "9. How do you check if a number is even?\n", "10. What is the purpose of the `else` statement in Python?\n", "11. What is the syntax of the `else` statement? Give an example.\n", "12. Write a program that prints different messages based on whether a number is positive or negative.\n", "13. Can the `else` statement be used without an `if` statement?\n", "14. What is the purpose of the `elif` statement in Python?\n", "15. What is the syntax of the `elif` statement? Give an example.\n", "16. Write a program that prints different messages for different months of the year.\n", "17. Write a program that uses `if`, `elif`, and `else` statements together.\n", "18. Can the `elif` statement be used without an `if` statement?\n", "19. Can the `elif` statement be used without an `else` statement?\n", "20. What is the difference between a chain of `if`, `elif`, `elif`… statements and a chain of `if`, `if`, `if`… statements? Give an example.\n", "21. Can non-boolean conditions be used with `if` statements? Give some examples.\n", "22. What are nested conditional statements? How are they useful?\n", "23. Give an example of nested conditional statements.\n", "24. Why is it advisable to avoid nested conditional statements?\n", "25. What is the shorthand `if` conditional expression? \n", "26. What is the syntax of the shorthand `if` conditional expression? Give an example.\n", "27. What is the difference between the shorthand `if` expression and the regular `if` statement?\n", "28. What is a statement in Python?\n", "29. What is an expression in Python?\n", "30. What is the difference between statements and expressions?\n", "31. Is every statement an expression? Give an example or counterexample.\n", "32. Is every expression a statement? Give an example or counterexample.\n", "33. What is the purpose of the pass statement in `if` blocks?\n", "34. Python does not have a switch or case statement. To get around this fact, one can use dictionary mapping. Try to implement code for this task.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "4a15eca1", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "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.9.7" } }, "nbformat": 4, "nbformat_minor": 5 }