+ "markdown": "# Mathematical and Logical Operators {#sec-calculator}\n\n\n## {{< fa bullseye >}} Objectives\n\n- Understand and use mathematical operators for mathematical computation\n- Understand and use logical operators to evaluate complex conditions\n- Understand and use basic string operations (repetition and concatenation)\n- Evaluate expressions using order of operations to predict how the computer will execute code\n- Translate mathematical concepts into a series of computational operations\n\n\n## Mathematical Operators\n\nLet's first start with a special class of functions that you're probably familiar with from your math classes - mathematical operators.\n\nHere are a few of the most important ones:\n\n| Operation | R symbol | Python symbol |\n|------------------|----------|---------------|\n| Addition | `+` | `+` |\n| Subtraction | `-` | `-` |\n| Multiplication | `*` | `*` |\n| Division | `/` | `/` |\n| Integer Division | `%/%` | `//` |\n| Modular Division | `%%` | `%` |\n| Exponentiation | `^` | `**` |\n\n: Mathematical operators in R and Python {#tbl-math-operators}\n\nThese operands are all for scalar operations (operations on a single number) - vectorized versions, such as matrix multiplication, are somewhat more complicated (and different between R and python).\n\n::: callout-caution\n\n### Example: Integer and Modular Division\n\nInteger division is the whole number answer to A/B, and modular division is the fractional remainder when A/B.\n\nLet's demonstrate with the problem 14/3, which evaluates to 4.6666667 when division is used, but has integer part 4 and remainder 2.\n\n::: panel-tabset\n\n### R {.unnumbered}\n\n`14 %/% 3` in R would be 4, and `14 %% 3` in R would be 2.\n\n::: {.cell}\n\n```{.r .cell-code}\n14 %/% 3\n## [1] 4\n14 %% 3\n## [1] 2\n```\n:::\n\n### Python {.unnumbered}\n\n::: {.cell}\n\n```{.python .cell-code}\n14 // 3\n## 4\n14 % 3\n## 2\n```\n:::\n\n:::\n\n:::\n\n## Order of Operations\n\nBoth R and Python operate under the same mathematical rules of precedence that you learned in school.\nYou may have learned the acronym PEMDAS, which stands for Parentheses, Exponents, Multiplication/Division, and Addition/Subtraction.\nThat is, when examining a set of mathematical operations, we evaluate parentheses first, then exponents, and then we do multiplication/division, and finally, we add and subtract.\n\n::: panel-tabset\n\n### R {.unnumbered}\n\n::: {.cell}\n\n```{.r .cell-code}\n(1+1)^(5-2) # <1>\n1 + 2^3 * 4 # <2>\n3*1^3 # <3>\n## [1] 8\n## [1] 33\n## [1] 3\n```\n:::\n1. The items in parentheses are evaluated first, so the expression becomes (2)^(3). Then, exponentiation is performed, yielding 8.\n2. Exponentiation is performed first (PEMDAS), so the expression becomes 1 + 8*4. Then multiplication is performed, yielding 1 + 32. Addition is the final step, so we get 33.\n3. Exponentiation is performed first, so this becomes 3*1. Then multiplication is performed, producing a final result of 3. \n\n### Python {.unnumbered}\n\n::: {.cell}\n\n```{.python .cell-code}\n(1+1)**(5-2) # <1>\n1 + 2**3*4 # <2>\n3*1**3 # <3>\n## 8\n## 33\n## 3\n```\n:::\n1. The items in parentheses are evaluated first, so the expression becomes (2)^(3). Then, exponentiation is performed, yielding 8.\n2. Exponentiation is performed first (PEMDAS), so the expression becomes 1 + 8*4. Then multiplication is performed, yielding 1 + 32. Addition is the final step, so we get 33.\n3. Exponentiation is performed first, so this becomes 3*1. Then multiplication is performed, producing a final result of 3. \n\n:::\n\n## Simple String Operations\n\nPython has some additional operators that work on strings.\nIn R, you will have to use functions to perform these operations, as R does not have string operators.\n\n::: callout-demo\n\n### String Operations in R and Python\n\n::: panel-tabset\n\n#### Python {.unnumbered}\n\nIn Python, `+` will **concatenate** (stick together) two strings.\nMultiplying a string by an integer will repeat the string the specified number of times.\n\n::: {.cell}\n\n```{.python .cell-code}\n\"first \" + \"second\"\n## 'first second'\n\"hello \" * 3\n## 'hello hello hello '\n```\n:::\n\n#### R {.unnumbered}\n\nIn R, to concatenate things, we need to use functions: `paste` or `paste0`:\n\n::: {.cell}\n\n```{.r .cell-code}\npaste(\"first\", \"second\", sep = \" \") # <1>\npaste(\"first\", \"second\", collapse = \" \")\npaste(c(\"first\", \"second\"), sep = \" \") # sep only works w/ 2 objects passed in\npaste(c(\"first\", \"second\"), collapse = \" \") # collapse works on vectors\n\npaste(c(\"a\", \"b\", \"c\", \"d\"), \n c(\"first\", \"second\", \"third\", \"fourth\"), \n sep = \"-\", collapse = \" \")\n# sep is used to collapse parameters, then collapse is used to collapse vectors\n\npaste0(c(\"a\", \"b\", \"c\"))\npaste0(\"a\", \"b\", \"c\") # equivalent to paste(..., sep = \"\")\n## [1] \"first second\"\n## [1] \"first second\"\n## [1] \"first\" \"second\"\n## [1] \"first second\"\n## [1] \"a-first b-second c-third d-fourth\"\n## [1] \"a\" \"b\" \"c\"\n## [1] \"abc\"\n```\n:::\n\nYou don't need to understand the details of this code at this point in the class, but it is useful to know how to combine strings in both languages.\n\n:::\n\n:::\n\n\n## Logical Operators {#sec-logical-ops}\n\nLogical variables can be combined through the use of logical operators in much the same way that numerical variables are combined through mathematical operators.\n\nThere are specific **logical operators** which are used to aggregate and combine multiple logical variables: the primary logical operators are `and`, `or`, and `not` [^xor].\n\n[^xor]: A fourth commonly used logical operator is **exclusive or** (`xor`). `xor` is True if only one of the two conditions is True, but False if both are True. `xor` is not a basic boolean operator, as it can be written as a combination of other operators: `A xor B = (A or B) and not(A and B)`.\n\nIn **pseudocode**, which is human-readable logic structured like computer code but without the syntax, we usually write these out in all caps. \n\n- (X AND Y) requires that both X and Y are true.\n- (X OR Y) requires that one of X or Y is true.\n- (NOT X) is true if X is false, and false if X is true. Sometimes called **negation**.\n- (X XOR Y) requires that one (and only one) of X or Y is true. Sometimes called **exclusive or**.\n\n::: {.callout-tip collapse=true}\n\n### Truth Tables: Useful Tools for Understanding Logical Expressions\n\nWhen constructing a logical expression that combines Boolean variables, it can be helpful to build a **truth table** that lists all possible inputs on the left and the output of the operator on the right. \nA truth table demonstrating the logical operators `and`, `or`, `not` and `xor` is provided in @tbl-truth-general.\n\n\na | b | a `and` b | a `or` b | `not` a | `not` b | a `xor` b\n-- | -- | -- | -- | -- | -- | --\nT | T | T | T | F | F | F\nT | F | F | T | F | T | T\nF | T | F | T | T | F | T \nF | F | F | F | T | T | F\n\n: Truth table for each of the common logical operators. {#tbl-truth-general}\n\n:::\n\nOperation | R | Python\n--- | --- | ---\nand | `&` | `&` or `and`\nor | `|` | `|` or `or`\nnot | `!` | `not`\nxor | `xor()` | `^`\n\n: Logical operators in R and Python. These operators are intended for single values; evaluation of vectors may require different operators. Note the use of `^` for `xor` in Python! {#tbl-log-operators}\n\n\nWhen writing code, we use the logical operators in R and Python shown in @tbl-log-operators.\n\n\n:::: {.callout-warning collapse=true}\n\n### Exploring Logical Operators with R and Python\n\nWe can generate each entry in the truth table using the relevant logical operators in R and python. \n\n::: panel-tabset\n\n#### AND\n\nIn R, `and` comparisons use `&` as the operator.\n\n::: {.cell}\n\n```{.r .cell-code}\n\nTRUE & TRUE\n## [1] TRUE\nTRUE & FALSE\n## [1] FALSE\nFALSE & TRUE\n## [1] FALSE\nFALSE & FALSE\n## [1] FALSE\n```\n:::\n\nIn Python, `and` expressions use `&` as the operator.\n\n::: {.cell}\n\n```{.python .cell-code}\nTrue & True\n## True\nTrue & False\n## False\nFalse & True\n## False\nFalse & False\n## False\n```\n:::\n\nAlternately, in Python, you can also spell out the whole word and use `and` explicitly. \n\n::: {.cell}\n\n```{.python .cell-code}\nTrue and True\n## True\nTrue and False\n## False\nFalse and True\n## False\nFalse and False\n## False\n```\n:::\n\n\n#### OR\n\nIn R, `or` is denoted with `|` (the vertical bar, shift + the button above the enter key on most keyboards). \n\n::: {.cell}\n\n```{.r .cell-code}\nTRUE | TRUE\n## [1] TRUE\nTRUE | FALSE\n## [1] TRUE\nFALSE | TRUE\n## [1] TRUE\nFALSE | FALSE\n## [1] FALSE\n```\n:::\n\nIn Python, `or` expressions use `|` as the operator.\n\n::: {.cell}\n\n```{.python .cell-code}\nTrue | True\n## True\nTrue | False\n## True\nFalse | True\n## True\nFalse | False\n## False\n```\n:::\n\nAlternately, in Python, you can also spell out the whole word and use `or` explicitly. \n\n::: {.cell}\n\n```{.python .cell-code}\nTrue or True\n## True\nTrue or False\n## True\nFalse or True\n## True\nFalse or False\n## False\n```\n:::\n\n\n#### NOT\n\nIn R, negation occurs using the `!` operator.\n\n::: {.cell}\n\n```{.r .cell-code}\n!TRUE\n## [1] FALSE\n!FALSE\n## [1] TRUE\n```\n:::\n\nIn Python, negation occurs using the `not` operator.\n\n::: {.cell}\n\n```{.python .cell-code}\nnot True\n## False\nnot False\n## True\n```\n:::\n\n#### XOR\n\nIn R, exclusive or uses the `xor()` function.\n\n::: {.cell}\n\n```{.r .cell-code}\nxor(TRUE, TRUE)\n## [1] FALSE\nxor(TRUE, FALSE)\n## [1] TRUE\nxor(FALSE, TRUE)\n## [1] TRUE\nxor(FALSE, FALSE)\n## [1] FALSE\n```\n:::\n\nIn Python, exclusive or uses the `^` operator.\n\n::: {.cell}\n\n```{.python .cell-code}\nTrue ^ True\n## False\nTrue ^ False\n## True\nFalse ^ True\n## True\nFalse ^ False\n## False\n```\n:::\n\nNote that this is why the exponentiation operator in Python is `**` instead of `^`. \nUsing `^` may produce errors (TypeError: unsupported operand type(s)) or may produce unexpected results with no warning at all, as in the following example. \n\n::: {.cell}\n\n```{.python .cell-code}\n3^4\n## 7\n```\n:::\n\n:::\n\n::::\n\n### Order of Operations\n\nJust as with mathematical operators, there is an order of operations to logical operators. \n\nPrecedence order: (top is evaluated first)\n\n- NOT \n- AND\n- OR\n\n\n::: panel-tabset\n\n#### R\n\n::: {.cell}\n\n```{.r .cell-code}\na1 <- TRUE\nb1 <- FALSE\nc1 <- FALSE\n\na1 | b1 & c1 # AND takes precedence\n## [1] TRUE\na1 | (b1 & c1) # same as above, with parentheses\n## [1] TRUE\n(a1 | b1) & c1 # force OR to be first using parentheses\n## [1] FALSE\n```\n:::\n\n#### Python\n\n::: {.cell}\n\n```{.python .cell-code}\na1 = True\nb1 = False\nc1 = False\n\na1 or b1 and c1 # AND takes precedence\n## True\na1 or (b1 and c1) # same as above, with parentheses\n## True\n(a1 or b1) and c1 # force OR to be first using parentheses\n## False\n```\n:::\n\n:::\n\n\n### De Morgan's Laws\n\n[De Morgan's Laws](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) are a set of rules for how to combine logical statements, similar to distributive laws in numerical operations. You can represent them in a number of ways:\n\n- NOT(A or B) is equivalent to NOT(A) and NOT(B)\n- NOT(A and B) is equivalent to NOT(A) or NOT(B)\n\n::: {.callout-tip collapse=true}\n\n#### Visual Representation of DeMorgan's Laws\n\nWe can also represent De Morgan's Laws visually using Venn Diagrams.\n\n\n\nWe will use the convention that .\n\n::: {.callout collapse=true}\n##### DeMorgan's First Law\n\n\n\n::: panel-tabset\n\n###### R\n\n::: {.cell}\n\n```{.r .cell-code}\n!(TRUE | TRUE)\n## [1] FALSE\n!(TRUE | FALSE)\n## [1] FALSE\n!(FALSE | TRUE)\n## [1] FALSE\n!(FALSE | FALSE)\n## [1] TRUE\n\n!TRUE & !TRUE\n## [1] FALSE\n!TRUE & !FALSE\n## [1] FALSE\n!FALSE & !TRUE\n## [1] FALSE\n!FALSE & !FALSE\n## [1] TRUE\n```\n:::\n\n###### Python\n\n::: {.cell}\n\n```{.python .cell-code}\nnot(True or True)\n## False\nnot(True or False)\n## False\nnot(False or True)\n## False\nnot(False or False)\n## True\n\nnot(True) and not(True)\n## False\nnot(True) and not(False)\n## False\nnot(False) and not(True)\n## False\nnot(False) and not(False)\n## True\n```\n:::\n\n:::\n\n:::\n\n\n::: {.callout collapse=true}\n\n##### DeMorgan's Second Law\n\n\n\n::: panel-tabset\n\n###### R\n\n::: {.cell}\n\n```{.r .cell-code}\n!(TRUE & TRUE)\n## [1] FALSE\n!(TRUE & FALSE)\n## [1] TRUE\n!(FALSE & TRUE)\n## [1] TRUE\n!(FALSE & FALSE)\n## [1] TRUE\n\n!TRUE | !TRUE\n## [1] FALSE\n!TRUE | !FALSE\n## [1] TRUE\n!FALSE | !TRUE\n## [1] TRUE\n!FALSE | !FALSE\n## [1] TRUE\n```\n:::\n\n###### Python\n::: {.cell}\n\n```{.python .cell-code}\nnot(True and True)\n## False\nnot(True and False)\n## True\nnot(False and True)\n## True\nnot(False and False)\n## True\n\nnot(True) or not(True)\n## False\nnot(True) or not(False)\n## True\nnot(False) or not(True)\n## True\nnot(False) or not(False)\n## True\n```\n:::\n\n:::\n\n:::\n\n:::\n",
0 commit comments