Skip to content

Commit 8afe7d0

Browse files
committed
Merge branch 'main' of github.com:pythoninchemistry/ch40208
2 parents da50815 + 8744bc2 commit 8afe7d0

7 files changed

Lines changed: 1061 additions & 238 deletions

File tree

CH40208/_toc.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ parts:
3939
- file: python_basics/iterating_over_dictionaries
4040
- file: python_basics/functions
4141
- file: python_basics/comparisons_and_flow_control
42+
- file: python_basics/advanced_loop_control
4243
- caption: Working with Data
4344
chapters:
4445
- file: working_with_data/numpy_arrays
@@ -118,6 +119,8 @@ parts:
118119
title: Arithmetic
119120
- file: worked_examples/week_1_lists
120121
title: Lists
122+
- file: worked_examples/week_1_loops
123+
title: Loops
121124
- file: worked_examples/week_1_dictionaries
122125
title: Dictionaries
123126
- file: worked_examples/week_2_index

CH40208/course_contents/week_2.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Introduction to Python (Continued)
44
- [Functions](../python_basics/functions.ipynb)
55
- [Comparisons and Flow Control](../python_basics/comparisons_and_flow_control.ipynb)
6+
- [Advanced Loop Control](../python_basics/advanced_loop_control.ipynb)
67

78
## Good Practice
89
- [Writing Readable Code](../good_pratice/readable.ipynb)
Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "c820cf10-b4be-44f4-94cf-89270a22ccd8",
6+
"metadata": {},
7+
"source": [
8+
"# Advanced Loop Control\n",
9+
"\n",
10+
"In the [Loops](loops.ipynb) section, you learnt how to use `for` loops to iterate over sequences. In the [Comparisons and Flow Control](comparisons_and_flow_control.ipynb) section, you learnt how to use `if` statements to make decisions in your code. Now we'll combine these concepts and introduce some more advanced loop control structures.\n",
11+
"\n",
12+
"This section covers:\n",
13+
"- **`while` loops**: loops that continue until a condition is no longer true\n",
14+
"- **`break`**: exiting a loop early\n",
15+
"- **`continue`**: skipping to the next iteration of a loop\n",
16+
"\n",
17+
"These tools are particularly useful in computational chemistry for iterative algorithms that need to run until convergence, or for processing datasets where you need to skip invalid data or stop when certain conditions are met.\n",
18+
"\n",
19+
"**Prerequisites:** Before working through this section, make sure you're comfortable with:\n",
20+
"- Basic `for` loops and `range()` (from [Loops](loops.ipynb))\n",
21+
"- `if`/`elif`/`else` statements (from [Comparisons and Flow Control](comparisons_and_flow_control.ipynb))\n",
22+
"- Comparison operators (`<`, `>`, `==`, etc.)\n",
23+
"\n",
24+
"## `while` loops\n",
25+
"\n",
26+
"In addition to `for` loops, Python also provides `while` loops for situations where you want to repeat a block of code as long as a condition is true.\n",
27+
"\n",
28+
"A `while` loop is particularly useful when you don't know in advance how many iterations you'll need - you just know when to stop.\n",
29+
"\n",
30+
"### Example: Cooling to Room Temperature\n",
31+
"\n",
32+
"Imagine a hot beaker cooling down to room temperature. The beaker loses 10% of the temperature difference with its surroundings in each time step. We want to simulate this cooling process until the beaker is within 0.5°C of room temperature."
33+
]
34+
},
35+
{
36+
"cell_type": "code",
37+
"execution_count": 9,
38+
"id": "8df6ddf1-189c-46ba-837b-b0825d889bd8",
39+
"metadata": {},
40+
"outputs": [
41+
{
42+
"name": "stdout",
43+
"output_type": "stream",
44+
"text": [
45+
"Step 1: Temperature = 92.00°C\n",
46+
"Step 2: Temperature = 84.80°C\n",
47+
"Step 3: Temperature = 78.32°C\n",
48+
"Step 4: Temperature = 72.49°C\n",
49+
"Step 5: Temperature = 67.24°C\n",
50+
"Step 6: Temperature = 62.52°C\n",
51+
"Step 7: Temperature = 58.26°C\n",
52+
"Step 8: Temperature = 54.44°C\n",
53+
"Step 9: Temperature = 50.99°C\n",
54+
"Step 10: Temperature = 47.89°C\n",
55+
"Step 11: Temperature = 45.10°C\n",
56+
"Step 12: Temperature = 42.59°C\n",
57+
"Step 13: Temperature = 40.33°C\n",
58+
"Step 14: Temperature = 38.30°C\n",
59+
"Step 15: Temperature = 36.47°C\n",
60+
"Step 16: Temperature = 34.82°C\n",
61+
"Step 17: Temperature = 33.34°C\n",
62+
"Step 18: Temperature = 32.01°C\n",
63+
"Step 19: Temperature = 30.81°C\n",
64+
"Step 20: Temperature = 29.73°C\n",
65+
"Step 21: Temperature = 28.75°C\n",
66+
"Step 22: Temperature = 27.88°C\n",
67+
"Step 23: Temperature = 27.09°C\n",
68+
"Step 24: Temperature = 26.38°C\n",
69+
"Step 25: Temperature = 25.74°C\n",
70+
"Step 26: Temperature = 25.17°C\n",
71+
"Step 27: Temperature = 24.65°C\n",
72+
"Step 28: Temperature = 24.19°C\n",
73+
"Step 29: Temperature = 23.77°C\n",
74+
"Step 30: Temperature = 23.39°C\n",
75+
"Step 31: Temperature = 23.05°C\n",
76+
"Step 32: Temperature = 22.75°C\n",
77+
"Step 33: Temperature = 22.47°C\n",
78+
"Step 34: Temperature = 22.23°C\n",
79+
"Step 35: Temperature = 22.00°C\n",
80+
"Step 36: Temperature = 21.80°C\n",
81+
"Step 37: Temperature = 21.62°C\n",
82+
"Step 38: Temperature = 21.46°C\n",
83+
"Step 39: Temperature = 21.31°C\n",
84+
"Step 40: Temperature = 21.18°C\n",
85+
"Step 41: Temperature = 21.06°C\n",
86+
"Step 42: Temperature = 20.96°C\n",
87+
"Step 43: Temperature = 20.86°C\n",
88+
"Step 44: Temperature = 20.78°C\n",
89+
"Step 45: Temperature = 20.70°C\n",
90+
"Step 46: Temperature = 20.63°C\n",
91+
"Step 47: Temperature = 20.57°C\n",
92+
"Step 48: Temperature = 20.51°C\n",
93+
"Step 49: Temperature = 20.46°C\n",
94+
"Thermal equilibrium reached after 49 steps\n",
95+
"Final temperature: 20.46°C\n"
96+
]
97+
}
98+
],
99+
"source": [
100+
"temperature = 100.0 # Starting temperature in °C\n",
101+
"room_temperature = 20.0 # Ambient temperature in °C\n",
102+
"threshold = 0.5 # Stop when within 0.5°C of room temp\n",
103+
"iteration = 0\n",
104+
"\n",
105+
"while temperature - room_temperature > threshold:\n",
106+
" # Cool by 10% of the temperature difference each step\n",
107+
" temperature_difference = temperature - room_temperature\n",
108+
" temperature = temperature - 0.1 * temperature_difference\n",
109+
" iteration += 1\n",
110+
" print(f\"Step {iteration}: Temperature = {temperature:.2f}°C\")\n",
111+
"\n",
112+
"print(f\"Thermal equilibrium reached after {iteration} steps\")\n",
113+
"print(f\"Final temperature: {temperature:.2f}°C\")"
114+
]
115+
},
116+
{
117+
"cell_type": "markdown",
118+
"id": "61da627f-ef7f-4c84-bf5c-4510028a9c63",
119+
"metadata": {},
120+
"source": [
121+
"**How this works:**\n",
122+
"- The `while` loop continues as long as the temperature is more than 0.5°C away from room temperature\n",
123+
"- Each iteration, the beaker cools by 10% of the current temperature difference\n",
124+
"- The loop automatically stops when the temperature gets close enough to room temperature\n",
125+
"\n",
126+
"**Key concept:** With a `while` loop, we don't need to know in advance how many iterations it will take - the loop continues until the condition becomes `False`."
127+
]
128+
},
129+
{
130+
"cell_type": "markdown",
131+
"id": "8b666ab4-322f-401c-841c-8d6a17d76aeb",
132+
"metadata": {},
133+
"source": [
134+
"## `continue` and `break`\n",
135+
"\n",
136+
"Python provides additional flow control statements for controlling the behaviour of **loops**. For example, if a certain condition is met, we might want to jump straight to the next iteration of a loop without running the rest of the current code block, or we might want to quit the loop altogether.\n",
137+
"\n",
138+
"- `continue` → jump straight to the next iteration of the loop.\n",
139+
"- `break` → jump out of the loop entirely.\n",
140+
"\n",
141+
"For example, if we are iterating through the numbers 0 to 99, but want to stop if we reach 3, we can use the `break` keyword:"
142+
]
143+
},
144+
{
145+
"cell_type": "code",
146+
"execution_count": 6,
147+
"id": "caaf4c1e-ef37-4e1c-b887-89b09a643a5f",
148+
"metadata": {},
149+
"outputs": [
150+
{
151+
"name": "stdout",
152+
"output_type": "stream",
153+
"text": [
154+
"0\n",
155+
"1\n",
156+
"2\n",
157+
"3\n",
158+
"Loop exited\n"
159+
]
160+
}
161+
],
162+
"source": [
163+
"for i in range(100):\n",
164+
" print(i)\n",
165+
" if i == 3:\n",
166+
" break\n",
167+
"print('Loop exited')"
168+
]
169+
},
170+
{
171+
"cell_type": "markdown",
172+
"id": "1c980124-f2b9-4a5e-90e1-f9fda380592e",
173+
"metadata": {},
174+
"source": [
175+
"Alternatively we might want to count numbers but **skip** those divisible by 3."
176+
]
177+
},
178+
{
179+
"cell_type": "code",
180+
"execution_count": 7,
181+
"id": "7bf01de2-d70e-4f9e-8a32-989ed358b93a",
182+
"metadata": {},
183+
"outputs": [
184+
{
185+
"name": "stdout",
186+
"output_type": "stream",
187+
"text": [
188+
"1\n",
189+
"2\n",
190+
"4\n",
191+
"5\n",
192+
"7\n",
193+
"8\n",
194+
"10\n",
195+
"11\n",
196+
"13\n",
197+
"14\n",
198+
"16\n",
199+
"17\n",
200+
"19\n"
201+
]
202+
}
203+
],
204+
"source": [
205+
"for i in range(20):\n",
206+
" if i%3 == 0: # `True` if i is divisible by 3\n",
207+
" continue\n",
208+
" print(i)"
209+
]
210+
},
211+
{
212+
"cell_type": "markdown",
213+
"id": "65a5ebfc-c805-4e9b-b4fd-e7992d1a1b42",
214+
"metadata": {},
215+
"source": [
216+
"## Exercises\n",
217+
"\n",
218+
"### Exercise 1: Temperature-Dependent Reaction Rate Study\n",
219+
"\n",
220+
"**Problem:** You are investigating how reaction rate changes with temperature. Your automated system heats a reaction vessel from 20°C to 100°C in 8°C increments, taking a measurement at each temperature.\n",
221+
"\n",
222+
"Write a `while` loop that:\n",
223+
"- Starts with `temperature = 20` (°C)\n",
224+
"- Takes a measurement (just print the temperature for now)\n",
225+
"- Increases temperature by 8°C\n",
226+
"- Continues until temperature reaches or exceeds 100°C\n",
227+
"\n",
228+
"Print each measurement temperature and count the total number of measurements taken.\n",
229+
"\n",
230+
"**Expected output format:**\n",
231+
"```\n",
232+
"Measurement 1: 20°C\n",
233+
"Measurement 2: 28°C\n",
234+
"Measurement 3: 36°C\n",
235+
"...\n",
236+
"Completed X measurements from 20°C to Y°C\n",
237+
"```"
238+
]
239+
},
240+
{
241+
"cell_type": "markdown",
242+
"id": "ae82c54a-4200-42b7-b1e5-bf0db21d159c",
243+
"metadata": {},
244+
"source": [
245+
"---\n",
246+
"\n",
247+
"### Exercise 2: Convergence with Iteration Limit\n",
248+
"\n",
249+
"**Problem:** The cooling simulation from the example converges relatively quickly because it loses 10% of the temperature difference each step. However, if the cooling rate is slower, convergence can take many iterations.\n",
250+
"\n",
251+
"Modify the simulation to use a slower cooling rate (only 2% per step instead of 10%). This is more realistic for a well-insulated vessel. However, since convergence is now much slower, add an iteration limit of 100 steps. If equilibrium isn't reached within 100 steps, stop and report that more time is needed.\n",
252+
"\n",
253+
"**Starting code:**\n",
254+
"```python\n",
255+
"temperature = 100.0 # Starting temperature in °C\n",
256+
"room_temperature = 20.0 # Ambient temperature in °C\n",
257+
"threshold = 0.5 # Stop when within 0.5°C of room temp\n",
258+
"cooling_rate = 0.02 # Cool by 2% per step\n",
259+
"iteration = 0\n",
260+
"max_iterations = 100\n",
261+
"\n",
262+
"while temperature - room_temperature > threshold:\n",
263+
" # Cool by 2% of the temperature difference each step\n",
264+
" temperature_difference = temperature - room_temperature\n",
265+
" temperature = temperature - cooling_rate * temperature_difference\n",
266+
" iteration += 1\n",
267+
" print(f\"Step {iteration}: Temperature = {temperature:.2f}°C\")\n",
268+
"\n",
269+
"print(f\"Thermal equilibrium reached after {iteration} steps\")"
270+
]
271+
},
272+
{
273+
"cell_type": "code",
274+
"execution_count": null,
275+
"id": "666851a2-ff37-4242-adb3-052034b7ff73",
276+
"metadata": {},
277+
"outputs": [],
278+
"source": []
279+
}
280+
],
281+
"metadata": {
282+
"kernelspec": {
283+
"display_name": "Python 3 (ipykernel)",
284+
"language": "python",
285+
"name": "python3"
286+
},
287+
"language_info": {
288+
"codemirror_mode": {
289+
"name": "ipython",
290+
"version": 3
291+
},
292+
"file_extension": ".py",
293+
"mimetype": "text/x-python",
294+
"name": "python",
295+
"nbconvert_exporter": "python",
296+
"pygments_lexer": "ipython3",
297+
"version": "3.12.9"
298+
}
299+
},
300+
"nbformat": 4,
301+
"nbformat_minor": 5
302+
}

0 commit comments

Comments
 (0)