Session 11: Loops#

Introduction#

In previous workshops, we’ve briefly encountered for loops, which we used to perform operations on each element of a list. In this session, we’ll extend our understanding of loops by introducing the range() function, which allows us to execute code a specific number of times. We’ll also explore while loops, which repeat a block of code as long as a condition remains true. Finally, we’ll look at how to control the flow of loops using break and continue statements.

Loops are essential in programming because they enable us to automate repetitive tasks, making our code more efficient and concise. In chemistry, loops can be used to simulate processes, analyze data, and perform calculations repeatedly under different conditions.

Part 1: for Loops with range()#

Task 1#

  1. Open a new Jupyter Notebook in your Workshop_8 directory.

  2. In a new cell, copy and run the following code:

print(range(5))

for i in range(5):
	print(i)

Analysis#

In this task, we introduce the range() function combined with a for loop to execute code a specific number of times.

  • range(5) generates a sequence of numbers from 0 up to, but not including, 5. So, it generates [0, 1, 2, 3, 4].

  • for i in range(5): initiates a loop that will iterate over each number in the sequence produced by range(5).

Task 2#

Let’s apply this concept to a chemistry-related problem.

  1. Suppose we want to simulate the decay of a radioactive substance over time. For simplicity, we’ll assume a fixed decay rate.

  2. Before running the code, predict what each line will do. Think about what type is each variable.

  3. Copy and run the following code:

initial_amount = 100  # grams
decay_rate = 0.1      # 10% decay per time unit
time_steps = 5

amount = initial_amount
for t in range(time_steps):
    amount = amount * (1 - decay_rate)
    print(f"After {t+1} time unit(s), amount remaining: {amount} grams")

Analysis#

  • initial_amount = 100 sets the starting amount of the substance.

  • decay_rate = 0.1 represents a 10% decay per time unit.

  • time_steps = 5 defines how many times we will apply the decay.

  • amount = initial_amount initializes the amount before the loop.

  • for t in range(time_steps): will iterate 5 times (from t = 0 to t = 4).

  • amount = amount * (1 - decay_rate) updates the amount by applying the decay rate.

  • print(f"After {t+1} time unit(s), amount remaining: {amount} grams") outputs the amount remaining after each time unit.

Part 2: while Loops#

while loops are useful for situations when we do not know how many times we want to run a certain piece of code, but we do know in what conditions we want to stop. For example, this might be searching or analyzing a text file until we encounter a specific symbol (\n).

Task 3#

Now let’s explore while loops.

  1. In a new cell, copy and run the following code:

count = 0
while count < 5:
    print(count)
    count += 1

Analysis#

  • count = 0 initializes the count variable.

  • while count < 5: creates a loop that will continue as long as count is less than 5.

  • print(count) outputs the current value of count.

  • count += 1 increments count by 1 in each iteration.

This loop will execute the code block repeatedly until the condition count < 5 is no longer true.

Task 4#

The previous example could have easily been written using a for loop (how?), but now let’s use a while loop to model a chemical reaction that continues until a reactant is depleted.

  1. Suppose we have 50 grams of a reactant that decreases by 15% each time due to a side reaction.

  2. Read and try to predict what the following code will do.

  3. Copy and run the code:

reactant_amount = 50  # grams
threshold = 5         # grams

time = 0
while reactant_amount > threshold:
    reactant_amount = reactant_amount * 0.85  # Decrease by 15%
    time += 1
    print(f"After {time} cycle(s), reactant amount: {reactant_amount:.2f} grams")

Analysis#

  • reactant_amount = 50 initializes the amount of reactant.

  • threshold = 5 defines when we consider the reactant depleted.

  • time = 0 initializes the time counter.

  • while reactant_amount > threshold: loop continues as long as the reactant amount is above the threshold.

  • reactant_amount = reactant_amount * 0.85 simulates the 15% decrease.

  • time += 1 increments the time counter.

  • print(f"After {time} cycle(s), reactant amount: {reactant_amount:.2f} grams") outputs the amount after each cycle.

Part 3: Controlling Loops with break and continue#

Task 5#

Now we’ll see how to control the flow of loops using break and continue.

  1. Copy and run the code:

for num in range(10):
    if num == 5:
        break
    print(num)

Analysis#

  • for num in range(10): loops over numbers from 0 to 9.

  • if num == 5: checks if num is equal to 5.

  • break exits the loop immediately when num is 5.

  • print(num) outputs the current number if the loop hasn’t been broken.

Task 6#

Let’s use continue in a loop.

  1. Copy and run the code:

for num in range(10):
    if num % 2 == 0:
        continue
    print(num)

Analysis#

  • for num in range(10): loops over numbers from 0 to 9.

  • if num % 2 == 0: checks if num is even.

  • continue skips the rest of the loop body and moves to the next iteration if num is even.

  • print(num) outputs the number if it is not even.

Task 7#

Chemistry Application

Let’s apply break and continue to a chemistry problem.

Suppose we’re monitoring a reaction, and we want to stop the process if the concentration of a product exceeds a certain limit.

  1. Read the following code and try to predict what it will do.

  2. Copy and run the code:

concentration = 0.0
time_step = 0
while True:
    concentration += 0.8  # Concentration increases by 0.8 M per time unit
    time_step += 1
    print(f"Time: {time_step}, Concentration: {concentration} M")
    if concentration >= 5.0:
        print("Concentration limit reached. Stopping the reaction.")
        break

Analysis#

  • while True: creates an infinite loop.

  • concentration += 0.8 increases concentration by 0.8 M each time.

  • time_step += 1 increments the time step.

  • print(f"Time: {time_step}, Concentration: {concentration} M") outputs the current time and concentration.

  • if concentration >= 5.0: checks if concentration has reached or exceeded 5.0 M.

  • print("Concentration limit reached. Stopping the reaction.") notifies that the limit has been reached.

  • break exits the loop.

Conclusion#

In this session, we’ve explored how loops can be used to execute code multiple times, either for a specific number of iterations or while a condition holds true. By using for loops with the range() function, we can repeat actions a set number of times, which is useful for simulations and repetitive calculations. The while loop allows us to continue processing as long as certain conditions are met, which is handy for monitoring ongoing processes in chemistry.

We also learned how to control the flow of loops using break and continue. The break statement allows us to exit a loop prematurely, which is useful when a certain condition necessitates stopping the process. The continue statement lets us skip the current iteration and move on to the next one, which is helpful when we need to ignore certain values or conditions.

Loops are powerful tools in programming that can help automate and simplify repetitive tasks in chemical computations and data analysis.


Feel free to experiment further by modifying the examples, such as changing the decay rates, thresholds, or lists of values, to see how the loops behave under different conditions.