An Introduction to the Art of Computer Programming Using Python in the Age of Generative AI

VII. Control Flow and Looping

Flat is better than nested.
Tim Peters, Zen of Python

Understanding how to control execution flow and implement looping constructs is fundamental to programming. Python provides a variety of control flow mechanisms, such as if, else, and elif statements, and looping constructs like for and while loops, which let programmers execute code conditionally and repetitively.

Crucial Note on Indentation: Unlike languages like C++ or Java that use curly braces {} to define blocks of code, Python uses indentation (whitespace). All code inside an if, else, or loop block must be indented by the same amount (typically 4 spaces).

If-Else Statements

An if statement is used to test a condition and execute a block of code if that condition is true. If the condition is false, the block of code under the else statement is executed. Multiple conditions can be tested in sequence using elif (short for "else if") statements. Each if or elif statement can have its own condition, and the block with the first true condition is executed. If no conditions are true, the else block, if present, is executed.

The Conditional Expression (Ternary Operator): Python also allows for a concise one-line if-else statement. This is useful for assigning values based on a condition without writing a full multi-line block.


x = 10

# Standard If-Else
if x > 5:
    print("x is greater than 5")
elif x == 5:
    print("x is equal to 5")
else:
    print("x is less than 5")

# One-liner (Ternary Operator)
status = "High" if x > 5 else "Low"
print(f"Status: {status}")
        

For Loops

for loops are fundamental constructs that let you execute a block of code repeatedly over a set of items or a range of values. This is especially important for repetitive tasks where you apply the same operation to multiple items. Below is a simple for loop example:


# range(5) generates numbers 0, 1, 2, 3, 4
for i in range(5):
    print(i)
        

For a clearer demonstration, here is a simple for loop that calculates the sum of the first five numbers:


sum_val = 0

for i in range(5):
    sum_val += i
    print(f'Sum: {sum_val}')
        

Sum: 0

Here is a more complex example combining for loops, if-else statements, and formatted strings:


fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
    # Check if the first letter is a vowel
    if fruit[0] in ['a', 'o', 'u', 'e', 'i']:
        print(f'I eat an {fruit}.')
    else:
        print(f'I eat a {fruit}.')
        

Looping with Enumerate

A common requirement is needing both the item and its index (position) in the list. The "Pythonic" way to do this is using the enumerate() function, rather than creating a manual counter or using range(len(list)).


fruits = ['apple', 'banana', 'cherry']

# enumerate returns pairs of (index, value)
for index, fruit in enumerate(fruits):
    print(f"Item {index}: {fruit}")
        

While Loops

while loops repeatedly execute a block of code as long as a given condition remains true. They are useful when you need to keep looping until a certain condition changes, which may not correlate to a fixed number of iterations.

Warning: Be careful with infinite loops. If the condition never becomes False (for example, if you forget to increment the counter), the program will run forever or until it crashes.


x = 0
while x < 5:
    print(x)
    x += 1 # Important: Modify x to eventually end the loop
        
Generative AI Insight: The Autoregressive Loop
Generative AI models (like ChatGPT) are fundamentally built on a while loop. They generate text one token (word part) at a time. The model predicts the next token, appends it to the conversation history, and loops back to predict the next one. This loop continues while the model has not yet produced a specific "stop token."

Breaking, Continuing, and Passing

If a loop should stop under certain conditions, use break. When executed, the loop exits immediately, and control resumes at the next line outside the loop. This is helpful if you need to exit once a target result is found, or a key condition is met.


for i in range(5):
    if i == 3:
        break
    print(i)
        

If you only want to skip certain iterations, use continue. Rather than running the entire loop body, it moves the loop to the next iteration.


for i in range(5):
    if i == 3:
        continue
    print(i)
        

Finally, the pass statement is a null operation. Nothing happens when it executes. It is often used as a placeholder in empty code blocks (common when AI generates skeleton code).


for i in range(5):
    if i == 3:
        pass # To be implemented later
    else:
        print(i)
        

A Simple Numerical Algorithm

With the concepts learned, we can perform various computations—even those requiring iterative algorithms. Suppose we want to approximate the square root of an integer (e.g., 25). One well-known method is the bisection search. We define the desired precision and know the square root is greater than 0 but no more than the integer itself. Then we halve the midpoint between our current maximum and minimum, compare the square of that midpoint to our target integer, and repeat until our accuracy requirement is met.


integer_number = 25
accuracy = 0.01

if integer_number < 0:
    print("There is no true square root of a negative number.")

else:
    minimum = 0
    maximum = max(1, integer_number)
    number_of_iterations = 0
    midpoint = (maximum + minimum) / 2

    # Loop until the difference is within our accuracy threshold
    while abs(midpoint ** 2 - integer_number) >= accuracy:
        if midpoint**2 < integer_number:
            minimum = midpoint
        else:
            maximum = midpoint
        midpoint = (maximum + minimum) / 2
        number_of_iterations += 1

    print(f"After {number_of_iterations} iterations, the bisection search algorithm found {midpoint} to be close to the square root of {integer_number} with an accuracy of {accuracy}. ")
        

Prompting Generative AI for Efficient Control Flow and Looping Constructs

Leveraging Generative AI to implement control flow and looping constructs effectively involves creating precise, goal-oriented prompts. By specifying clear objectives, context, and requirements, you can obtain AI-generated code that meets your programming needs. Here are a few tips:

Example Prompt:
Create a Python program that uses a for loop to iterate through a list of numbers. The program should check whether each number is prime or not using if-else statements and store the results in a dictionary. Finally, display the dictionary with numbers as keys and their prime status as values.

Resulting AI-generated code:


# Prime Number Checker Program
numbers = [2, 3, 4, 5, 10, 13, 17, 19, 23, 24, 29]
prime_status = {}

for number in numbers:
    if number < 2:
        prime_status[number] = False
    elif number == 2:
        prime_status[number] = True
    else:
        is_prime = True
        # Optimization: We only need to check up to the square root of the number
        for i in range(2, int(number ** 0.5) + 1):
            if number % i == 0:
                is_prime = False
                break
        prime_status[number] = is_prime

print("Prime Status of Numbers:")
for num, status in prime_status.items():
    print(f"{num}: {'Prime' if status else 'Not Prime'}")
        
Back to Home