class: middle, center # Lecture 4 ### 2 September 2024 **Admin Matters**
Unit 8: **Conditionals**
Unit 9: **Logical Expression**
Unit 10: **Assertion**
--- ### Midterm and PE - PE dates confirmed (PE0 on 1 October) - Midterm date changed to 7 October (Report at 4:30 PM. Released 6:15 PM) --- ### Exercises - Exercise 0 due tonight - Exercise 1 released today --- class: middle,wide .fit[![max](../notes/figures/max-flowchart/max-flowchart-pdf-0.png)] --- class: middle,wide .fit[![factorial](../notes/figures/max-flowchart/max-flowchart-pdf-9.png)] --- .smaller[ ```C if (<logical expression>) { // "true block" // statements to be executed if the expression // evaluates to true } else { // "false block" // statements to be executed if the expression // evaluates to false } ``` ] --- ```C long factorial(long n) { long answer; if (n == 0) { answer = 1; } else { answer = n * factorial(n - 1); } return answer; } ``` --- class: center ### Comparison Operator `==` `!=` `>=` `<=` `<` `>` --- | Score | Letter Grade | | --------------------------- | ------------ | | 8 or higher | A | | Less than 8 but 5 or higher | B | | Less than 5 but 3 or higher | C | | Less than 3 | D | --- ### Break into Smaller Tables | Score | Letter Grade | | ----------- | ------------ | | 8 or higher | A | | Less than 8 | See Table 1 | --- ### Table 1 (less than 8) | Score | Letter Grade | | ----------- | ------------ | | 5 or higher | B | | Less than 5 | See Table 2 | --- ### Table 2 (less than 5) | Score | Letter Grade | | ----------- | ------------ | | 3 or higher | C | | Less than 3 | D | --- class: middle,wide .fit[![score](../notes/figures/max-flowchart/max-flowchart-pdf-18.png)] --- class: top,wide .smaller[ ```C void print_score(double score) { if (score >= 8) { cs1010_println_string("A"); } else { // See Table 1 } } ``` ] --- class: top,wide .smaller[ ```C void print_score(double score) { if (score >= 8) { cs1010_println_string("A"); } else { if (score >= 5) { cs1010_println_string("B"); } else { // See Table 2 } } } ``` ] --- class: top,wide .smaller[ ```C void print_score(double score) { if (score >= 8) { cs1010_println_string("A"); } else { if (score >= 5) { cs1010_println_string("B"); } else { if (score >= 3) { cs1010_println_string("C"); } else { cs1010_println_string("D"); } } } } ``` ] --- class: top,wide .smaller[ ```C void print_score(double score) { if (score >= 8) { cs1010_println_string("A"); } else if (score >= 5) { cs1010_println_string("B"); } else if (score >= 3) { cs1010_println_string("C"); } else { cs1010_println_string("D"); } } ``` ] --- .smaller[ ```C if (<logical expression>) { // "true block" // statements to be executed if the expression // evaluates to true } else { // nothing to do.. } ``` ] can be simplified to: .smaller[ ```C if (<logical expression>) { // "true block" // statements to be executed if the expression // evaluates to true } ``` ] --- class: middle,wide .fit[![max](../notes/figures/max-flowchart/max-flowchart-pdf-0.png)] --- class: middle,wide,center ### Another Example Finds the larger of two numbers $x$ and $y$. --- ```C // set max to the larger of x and y if (x > y) { max = x; } if (x < y) { max = y; } ``` --- ```C // set max to the larger of x and y if (x > y) { max = x; } if (x < y) { max = y; } if (x == y) { max = y; } ``` --- class: middle,wide .fit[![score](../notes/figures/max-flowchart/max-flowchart-pdf-21.png)] --- ```C // set max to the larger of x and y if (x > y) { max = x; } else { max = y; } ``` --- ```C long factorial(long n) { long answer; if (n == 0) { answer = 1; } else { answer = n * factorial(n - 1); } return answer; } ``` --- ```C long factorial(long n) { if (n == 0) { return 1; } else { return n * factorial(n - 1); } } ``` --- ```C long factorial(long n) { if (n == 0) { return 1; } return n * factorial(n - 1); } ``` --- class: middle,center .fit[![meme](figures/meme/bad-good-return-else.png)] --- ### Good Practices (so far) - Use `else if` to make the code concise - Make sure your code flow covers all possibilities - Don't check for a condition that is always true - No `else` after `return`. --- class: middle,center ### Common Pitfalls --- class: wide What will get printed if `score` is 5? .small[ ```C if (score >= 8) if (late_penalty != 0) cs1010_println_string("late submission"); else cs1010_println_string("you can do better!"); ``` ] --- class: middle,center .fit[![meme](figures/meme/bad-good-curly.png)] --- ```C double sum = 0.3 + 0.6; if (sum == 0.9) { : } ``` --- ```C double sum = 0.3 + 0.6; if (fabs(sum - 0.9) < 0.0000001) { : } ``` --- class: middle,center .fit[![meme](figures/meme/bad-good-fp-equal.png)] --- class: middle ### The `bool` data type ```C #include
: bool is_found = false; // or true : if (!is_found) { : } ``` --- class: middle,center .fit[![meme](figures/meme/grandma-bool.jpg)] --- class: middle ### Old-school C uses integers ```C int is_found = 100; : if (!is_found) { : } ``` --- ### Good Practices (so far) - Use `else if` to make the code concise - Make sure your code flow covers all possibilities - Don't check for a condition that is always true - No `else` after `return` - Always use braces around true/false blocks - Never use `==` on real numbers - Use `bool` for true/false, not `int` --- class: middle,center ### Logical operators `&&` `||` `!` --- | `a` | `b` | `a && b` | `a ❘❘ b` | `!a` | |--------|-------|----------|------------|-------| |
true
|
true
|
true
|
true
|
false
| |
true
|
false
|
false
|
true
|
false
| |
false
|
true
|
false
|
true
|
true
| |
false
|
false
|
false
|
false
|
true
| --- .small[ ```C bool is_gen_z(long birth_year) { if (birth_year >= 1995) { if (birth_year <= 2005) { return true; } } return false; } ``` ] --- class: wide .smaller[ ```C bool is_gen_z(long birth_year) { if ((birth_year >= 1995) && (birth_year <= 2005)) { return true; } return false; } ``` ] --- class:wide .smaller[ ```C bool is_gen_z(long birth_year) { return (birth_year >= 1995) && (birth_year <= 2005); } ``` ] --- class:wide .smaller[ ```C bool is_gen_z(long birth_year) { if ((birth_year < 1995) || (birth_year > 2005)) { return false; } return true; } ``` ] --- class: wide .smaller[ ```C bool is_gen_z(long birth_year) { return !((birth_year < 1995) || (birth_year > 2005)); } ``` ] --- class: center ### De Morgan's Law `!(e1 && e2)` is the same as `(!e1) || (!e2)` --- class: center ### De Morgan's Law `!(e1 || e2)` is the same as `(!e1) && (!e2)` --- class: center ### Short Circuiting ### `a && b` ### `a || b` --- ### Which one is better? .small[ ```C if (number < 100000 && is_prime(number)) { : } ``` ] .small[ ```C if (is_prime(number) && number < 100000) { : } ``` ] --- class: center ## Assertion ``` // { ... } ``` A logical expression that must always be true
at a given point in a program. --- ```C x = 1; // { x == 1 } ``` --- ```C if (cond) { : : } else { : : } ``` --- ```C if (cond) { : : // { condition A } } else { : : // { condition B } } ``` --- ```C if (x > y) { max = x; } else { max = y; } ``` how can we be sure that `max` is now the larger of the two? --- ```C if (x > y) { max = x; } else { max = y; } ``` --- .tiny[ ```C if (score >= 8) { cs1010_println_string("A"); } else { if (score >= 5) { cs1010_println_string("B"); } else { if (score >= 3) { cs1010_println_string("C"); } else { cs1010_println_string("D"); } } } ``` ] When would `C` be printed? --- .tiny[ ```C if (score >= 8) { cs1010_println_string("A"); } else { if (score >= 5) { cs1010_println_string("B"); } else { if (score >= 3) { cs1010_println_string("C"); } else { cs1010_println_string("D"); } } } ``` ] When would `C` be printed? --- ### Homework - Problem Sets 8 - 10 - Diagnostic Quiz 4 - Diagnostic Quiz on Vim - Exercise 1 --- class: bottom .tiny[ ]