Applied Programming/Conditions



This lesson introduces conditions, validation, exception handling, and defensive programming.

Objectives and Skills
Objectives and skills for this lesson include:
 * Construct and analyze code segments that use branching statements
 * if; elif; else; nested and compound conditional expressions
 * Analyze, detect, and fix code segments that have errors
 * Syntax errors; logic errors; runtime errors
 * Analyze and construct code segments that handle exceptions
 * Try; except; else; finally; raise; assert

Readings

 * 1)  Structured programming
 * 2)  Conditional (computer programming)
 * 3)  Data validation
 * 4)  Exception handling
 * 5)  Python syntax and semantics - EAFP vs. LBYL
 * 6)  Defensive programming

Multimedia

 * 1) YouTube: Introduction to Structured Programming
 * 2) YouTube: The Three Basic Structures—Sequence, Selection, and Loop
 * 3) YouTube: Programming For Beginners - Relational Operators
 * 4) YouTube: Introduction to Programming - Control Flow
 * 5) YouTube: Exception Handling in Java
 * 6) YouTube: Defensive Programming
 * 7) YouTube: Python 3 Programming Tutorial: If Statement
 * 8) YouTube: Python 3 Programming Tutorial - Try and Except error Handling
 * 9) YouTube: Assert statements and unit tests (Python)

Examples

 * C#
 * /Java/
 * /JavaScript/
 * /PHP/
 * /Python3/

Activities
Modify your program from the previous lesson to add input validation, parameter validation, assertions, and exception handling.
 * 1) Review  Data validation. Add input validation to ensure that only valid data may be entered for each input. Validate for both data type and range. Invalid input should terminate the program with an appropriate error message.
 * 2) Review  Parameter validation. Add parameter validation to all calculation / conversion functions to ensure that only valid parameters are passed to each function. Validate for both data type and range. Throw or raise appropriate exceptions for invalid parameters.
 * 3) Review  Assertion (software development). Add assertions to the output function to assure that only valid parameters are passed. Validate for both data type and range.
 * 4) Review  Exception handling. Add exception handling to your main function to catch any errors thrown during processing and terminate the program gracefully.
 * 5) Update program and function documentation regarding parameters and exceptions, consistent with the documentation standards for your selected programming language.

Lesson Summary

 * Assertion is a predicate(a Boolean-valued function over the state space, usually expressed as a logical proposition using the variables of a program) connected to a point in the program, that always should evaluate to true at that point in code execution. Assertions can help a programmer read the code, help a compiler compile it, or help the program detect its own defects.
 * Exception handling is a means to respond to and ideally address run-time errors that occur during the execution of a program—these are errors that either cannot be handled by another mechanism or their handling would make for clumsy and inelegant design.
 * There are viable alternatives. Critical functions may return error codes that are subject to explicit checks by the programmer. For example, the new operator in C++ allocates dynamic memory, returning a pointer after doing so. If for some reason, the system cannot perform such a task, the pointer returned may hold the special value NULL, indicating the failure of the desired operation.
 * Where possible, you may also use other data validation techniques (making use of conditions and loops) to "preemptively filter exceptional cases."
 * Designated handling constructs separate the main logic of the program from the handling of exceptional cases into semantic blocks, resulting in code that is simpler to read and maintain.
 * Most implementations of exception handling feature a try-catch or in the specific case of Python, a try-except, statement. Despite syntactical differences between languages, the concept of exception handling is similar across the board.
 * The try clause houses code that is to be attempted. If an exception (either thrown or raised by the run-time environment or manually by the programmer) were to occur, further processing halts as the exception are passed onto the corresponding catch or except clause. There may be several of these clauses.
 * Generally, the intent of exception handling is to ameliorate the problem with grace. If this is not possible, you can throw or raise the exception again to be caught by a higher-level exception handler.
 * In Python, as well as many other languages, you may specify to catch an exception generically or precisely (by denoting the exact name of the exceptional case, either language-specified or user-defined). You can even group exceptional cases to handle by adjoining them into a tuple data structure.
 * The exception can be accessed much like a function argument (e.g., except ValueError as e), so you can more thoroughly investigate and diagnose the matter at hand.
 * You can also tack on else and finally clauses for house-keeping purposes.
 * There are two models to approach code that may result in exceptional cases: EAFP and LBYL.
 * The LBYL, "look before you leap," mentality has the programmer write code such that a precondition is tested before accessing the sought after resource.
 * This, however, doesn't always work as intended. If the state of an object were changing in real-time, the resource that was once safe can be rendered unsafe between the evaluation of the precondition and the later accessing of that resource. This is a specific bug known as a time of check to time of use (abbreviated TOCTTOU) race condition.
 * The EAFP, "it's easier to ask for forgiveness than permission," form is a staple of Python idioms. Abiding by such a philosophy, you are to simply attempt the desired action. If there is a resultant exception, it's to be handled by a try-except block. This sidesteps the potentiality for a change of state and the ensuing "race condition" that it might cause, as described above.
 * Structured programming aims to improve clarity, quality, and readiness by taking advantage of subroutines, block codes, loops, and more.
 * The discovery of what is now known as the structured program theorem contributed to the acceptance of structured programming by computer scientists.
 * The structured program theorem is composed of control structures: Sequence, Selection, Iteration, and Recursion. It proved that goto statements are not necessary to code programs. It led to Spaghetti code which was difficult to read, maintain, and had a complex structure.
 * Conditional statements in computer science allow for the selection between alternatives at runtime.
 * If-then-else is widely used in many programming languages. An additional else-if can be used multiple times to combine several conditions. Switch statements also offer the same concept.
 * Data Validation is the process of ensuring that data is both correct and useful.
 * There are 4 general kinds of validation: Data type validation, Range and constraint validation, Code and Cross-reference validation, and Structured validation.
 * Data type validation verifies that the individual characters provided through user input are consistent with the expected characters of one or more known primitive data types: integer, float (decimal), or string.
 * Simple range and constraint validation examine user input to ensure it falls within the minimum/maximum range or consistency with a test for evaluating a sequence of characters.
 * Code and cross-reference validation include tests for data type validation, combined with one or more operations to verify that the user-supplied data is consistent with one or more external rules. These additional validity constraints may involve cross-referencing supplied data with a known look-up table or directory information service.
 * Structured validation allows for the combination of any of various basic data type validation steps, along with more complex processing. In other words, when a piece of data is accepted and continued its operation, it does not mean that it is the correct piece of data. This method examines that the piece of data is entered correctly.
 * Different methods of validation include but are not limited to: Allowed character checks, Batch totals, Cardinality check, Check digits, Consistency checks, Control totals, Cross-system consistency checks, Data type checks, File existence checks, Format or picture check, Hash totals, Limit check, Logic check, Presence check, Range check, Referential integrity, Spelling and Grammar check, Uniqueness check, and Table Look Up check.
 * Post Validation Actions include:
 * Enforcement Action - typically rejects the data entry request and requires the input actor to make a change that brings the data into Advisory Action.
 * Advisory Actions - typically allow data to be entered unchanged but sends a message to the source actor indicating those validation issues that were encountered.
 * Verification Actions - special cases of advisory actions in which the source actor can be asked to verify that this data is what they would really want to enter, in the light of a suggestion to the contrary.
 * Defensive programming is a form of defensive design intended to ensure the continuing function of a piece of software under unforeseen circumstances.
 * Defensive programming practices are often used where high availability, safety or security is needed.
 * Defensive programming is an approach to improve software and source code, in terms of:
 * General quality – reducing the number of software bugs and problems.
 * Making the source code comprehensible – the source code should be readable and understandable, so it is approved in a code audit.
 * Making the software behave in a predictable manner despite unexpected inputs or user actions.
 * Offensive programming is a category of defensive programming, with the added emphasis that certain errors should not be handled defensively.
 * Defensive Programming Techniques:
 * Intelligent Source Code Reuse - If existing code is tested and known to work, reusing it may reduce the chance of bugs being introduced. However, reusing code is not always a good practice, because it also amplifies the damages of a potential attack on the initial code.
 * Canonicalization - libraries that can be employed to avoid bugs due to non-canonical input.
 * Low tolerance against "potential" bugs – Assume that code constructs that appear to be problem prone are bugs and potential security flaws.

Key Terms

 * assertion
 * An assertion is a predicate connected to a point in the program, that always should evaluate to true at that point in code execution. Assertions can help a programmer read the code, help a compiler compile it, or help the program detect its own defects.


 * Boolean expression
 * An expression in a programming language that produces a Boolean value when evaluated, i.e. one of true or false.


 * conditional statements
 * Allow for selection between alternatives at runtime.


 * data validation
 * The process of ensuring that data have undergone data cleansing to ensure they have data quality, that is, that they are both correct and useful.


 * defensive programming
 * A form of defensive design intended to ensure the continuing function of a piece of software under unforeseen circumstances.


 * EAFP (Easier to Ask Forgiveness than Permission)
 * Approach that first attempts the desired action then handles any resulting exceptions.


 * exception handling
 * The process of responding to the occurrence, during computation, of exceptions. Anomalous or exceptional conditions requiring special processing, often changing the normal flow of program execution.


 * GoTo statement
 * Performs a one-way transfer of control to another line of code; in contrast, a function call normally returns control.


 * if statement
 * An if statement is a programming conditional statement that, if proved true, performs a function or displays information.


 * LBYL (Look Before You Leap)
 * Approach which a precondition is tested before accessing the sought-after resource.


 * logic error
 * Error that makes the program deliver unexpected results without crashing it.


 * relational operator
 * A programming language construct or operator that tests or defines some kind of relation between two entities, including numerical equality (e.g., 5 = 5) and inequalities (e.g., 4 ≥ 3).


 * runtime error
 * Error produced by the runtime system if something goes wrong while a syntactically correct program is running.


 * software bug
 * An error, flaw, failure or fault in a computer program or system that causes it to produce an incorrect or unexpected result, or to behave in unintended ways.


 * structured programming
 * A programming paradigm aimed at improving the clarity, quality, and development time of a computer program.


 * syntax
 * Syntax of a computer language is the set of rules that defines the combinations of symbols that are considered to be a correctly structured document or fragment in that language.


 * syntax error
 * Error that indicates something is wrong with program syntax. It's produced by Python during the translation of the source code into byte code.


 * truth table
 * A mathematical table used in logic, truth tables can be used to show whether a propositional expression is true for all legitimate input values, that is, logically valid.