Concepts / Debugging and Error Handling

Debugging and Error Handling

Use the continue statement to skip lines that do not meet your criteria, jumping immediately back to the next iteration of the loop.

  • Programming

The Hidden Risk in Line Parsing

When a program parses a file line by line, it may split each line into words and then inspect particular words. The danger is that lines do not always have the same structure. A line may be empty, or it may contain only one word when the program expects more. Accessing a list index that does not exist causes an IndexError and crashes the program. Defensive control flow prevents the program from making that unsafe access.

The three techniques in this lesson work together: continue skips unwanted lines, guardian code checks that an access is safe, and or combines several skip conditions into one readable decision.

Skipping Unwanted Iterations

When parsing a file, you may care only about lines that begin with the word From. A continue statement handles the lines that do not qualify. When the condition for skipping is met, continue immediately jumps back to the top of the loop. The remaining statements in the current iteration are not executed, and the loop moves on to the next line.

for line in lines: words = line.split() if words[0] != "From": continue process_line(words)

NoYesRead lineFirst word is FromcontinueNext iterationProcess line
When a line does not meet the condition, what happens next?

Why the First Check Can Fail

What do you think happens?

What happens when an empty line reaches the expression words[0]?

Reveal answer

Answer: The program raises an IndexError before it can execute continue.

An empty line produces no words, so there is no element at index 0. The program must check that the list contains an element before accessing words[0].

The continue statement cannot protect an expression that fails before the condition is evaluated. In the earlier pattern, words[0] is evaluated as part of the if condition. If words is empty, the program crashes while trying to obtain its first element. The missing step is a guardian check placed before the access it protects.

Guarding List Access

Guardian code is a defensive check that verifies whether an operation is safe before allowing it to happen. For a list of words, the program checks the list length before accessing an index. If the list is empty, continue skips the line. Only after this check succeeds may the program safely inspect words[0].

python

Protecting the First-Word Check

A parser should process only lines whose first word is From, but some input lines may be empty.

Split the line: The line becomes a list named words.

Check the length: If len(words) is 0, the line has no first word, so continue skips it before any index access.

Inspect the first word: The expression words[0] is reached only after the guardian check confirms that an element exists.

Skip or process: A nonmatching first word causes another continue; a first word of From reaches the processing step.

The parser avoids accessing a nonexistent first element and processes only lines that meet the required criterion.

length is 0length is greater than 0safe accesswordsList length checked firstEmpty listSkip with continueIndex 0First word existsCheck From
How does checking a list's length prevent access to an element that does not exist?

Combining Skip Conditions

Two separate if statements can both use continue: one for an empty list and one for a first word that is not From. This works, but the conditions can be combined. The or operator makes the complete condition true when at least one of its component conditions is true. Therefore, the line is skipped if it is empty or if its first word is not From.

python
Either condition truelen(words) == 0Empty listorCombine conditionswords[0] != FromNonmatching first wordcontinueSkip iteration
How do multiple conditions combine, and when does the overall expression become true?
Line conditionOverall skip conditionResult
The list is emptyTrue or ...continue skips the line
The first word is not From... or Truecontinue skips the line
The list is not empty and the first word is FromFalse or FalseThe line reaches processing

The or expression is true when at least one skip condition is true.

A Complete Defensive Pattern

for line in lines: words = line.split() if len(words) == 0 or words[0] != "From": continue process_line(words)

This pattern is compact without removing the safety check. The guardian condition comes first inside the compound expression, and the filtering condition follows it. The continue statement has one clear job: leave the current iteration whenever the line should not be processed.

Mistakes That Cause Crashes

  • Accessing words[0] before checking whether the list has an element.

    An empty line produces an empty list, so index 0 does not exist and the program raises IndexError.

    Fix: Check the list length first, then access words[0] only when the list is not empty.

  • Putting the guardian check after the protected access.

    The unsafe access has already happened before the length check can help.

    Fix: Place the guardian check before every access it protects.

  • Processing every line without filtering.

    Lines that do not meet the required criterion are processed instead of being skipped.

    Fix: Use continue to move immediately to the next iteration when a line does not qualify.

  • Repeating separate skip blocks when one compound condition is clearer.

    The logic works, but combining related skip conditions can reduce duplication and improve readability.

    Fix: Use one if statement with or when either condition should cause the same continue action.

Practice the Control Flow

MEDIUM

Rewrite a line-parsing loop so that it processes only nonempty lines whose first word is From. Use one compound if statement with or and place continue in that statement.

Hints
  • Split each line into a list named words.
  • The first condition should identify an empty list.
  • The second condition should identify a first word that is not From.
  • Both conditions should lead to the same continue statement.

Tracing Three Kinds of Lines

Predict the control-flow result for an empty line, a line beginning with To, and a line beginning with From.

Empty line: Splitting produces no words. The length condition is true, so continue skips the iteration before words[0] is accessed.

Line beginning with To: The list is not empty, but the first word is not From. The second condition is true, so continue skips the iteration.

Line beginning with From: The list is not empty and the first word is From. Both skip conditions are false, so the line reaches processing.

Only the line beginning with From reaches the processing step, while the empty and nonmatching lines are skipped safely.

Reliable Parsing Habits

  • Identify which lines your parser actually needs to process.
  • Use continue to leave an iteration as soon as a line fails the required criterion.
  • Check a list's length before accessing an index.
  • Place guardian checks before the code they protect.
  • Combine skip conditions with or when either condition should produce the same result.
  • Test with empty lines and lines containing fewer words than expected.

Debugging is not only about reacting after a crash. In this pattern, error handling is built into the control flow: unsafe input is recognized early, the current iteration is abandoned, and only data that passes the checks is processed.

Key Takeaways

  • continue immediately moves control to the next loop iteration, skipping the remaining statements for the current line.
  • Accessing a nonexistent list index can raise IndexError, especially when parsing empty or inconsistently structured lines.
  • Guardian code checks the list length before an index is accessed.
  • The or operator makes a combined skip condition true when at least one component condition is true.
  • Robust parsing places checks before protected operations and tests edge cases such as empty lines.