{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b156e5f4-db72-4fcd-9219-ff6c2d083215",
   "metadata": {},
   "source": [
    "# Boolean Expressions & Logical Operators\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "01d53491",
   "metadata": {},
   "source": "## Selection Statements\n\nSelection statements, sometimes referred to as conditional statements,\nare one of the three basic constructs (sequence, selection, iteration) in programming.\nSelection statements provide the logic to perform decision-making: taking different\nactions based on different conditions. When selecting from possible paths for execution,\nthe decisions are made based on the value of an expression.\n\nC# has the following conditional statements:\n\n- The `if` statement specifies a block of code to be executed, only if a provided Boolean\n  expression evaluates to `true`.\n- The `if-else` statement allows you to choose which of the two code paths to follow\n  based on a Boolean expression.\n- The `else if` statement specifies a new `condition` to `test`.\n- `switch` statement selects from a list of code to execute based on a pattern match with an expression.\n\nThe basic syntax for an if statement is:\n\n"
  },
  {
   "cell_type": "markdown",
   "id": "db38b155",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "source": [
    "```csharp\n",
    "if (condition)\n",
    "{\n",
    "    // block of code to be executed if the condition is true\n",
    "}\n",
    "```\n",
    "\n",
    "Here, `condition` is a **Boolean expression** — an expression that evaluates to either `true` or `false`. The parentheses around it are required syntax: they tell the compiler where the condition begins and ends, distinguishing it from the body of the `if` statement. This is different from parentheses in arithmetic expressions, where they are used to control the order of operations.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7cdb4dd7",
   "metadata": {},
   "source": "## Boolean Data Type\n\nThe condition in an `if` statement is a **Boolean expression** — also called a **relational expression**.\nEvery expression in C# produces a value, and the defining feature of a Boolean expression is that\nits value is always either `true` or `false` (think: Yes/No, On/Off, 1/0).\nThis two-state result is represented by C#'s `bool` type, whose only legal values are `true` and `false`.\n\nYou can quickly try `bool` variables in `csharprepl`:\n\n```text\n> bool isRollaQuiet = true;\n> bool isChicagoClose = false;\n> isRollaQuiet\ntrue\n> isChicagoClose\nfalse\n```\n\nFor a more complete example in VS Code, you can write a small program:\n\n```csharp\nnamespace Program\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            BooleanExpression.Rolla();\n        }\n    }\n\n    internal class BooleanExpression\n    {\n        internal static void Rolla()\n        {\n            bool isRollaQuiet = true;\n            bool isChicagoClose = false;\n            Console.WriteLine(isRollaQuiet);   // True\n            Console.WriteLine(isChicagoClose); // False\n        }\n    }\n}\n```\n\n:::{note}\n`BooleanExpression.Rolla()` is called as a static method on a separate class.\nThis is a preview of how static methods in one class can be called from another —\na pattern covered in depth later in the course.\n:::\n\nOutput:\n\n```console\nTrue\nFalse\n```"
  },
  {
   "cell_type": "markdown",
   "id": "5eaacf5b",
   "metadata": {},
   "source": "## Boolean Expressions\n\nTo drive decision-making in selection statements, Boolean expressions are typically\nbuilt using **comparison operators** (`==`, `!=`, `<`, `>`, `<=`, `>=`):\n\n| Operator | Name | Description |\n|----------|------|-------------|\n| `<` `>` `<=` `>=` | Relational | Compare numeric (and `char`) values; supported by all integral and floating-point types |\n| `==` | Equality | `true` when operands have the same value (value types) or refer to the same object (reference types) |\n| `!=` | Inequality | Opposite of `==` |\n\nExamples:\n\n```csharp\nConsole.WriteLine(7.0 < 5.1);   // False\nConsole.WriteLine(7.0 > 5.1);   // True\nConsole.WriteLine(7.0 <= 5.1);  // False\nConsole.WriteLine(7.0 >= 5.1);  // True\n\nint a = 1 + 2 + 3;\nint b = 6;\nConsole.WriteLine(a == b);      // True\n\nchar c1 = 'a';\nchar c2 = 'A';\nConsole.WriteLine(c1 == c2);    // False (different character codes)\n```\n\nReference types (classes) compare identity rather than value — two objects with identical\ncontents are *not* equal unless they are the same instance. This is illustrated below."
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6ea38ae4",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "public class ReferenceTypesEquality\n",
    "{\n",
    "public class MyClass\n",
    "{\n",
    "private int id;\n",
    "\n",
    "        public MyClass(int id) => this.id = id;\n",
    "    }\n",
    "\n",
    "    public static void Main()\n",
    "    {\n",
    "        var a = new MyClass(1);\n",
    "        var b = new MyClass(1);\n",
    "        var c = a;\n",
    "        Console.WriteLine(a == b);  // output: False\n",
    "        Console.WriteLine(a == c);  // output: True\n",
    "    }\n",
    "\n",
    "}\n",
    "\n",
    "\n",
    "    Understanding boolean expressions above should give you a good sense of how\n",
    "    conditional/select statement syntax works:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "beebc06c",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "    if (condition)\n",
    "    {\n",
    "      // block of code to be executed if the condition is True\n",
    "    }\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50cabf6e",
   "metadata": {},
   "source": [
    "You should know that the `condition` is a `Boolean expression`, which will evaluate to either `true` or\n",
    "`false`. The parentheses is a testing construct. If the testing construct results to\n",
    "`true`, then the code block follows will be executed. Otherwise, the code block\n",
    "follows will not be executed."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96ef9d16",
   "metadata": {},
   "source": [
    "```{index} boolean operator; &&\n",
    "```\n",
    "\n",
    "(compound-boolean-expressions)=\n",
    "\n",
    "## Compound Boolean Expressions\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "53a11c4a",
   "metadata": {},
   "source": "## Logical Operators\n\nTo be eligible to graduate from M S&T, you must\nhave 120 credits *and* a GPA of at least 2.0. C# does not use the\nword *and*. Instead it uses `&&` (inherited from the C language).\nThen, the requirement translates directly into C# as a *compound condition*\nusing the logical operator `&&`:\n\n```\ncredits >= 120 && GPA >=2.0\n```\n\nThis is true if both `credits >= 120` is true and `GPA >= 2.0`\nis true. A short example function using this would be:\n\n"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "77c92973",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "static void checkGraduation(int credits, double GPA)\n",
    "{\n",
    "   if (credits >= 120 && GPA >=2.0) {\n",
    "      Console.WriteLine(\"You are eligible to graduate!\");\n",
    "   }\n",
    "   else {\n",
    "      Console.WriteLine(\"You are not eligible to graduate.\");\n",
    "   }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bb82befb",
   "metadata": {},
   "source": [
    "\n",
    "The C# syntax for the logical operator `&&` is:\n",
    "\n",
    "> *condition1* `&&` *condition2*\n",
    "\n",
    "The compound condition is `true` if `both` of the component conditions\n",
    "are true. It is `false` if `at least one` of the conditions is false.\n",
    "\n",
    "Suppose we want a C# condition that is true in the same situations\n",
    "as the mathematical expression: low < val < high. Unfortunately the\n",
    "math is not a C# expression. The C# operator `<` is binary.\n",
    "In C#, the statement above is equivalent to\n",
    "\n",
    "> (low < val) < high\n",
    "\n",
    "comparing a Boolean result to high, and causing a compiler error.\n",
    "There is a C# version. Be sure to use this pattern:\n",
    "\n",
    "```\n",
    "low < val && val < high\n",
    "```\n",
    "\n",
    "```{index} boolean operator; ||\n",
    "```\n",
    "\n",
    "Now suppose we want the opposite condition: that val is *not*\n",
    "strictly between low and high.\n",
    "There are several approaches.\n",
    "One is that `val` would be less than or equal to low\n",
    "*or* greater than or equal to `high`. C# translate *or* into `||`,\n",
    "so a C# expression would be:\n",
    "\n",
    "> val \\<= low || val >= high\n",
    "\n",
    "The C# syntax for the logical operator `||` is:\n",
    "\n",
    "> *condition1* `||` *condition2*\n",
    "\n",
    "The compound condition is true if at least one of the component conditions\n",
    "are true. It is false if both conditions are false.\n",
    "\n",
    "```{index} boolean operator; !\n",
    "```\n",
    "\n",
    "Another logical way to express the opposite of the condition low < val < high\n",
    "is that it is *not* the case\n",
    "that low < val && val \\<< high. C# translates *not* as `!`. Another way\n",
    "to state the condition would be\n",
    "\n",
    "```\n",
    "!(low < val && val < high)\n",
    "```\n",
    "\n",
    "The parentheses are needed because the `!`\n",
    "operator has higher precedence than\n",
    "`<`.\n",
    "\n",
    "A way to remember this strange *not* operator is to think of the use of `!`\n",
    "in the not-equal operator: `!=`\n",
    "\n",
    "The C# syntax for the operator `!`:\n",
    "\n",
    "> `!` *condition*\n",
    "\n",
    "This whole expression is true when *condition* is false,\n",
    "and false when *condition* is true.\n",
    "\n",
    "Because of the precedence of `!`, you are often going to write:\n",
    "\n",
    "> `!(` *condition* `)`\n",
    "\n",
    "Remember when such a condition is used in an `if` statement, *outer*\n",
    "parentheses are also needed:\n",
    "\n",
    "> `if (!(` *condition* `)) {`\n",
    "\n",
    "Note that `!` has the high precedence of unary arithmetic operators.\n",
    "The operators `&&` and `||` are almost at the bottom of the operators\n",
    "considered in this book, just above the assignment operators, and below the\n",
    "relational operators, with `&&` above `||`. You are encourages to use\n",
    "parentheses to make sure.\n",
    "\n",
    "**Compound Overkill**: Look back to the code converting a score to a letter\n",
    "grade in the LetterGrade2 ({ref}`else-if-cases`) method, the condition before assigning the B\n",
    "grade could have been:\n",
    "\n",
    "```\n",
    "(score >= 80 && score < 90)\n",
    "```\n",
    "\n",
    "That would have totally nailed the condition, but it is overly verbose in the\n",
    "`if` .. `else if` ... code where it appeared. Since you only get\n",
    "to consider a B as a grade if the grade was *not* already\n",
    "set to A, the second part of the compound condition above is redundant.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c1263e5e",
   "metadata": {},
   "source": "## Compound test conditions\n\nConsider a different situation: Steven Covey suggested that people classify\npossible actions on two axes: urgent vs. not urgent and important vs. not\nimportant, leading to four possible combinations.\nWe could ask a person to classify an activity this way, and them give a\nprocess comment, something like from Covey's book:\n\n- Important and urgent: Be sure to schedule this promptly!\n- Important and not urgent: Make sure that this is included regularly in your\n  plans! Do not let urgent but unimportant things interfere!\n- Not important and urgent: Can you skip this, or is it really worth\n  letting this displace important things you need to do?\n- Not important and not urgent: Is there anything more worthwhile\n  for you to do now?\n\nAssume we have Boolean variables `important` and `urgent`.\nThere are four separate combinations, and we could handle this with a\nchain of compound conditions checking for one at a time:\n\n"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7fc24d2c",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "if (important && urgent) {\n",
    "   Console.WriteLine(\"Be sure ...\");\n",
    "}\n",
    "else if (important && !urgent) {\n",
    "   Console.WriteLine(\"Make sure ...\");\n",
    "}\n",
    "else if (!important && urgent) {\n",
    "   Console.WriteLine(\"Can you...\");\n",
    "}\n",
    "else {\n",
    "   Console.WriteLine(\"Is there ...\");\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d150be3b",
   "metadata": {},
   "source": [
    "\n",
    "Compound test conditions are not necessary if we keep track of partial\n",
    "answers by nesting `if` statements. Consider the two aspects separately\n",
    "using an if-else statement with nested if-else sub-statements:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8aa12c93",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "if (important) {\n",
    "   if (urgent) {\n",
    "      Console.WriteLine(\"Be sure ...\");\n",
    "   }\n",
    "   else {\n",
    "      Console.WriteLine(\"Make sure ...\");\n",
    "   }\n",
    "}\n",
    "else {\n",
    "   if (urgent) {\n",
    "      Console.WriteLine(\"Can you...\");\n",
    "   }\n",
    "   else {\n",
    "      Console.WriteLine(\"Is there ...\");\n",
    "   }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c5cb07e6",
   "metadata": {},
   "source": [
    "\n",
    "The outer {{ if_else }} determines whether the action is important, so the inner\n",
    "conditions only need to deal with urgency. Also note that in executing\n",
    "this version there are never more than two short conditions evaluated.\n",
    "In the first version, you may have to go through all three conditions.\n",
    "Both approaches work. Which is clearer to you?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "footnotes",
   "metadata": {},
   "source": [
    "```{rubric} Footnotes\n",
    "```\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".NET (C#)",
   "language": "C#",
   "name": ".net-csharp"
  },
  "language_info": {
   "name": "csharp"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}