Lecture Notes: Decision Making, Control Structures, and Boolean Logic in Programming

  • Overview of programming flow

    • Sequential programming: starts at the beginning, executes every line once and only once until the end.
    • Decision making: introducing control flow that may skip or execute a line based on a condition (an if statement).
    • Future topics preview: while loops (repeat), for loops (iterate), then data structures and code reuse via libraries.
  • Data structures and data types (foundational ideas)

    • Data structures help manage multiple items (e.g., a class of 20 students) with a uniform processing approach.
    • Data types discussed:
    • Integer: whole numbers, e.g., 1, 2, 3
    • Float: decimal numbers, e.g., 1.0, 2.897
    • Long/Double variations exist across languages (examples given:
      • 2.69378036 as a long/float representation)
    • String: sequence of characters in quotes, e.g., "hello world"
    • Char: a single character, e.g., 'a' or '6'
    • Boolean: true or false only
  • Boolean logic and relational operators

    • Booleans are used to drive decisions in if statements.
    • All numeric comparisons rely on relational operators:
    • Less than: {<}
    • Greater than: {>}
    • Less than or equal to: {\leq}
    • Greater than or equal to: {\geq}
    • Equal to: {=} (note: in many languages this is == for comparison; single '=' is assignment in many languages)
    • Not equal to: {\neq}
    • In Visual Logic, the single equal sign is used for either assignment or equality depending on context; many languages require a double equal for comparison.
    • Truth values: a relational expression evaluates to true or false.
  • Assignments vs comparisons (a common confusion)

    • Assignment: puts the value on the right-hand side into the left-hand side variable using '=' in many languages.
    • Comparison: tests whether two values are equal; often written as '==' in languages like C/Java/Python.
    • Visual Logic example uses '=' for both in some contexts; be mindful of your language syntax.
  • The structure of a relational expression (conditions)

    • A condition is a Boolean expression that typically uses relational operators to compare variables or literals.
    • Example intuition: a < b, a
    • Example interpretation: If x equals 2 and y equals 3, the expression x < y would be true.
    • Importance: conditions are the gateways for taking true vs false branches in flow control.
  • Basic if statements and control flow

    • If statements select between actions:
    • The true branch executes when the condition is true.
    • The false branch (else) executes when the condition is false.
    • Trailing else: used for a default value or error-checking path.
    • You may nest if statements within true or false branches to handle more complex logic.
    • Any legal statement in the language can appear inside an if/else branch (including further ifs or loops).
  • Nested if statements (embedded ifs)

    • Nested/embedded if means an if statement inside the true or false branch of another if.
    • Example rationale: if two numbers are equal, you don’t need to check whether they are less than or greater than – that would be redundant.
    • When nesting, the outer condition gates the inner checks; if outer is false, inner checks aren’t evaluated.
    • Practical intuition: only three numeric states exist for any numeric comparison: equal, less than, greater than.
  • All-in-one example: payroll calculation with overtime (paycheck example)

    • Given: hours worked and hourly rate; regular hours assumed to be 40.
    • Pay calculation (conceptual):
    • If hours <= 40: pay = hours * rate
    • If hours > 40: pay = 40 * rate + (hours - 40) * rate * 1.5
    • Improved practice: use a constant for regular hours and for the overtime multiplier to avoid hard-coding numbers.
    • Example constants:
    • Regular hours constant: \text{REGULAR_HOURS} = 40
    • Overtime multiplier: \text{OVERTIMEeta} = 1.5
    • Improved formula using constants:
    • If hours <= \text{REGULAR_HOURS}: pay = hours * rate
    • Else: pay = \text{REGULAR_HOURS} * rate + (hours - \text{REGULAR_HOURS}) * rate * \text{OVERTIMEeta}
    • Practice tips: avoid embedding numbers; prompt for inputs clearly (e.g., “Enter hours” and “Enter rate”); consider naming conventions (uppercase with underscores) to indicate constants.
    • Example test cases for verification (easy numbers):
    • Hours = 50, Rate = 10 → pay should reflect 40 hours at 10 and 10 hours overtime at 15.
    • Hours = 40, Rate = 10 → pay should be 400 (no overtime).
    • Hours = 30, Rate = 10 → pay should be 300.
  • Practical design decisions and coding style

    • Use constants to improve readability and maintainability.
    • Separate input handling from calculation logic for clarity.
    • Pseudocode often uses words like then and end if; pseudocode variations exist, but the core logic remains the same.
    • Before coding, write a pseudocode/algorithm outline to ensure correct logic flow; then add line comments and finally implement in the target language.
    • It’s okay to consult outside resources for ideas, but you must cite sources and produce original work with your own explanations.
  • Pseudocode vs actual code (notation and practice)

    • Pseudocode commonly uses: then, end if, end for, end while.
    • Pseudocode is not meant to be executed; it’s a high-level description of the algorithm.
    • You might encounter variations in pseudocode syntax across textbooks or courses; adapt as instructed by your teacher.
  • Control structures: compound vs nested vs sequential conditions

    • Compound condition: combines two or more Boolean expressions with a logical operator and is evaluated as a single condition.
    • Nested condition: one condition is inside another’s true or false branch (surgical narrowing of decisions).
    • Sequential (independent) conditions: separate if statements that do not depend on each other (e.g., age check and state residency check, each producing its own message).
    • When to use which:
    • If one condition depends on another, use nested/compound appropriately.
    • If conditions are independent, sequential ifs can be clearer and avoid unnecessary coupling.
  • Logical operators (and, or, not, exclusive or) and short-circuiting

    • Logical AND (and): both expressions must be true for the whole to be true.
    • Logical OR (or): at least one expression must be true for the whole to be true.
    • NOT (not): negates a Boolean expression.
    • Exclusive OR (exclusive or, XOR): true when exactly one of the operands is true.
    • Short-circuit evaluation: in an AND, if the first condition is false, the second is not evaluated; in an OR, if the first condition is true, the second is not evaluated.
    • Parentheses: always use parentheses around each condition in a compound expression to avoid ambiguity and ensure correct evaluation order.
    • Example truth tables (conceptual):
    • And: true only if both conditions are true.
    • Or: true if at least one condition is true.
    • Not: flips the truth value.
    • XOR: true if exactly one condition is true.
    • Practical note: in some contexts, you may choose XOR for clarity or efficiency; some courses even emphasize it for hardware design (gates) but many software problems use and/or/not instead.
  • Example: compound condition for billing window (nested vs compound)

    • Nested approach: if time > 6 and time < 18, then charge; else do not.
    • Compound approach: if (time > 6) and (time < 18) then charge; else do not.
    • Real-world lesson: complex conditions may be written as nested checks or as a single combined condition; choose the form that is clearer and less error-prone for your situation.
    • In the billing example, peak hours (greater than 6 and before 18) are charged at a rate (e.g., 0.10 per minute);
    • If not within the window, no charge.
  • Operator precedence and parentheses reminder (programming practice)

    • Always group each condition with parentheses when using logical operators to avoid mis-evaluation and to aid readability.
    • In Python, indentation and blocks replace curly braces; in many other languages, braces define blocks; different languages have different syntax, but the logical principles remain the same.
  • Common mistakes and debugging guidance

    • Don’t rely on a single example to validate a program; test all meaningful paths (often six test cases for middle-value problems with three inputs).
    • When grading or reviewing, expect comprehensive testing data and demonstrations of different input scenarios.
    • Do not copy-paste code from online sources without understanding and without providing your own explanation and comments.
    • Keep comments clear and explain the reasoning behind each step; this helps instructors verify understanding.
  • Testing middle-value problems with three numbers (unduplicated inputs)

    • Problem: given three numbers a, b, c, determine which is the middle value.
    • Six conditions to consider (for unduplicated numbers only):
    • If b < a < c or c < a < b, then a is the middle value.
    • If a < b < c or c < b < a, then b is the middle value.
    • If a < c < b or b < c < a, then c is the middle value.
    • If you allow duplicates, you must test additional combinations such as 333, 355, 553, 535, etc. (the six core cases expand when duplicates are allowed).
    • Approach options:
    • Nested/compound approach: use a primary comparison (e.g., determine the smallest, then the middle, then the largest) and nest subsequent checks accordingly.
    • Sequential approach: treat independent comparisons separately where appropriate.
    • The goal is to cover all possible input scenarios, including edge cases like duplicates, to ensure robustness.
  • Real-world takeaways and philosophy

    • Visual logic is highly visual for understanding flow: true vs false branches are explicit in flowcharts.
    • In larger programs, avoid unnecessary checks to optimize performance (short-circuiting and minimal calculations).
    • When communicating with teammates, use consistent naming conventions and emphasize readability (constants in caps, descriptive variable names).
    • The lecture emphasizes balancing clarity, correctness, and efficiency in program design, along with responsible debugging and documentation practices.
  • Quick reminders from the instructor

    • You can discuss the concepts of flowcharts, pseudocode, and control structures in class assignments and exams.
    • You may be allowed to use notes and lectures but not AI or external help during exams.
    • The instructor stresses the importance of testing thoroughly, using the right structure for your language, and maintaining clean, maintainable code.