Control flow is a fundamental concept in programming that refers to the order in which statements are executed in a program. In Python, control flow is managed through conditional statements and loops. These constructs enable programmers to create programs that can make decisions and perform repetitive tasks based on certain conditions.
Show the code
import numpy as npimport matplotlib.pyplot as plt# Define grid sizex = np.linspace(-3.0, 3.0, 400)y = np.linspace(-3.0, 3.0, 400)X, Y = np.meshgrid(x, y)# Initialize the Z matrixZ = np.zeros_like(X)# Define a function to create loop patternsdef generate_loop_pattern(X, Y, num_loops): Z = np.zeros_like(X)for i inrange(1, num_loops +1): Z += np.sin(X * i) * np.cos(Y * i)return Z# Generate loop patternsnum_loops =5Z = generate_loop_pattern(X, Y, num_loops)# Create plotplt.figure(figsize=(8, 6))# Superimpose imshow and contourplt.imshow(Z, extent=(-3, 3, -3, 3), origin='lower', cmap='Spectral', alpha=0.5)contour = plt.contour(X, Y, Z, levels=10, colors='black')# Add color bar and labels#plt.colorbar(contour, label='Contour Levels')plt.xlabel('X axis')plt.ylabel('Y axis')plt.show()
Pastel Loops
The need for control flow arises from the fact that many programs require a degree of flexibility in the way they operate. For example, a program that calculates the average of a list of numbers may need to handle lists of different lengths or perform additional calculations based on the input data. Control flow constructs allow programmers to create programs that can adapt to different scenarios and respond accordingly.
Python provides several control flow constructs, including:
Conditional statements: Conditional statements allow programmers to execute different blocks of code based on whether a certain condition is true or false. In Python, conditional statements are created using the “if”, “elif”, and “else” keywords.
Loops: Loops allow programmers to execute a block of code multiple times. Python provides two types of loops: “for” loops, which iterate over a sequence of elements, and “while” loops, which repeat a block of code until a certain condition is no longer true.
The concept of control flow is not unique to Python and has been present in programming languages for decades. The first programming languages, such as Fortran and COBOL, were designed to handle complex mathematical calculations and did not include control flow constructs. As programming languages evolved and became more versatile, control flow constructs were introduced to enable programmers to create more complex programs.
Today, control flow is a core concept in programming and is used in a wide range of applications, from web development to scientific computing. By providing a flexible and powerful set of control flow constructs, Python enables programmers to create programs that can handle a wide range of scenarios and respond to changing conditions.
3.1 Conditionals
Often a certain process needs to executed if a certain condition is fulfilled. The result of this conditions has to be of the Boolean data type.
a =0b =1100
a > b
False
if a > b:print('a is bigger than b')print(a**2)else:print('b is bigger than a')print(b**2)
b is bigger than a
1210000
Important
Please do not forget to add the colon after the condition and also after the else statement. The indentation is used to specify the sub-process that the program executes when the condition is either satisfied or not satisfied.
3.1.1 Extended Conditions
The keyword elif is used to add additional conditions.
if a > b:print('a is bigger than b')elif a ==0:print('a is 0')else:print('a is neither zero or bigger than b')
a is 0
One Liners
The conditional statements can also be included as one-liners !
if a <1: print('a is less than 1') # One liner if
a is less than 1
print('a is less than one') if a <1elseprint('a greater than 1') # One liner if.. else
a is less than one
and, or
If multiple conditions have to be tested, and and or keywords can be used !
if b > a and a ==0: print('b is greater than a and a is equal to 0')
b is greater than a and a is equal to 0
if b > a or a ==0: print('b is greater than a and a is equal to 0') # short-circuiting
b is greater than a and a is equal to 0
x =50if x >10:print("Above ten,")if x >20:print("and also above 20!")print(x**2)else:print("but not above 20.")
Above ten,
and also above 20!
2500
3.2 Loop Constructs
Loop constructs are used to repeatedly execute a block of code as long as a specific condition is met. Python provides two main types of loop constructs: the “for” loop and the “while” loop. These loop constructs are fundamental for iterating over sequences, performing repetitive tasks, and controlling the flow of your programs.
3.2.1 While Loop:
The “while” loop in Python repeatedly executes a block of code as long as a specified condition remains true. It’s often used when you don’t know in advance how many times the loop will run.
Here’s the basic structure of a “while” loop in Python:
while condition:# Code to be executed as long as the condition is true
condition: The loop continues executing as long as this condition evaluates to True.
In addition to these basic loop constructs, Python also supports control statements like break and continue to control the flow within loops. The break statement allows you to exit a loop prematurely based on a certain condition, while the continue statement allows you to skip the rest of the current iteration and move to the next one.
k =1while k <6: # the code in the intedentation is executed until the condition is true !print('in loop') print(k) k = k +1
in loop
1
in loop
2
in loop
3
in loop
4
in loop
5
Sometimes it maybe wise to stop the computation in the framework of a while loop if a certain condition is met.
k =1while k <1000:if k >20:breakprint('The value of k is: {k_value}'.format(k_value=k)) # format is used to inject data into a string ! k = k +1
The value of k is: 1
The value of k is: 2
The value of k is: 3
The value of k is: 4
The value of k is: 5
The value of k is: 6
The value of k is: 7
The value of k is: 8
The value of k is: 9
The value of k is: 10
The value of k is: 11
The value of k is: 12
The value of k is: 13
The value of k is: 14
The value of k is: 15
The value of k is: 16
The value of k is: 17
The value of k is: 18
The value of k is: 19
The value of k is: 20
Without the break statement, the while loop would continue until the final value of 1000 !
We initialize a counter count to 1 and iterate while count is less than or equal to 10. When count is equal to 5, we use continue to skip the current iteration, so 5 is not printed. For all other values of count, we print the number and increment count by 1.
3.2.2 For Loop:
The “for” loop in Python is primarily used for iterating over sequences like lists, tuples, strings, and dictionaries, as well as other iterable objects. It iterates over each element in the sequence and executes a specified block of code for each element.
Here’s the basic structure of a “for” loop in Python:
for variable in iterable:# Code to be executed for each element
variable: This is a variable that represents the current element in the iterable.
iterable: The sequence or iterable object over which the loop iterates.
The for keyword is used to loop over a sequence (list, tuple, dictionary, set, or a string).
In Python, the for loop can be used with various types of iterables. An iterable is an object that can be iterated upon, meaning that you can loop over its elements one at a time.
my_list_of_data = [1, 'test', 3, 4]
for d in my_list_of_data:print(d)
1
test
3
4
In case a certain value in the sequence needs to be skipped from processing, the keyword continue can be used.
Tuples inside lists can be accessed through the for loop.
list_of_tuples = [(1, 3), (10, 30), (100, 300)]
for small, big in list_of_tuples:print('This is the small number:'+str(small))print('This is the big number:'+str(big))
This is the small number:1
This is the big number:3
This is the small number:10
This is the big number:30
This is the small number:100
This is the big number:300
You can iterate over the characters of a string using a for loop.
my_text ='data_file.xls'file_extension = []for character in my_text: if character =='.': file_extension = [] file_extension.append(character)empty_delimiter =''print(empty_delimiter.join(file_extension))
.xls
You can iterate over the keys, values or items of a dictionary using a for loop.
material = {'name': 'Iron', 'Symbol': 'Fe', 'Atomic radius (pm)': 126}
for key, value in material.items():print(key, ':', value)
name : Iron
Symbol : Fe
Atomic radius (pm) : 126
Tip
One can quickly loop over integer sequences using the range function. A range object represents a sequence of numbers. You can iterate over the numbers in a range object using a for loop.
The command range() is often used to generate a list when performing iterative computations ! range(n) generates an iterator starting at 0 and ending at n-1.
# prints a functionfor x inrange(6): y = x + x**2+ x**0.3print(x, y)
In case the increment does not need to be in steps of one but in steps of another fixed value, the range(start, stop, step) specification can be used !
my_data = []for z inrange(0, 101, 10): # range(start:stop:step) 100 items starting at 0 ends at 99 ! y = z + z**2+ z**0.3 my_tuple = (z, y) my_data.append(my_tuple)
A generator expression is a concise way to create a generator object, which is an iterable that generates values on-the-fly. You can iterate over the values generated by a generator expression using a for loop.
squares = (x**2for x inrange(1, 6))
squares
<generator object <genexpr> at 0x174c53ac0>
type(squares)
generator
# define a generator for generating squaresfor square in squares:print(square)
1
4
9
16
25
3.4 Iterators
In Python, an iterator is an object that represents a sequence of values. Iterators can be used to loop over a sequence of values one at a time, without loading the entire sequence into memory at once. This can be especially useful for working with large datasets or for situations where memory is limited.
Historically, the concept of iterators has been important in computer science because it helps programmers optimize their code and improve its performance. Prior to the development of iterators, programmers would often use loops and conditionals to work with sequences of values. However, this approach could be inefficient and lead to performance issues when working with large datasets.
In Python, iterators are implemented using the iter() function, which takes a sequence object and returns an iterator object. You can then use the next() function to retrieve the next value from the iterator, or use a for loop to iterate over all the values in the sequence.
my_list = [1, 2, 3]my_iter =iter(my_list)
type(my_iter)
list_iterator
print(next(my_iter))
1
for item in my_iter:print(item);# 3
2
3
In this example, we create a list of values called my_list, and then use the iter() function to create an iterator object called my_iter. We then use the next() function to retrieve the first three values from the iterator, and use a for loop to iterate over the remaining values. Iterators are an important concept in Python and can be used in a variety of contexts, including working with files, databases, and other data sources. By understanding iterators and how they work, programmers can write more efficient and effective Python code.
Note
The for loop actually creates an iterator object and executes the next() method for each loop.
3.5 Itertools
The itertools module in Python provides a set of tools for working with iterable objects like lists, tuples, and iterators. These tools are designed to be fast and memory-efficient, and can be used to perform complex tasks with minimal code.
Here is a brief description on some of the most commonly used tools in the itertools module:
count(start=0, step=1) returns an iterator that generates a sequence of numbers starting from start and incrementing by step at each iteration.
import itertools# Generate a sequence of numbers starting from 0 and incrementing by 2for i in itertools.count(0, 2):if i >10:breakprint(i)
0
2
4
6
8
10
cycle(iterable) returns an iterator that cycles through the elements of iterable indefinitely.
my_list = [1, 2, 3, 4]counter =0for i in itertools.cycle(my_list): counter +=1if counter >10:breakprint(i)
1
2
3
4
1
2
3
4
1
2
repeat(elem, n=None) returns an iterator that generates the elem value n times, or indefinitely if n is not specified.
for i in itertools.repeat(5, 5):print(i)
5
5
5
5
5
chain(*iterables) takes multiple iterables as arguments and returns a single iterator that produces the elements of each iterable in sequence.
list1 = [1, 2, 3]list2 = [4, 5, 6]list3 = [7, 8, 9]for i in itertools.chain(list1, list2, list3):print(i)
1
2
3
4
5
6
7
8
9
product(*iterables, repeat=1) returns an iterator that produces the Cartesian product of the input iterables, with repeat specifying the number of repetitions of each input iterable.
Error handling in Python is a technique used to gracefully handle unexpected or exceptional situations that may arise during the execution of a program. Python provides a way to catch and manage errors or exceptions using try and except blocks. Here’s a brief introduction to error handling in Python with an example:
In Python, exceptions are raised when an error occurs during program execution. These exceptions can be built-in errors (e.g., ValueError, IndexError) or custom exceptions defined by the programmer.
The basic syntax for error handling in Python is as follows:
try:# Code that may raise an exceptionexcept ExceptionType1:# Code to handle ExceptionType1except ExceptionType2:# Code to handle ExceptionType2else:# Code to execute if no exceptions are raisedfinally:# Code to execute regardless of whether an exception occurred or not
try: This block contains the code where you anticipate an exception might occur.
except: If an exception of the specified type occurs within the try block, the corresponding except block will be executed. You can have multiple except blocks to handle different types of exceptions.
else (optional): This block is executed if no exceptions occur in the try block.
finally (optional): This block is always executed, whether an exception occurred or not. It is typically used for cleanup operations, such as closing files or releasing resources.
Here’s an example that demonstrates error handling in Python:
try: num1 =25 num2 =0 result = num1 / num2exceptZeroDivisionError:print("Error: Division by zero is not allowed.")exceptValueError:print("Error: Please enter valid numeric values.")else:print(f"Result of division: {result}")finally:print("Program execution completed.")
Error: Division by zero is not allowed.
Program execution completed.
In this example:
We attempt to get two integer inputs from the user and perform division in the try block.
If the user enters non-numeric values, a ValueError exception is caught in the first except block.
If the user enters a denominator of zero, a ZeroDivisionError exception is caught in the second except block.
If no exceptions occur, the else block calculates and prints the result.
The finally block is always executed, providing a message that the program execution is completed.
Error handling allows your program to handle exceptional conditions without crashing, making your code more robust and user-friendly. It’s an essential part of writing reliable Python programs.
3.7 Example from data: Hours of Sunshine
Sunshine hours play a crucial role in assessing the potential for renewable energy investment, particularly in solar power. Essentially, sunshine hours refer to the duration of time during which sunlight reaches the Earth’s surface. This metric is pivotal for determining the viability and effectiveness of solar energy generation in a particular region.
Regions with higher sunshine hours generally have greater solar energy potential. By analyzing historical data on sunshine hours, investors and policymakers can identify areas where solar energy projects are likely to yield optimal results. This information enables strategic decision-making regarding the allocation of resources for renewable energy infrastructure.
Moreover, sunshine hours serve as a key parameter for evaluating the economic feasibility of solar energy projects. Higher sunshine hours typically translate to increased energy production, which can lead to greater returns on investment over the project’s lifespan. Additionally, areas with abundant sunshine hours may benefit from reduced reliance on fossil fuels, thereby contributing to environmental sustainability and mitigating climate change.
The csv file with the following data-structure is available in the data folder. This is a short excert from the file.
Country
City
Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dec
Year
Finland
Helsinki
38.0
70.0
138.0
194.0
284.0
297.0
291.0
238.0
150.0
93.0
36.0
29.0
1858
France
Lyon
74.0
101.0
170.0
191.0
221.0
254.0
283.0
253.0
195.0
130.0
76.0
54.0
2002
France
Marseille
150.0
156.0
215.0
245.0
293.0
326.0
366.0
327.0
254.0
205.0
156.0
143.0
2836
France
Nice
156.7
166.1
218.0
229.2
270.9
309.8
349.3
223.2
249.8
191.1
151.5
145.2
2760.5
France
Paris
63.0
79.0
129.0
166.0
194.0
202.0
212.0
212.0
168.0
118.0
68.0
51.0
1662
Georgia
Tbilisi
99.0
102.0
142.0
171.0
213.0
249.0
256.0
248.0
206.0
164.0
103.0
93.0
2046
Germany
Berlin
47.0
74.0
121.0
159.0
220.0
222.0
217.0
211.0
156.0
112.0
51.0
37.0
1626
Germany
Frankfurt
50.0
80.0
121.0
178.0
211.0
219.0
233.0
219.0
156.0
103.0
51.0
41.0
1662
Greece
Athens
130.0
134.0
183.0
231.0
291.0
336.0
363.0
341.0
276.0
208.0
153.0
127.0
2773
Hungary
Budapest
62.0
93.0
137.0
177.0
234.0
250.0
271.0
255.0
187.0
141.0
69.0
52.0
1988
Iceland
Reykjavik
20.0
60.0
109.0
164.0
201.0
174.0
168.0
155.0
120.0
93.0
41.0
22.0
1326
Ireland
Dublin
59.0
75.0
109.0
160.0
195.0
179.0
164.0
157.0
129.0
103.0
71.0
53.0
1453
Italy
Cagliari
150.0
163.0
209.0
218.0
270.0
311.0
342.0
321.0
243.0
209.0
150.0
127.0
2726
Italy
Milan
59.0
96.0
152.0
177.0
211.0
243.0
285.0
251.0
186.0
130.0
66.0
59.0
1915
Italy
Naples
115.0
128.0
158.0
189.0
245.0
279.0
313.0
295.0
234.0
189.0
126.0
105.0
2375
Italy
Rome
121.0
133.0
167.0
201.0
264.0
285.0
332.0
298.0
237.0
195.0
129.0
112.0
2473
3.7.1 Identify the top 10 cities with the highest sunlight hours per year
import csv# Path to your CSV filecsv_file_path ='data/Sunshine hours for cities in the world.csv'import csvwithopen(csv_file_path, mode='r') asfile: csv_reader = csv.reader(file)# Read data into a list of lists data = []# Skip the header if your CSV has one# headers = data.pop(0)# Ensure the last column is numeric (int or float)for row in csv_reader:try: row[-1] =float(row[-1]) # Convert to float data.append(row)exceptValueError:pass# Handle the error or skip rows with non-numeric last column# Sorting in descending order sorted_data =sorted(data, key=lambda x: x[-1], reverse=True) city_data = []# Print the 10 highest sun counter =1for row in sorted_data: city_data.append((row[0] +'-'+ row[1], row[-1])) counter +=1if counter >10:breakcity_data
3.7.2 Get the average sunlight a country recieves per year and plot this data
import csv# Initialize an empty dictionary for the datacountry_city_sunlight = {}# Open the CSV filewithopen(csv_file_path, 'r') asfile: csv_reader = csv.reader(file)# Skip the header rownext(csv_reader)# Iterate over each row in the CSVfor row in csv_reader: country, city, *sunlight_hours = row sunlight_hours =tuple(map(float, sunlight_hours)) # Convert sunlight hours to float and make a tuple# Check if the country is already in the dictionaryif country notin country_city_sunlight: country_city_sunlight[country] = {}# Add the city and its sunlight hours to the country's dictionary country_city_sunlight[country][city] = sunlight_hours[-1]country_sunlight = {}for country, city_data in country_city_sunlight.items(): country_sunlight[country] =0for city, sunlight in city_data.items(): country_sunlight[country] += sunlight country_sunlight[country] = country_sunlight[country]/len(city_data.items()) country_sunlight =sorted(country_sunlight.items(), key=lambda x: x[1], reverse=True)
Show the code
import matplotlib.pyplot as plt# Unpacking the tuples into two listslabels, values =zip(*country_sunlight)# Normalize values for colormapnorm = plt.Normalize(vmin=min(values), vmax=max(values))cmap = plt.get_cmap('Spectral_r') # Use 'Spectral_r' to reverse the colormapcolors = [cmap(norm(value)) for value in values]# Creating the plotplt.figure(figsize=(6, 18))bars = plt.barh(labels, values, color=colors)# Adding some labels and title for clarityplt.xlabel('Average Sunlight per Year [Hours]')plt.ylabel('Country')plt.tight_layout() # Adjust layout to make room for the horizontal bar labelsplt.show()
Sunshine hours per country
3.8 Exercises
3.8.1 Theory
Write a brief explanation of the difference between a “for” loop and a “while” loop in Python.
Explain the purpose of the “break” and “continue” statements in Python.
Describe the concept of “nested” control flow in Python, and provide an example.
What is the difference between an “if” statement and an “if-else” statement in Python? Provide an example of when you would use each.
Explain the concept of “short-circuiting” in Python and provide an example.
3.8.2 Coding
Write a Python code that:
takes a list of numbers as input and returns the sum of all the even numbers in the list.
reads in a list of integers from the user and prints the maximum value in the list, as well as the index at which it occurs.
prompts the user to enter a number and then uses a “for” loop to print out the first 10 multiples of that number.
reads in a list of integers and then removes all duplicates from the list. The program should print the modified list.
Generate a list of prime numbers upto 1000 ! Hint: Use append() function to add items to the list !
Generate a list of the Fibonacci numbers ! Hint: \(f_n = f_{n-1} + f_{n-2}\)