π Introduction to Branching#
Utility of branching#
Branching causes specific blocks of code to be executed only under certain conditions. The conditions are articulated as logical expressions.
How do you write branching statements?#
The simplest version of branching statement is an βif statementβ.
if logical_expression:
code_block
def categorize_student_by_gpa(gpa):
"""
Categorizes a student based on their GPA according to hypothetical Drexel Engineering honors criteria.
Parameters:
gpa (float): The GPA of the student.
Returns:
str: The honors category of the student.
"""
if gpa >= 3.9:
return 'Summa Cum Laude' # Highest honors
# Example usage
student_gpa = 3.85
honors_category = categorize_student_by_gpa(student_gpa)
print(f"A student with a GPA of {student_gpa} graduates {honors_category}.")
A student with a GPA of 3.85 graduates None.
More complex structures are possible with βif-else statementsβ.
if logical_expression_A:
code_block_1
elif logical_expression_B:
code_block_2
elif logical_expression_C:
code_block_3
else:
code_block_4
def categorize_student_by_gpa(gpa):
"""
Categorizes a student based on their GPA according to hypothetical Drexel Engineering honors criteria.
Parameters:
gpa (float): The GPA of the student.
Returns:
str: The honors category of the student.
"""
if gpa >= 3.9:
return 'Summa Cum Laude' # Highest honors
elif gpa >= 3.7:
return 'Magna Cum Laude' # High honors
elif gpa >= 3.5:
return 'Cum Laude' # Honors
else:
return 'No honors' # Below the honors threshold
# Example usage
student_gpa = 3.85
honors_category = categorize_student_by_gpa(student_gpa)
print(f"A student with a GPA of {student_gpa} graduates {honors_category}.")
A student with a GPA of 3.85 graduates Magna Cum Laude.
Using branching in basic control theory#
Many engineering interventions aim to maintain an optimal setting in a system. Control theory is the basis for achieving these optimal conditions as smoothly and consistently as possible.
One very common example is temperature control in buildings.
Architectural engineers learn how to design heating, ventilation, and air conditioning systems throughout buildings that allow temperature in a room to be controlled.
Electrical engineers help with innovating the sensors and controls that allow for the temperature to be optimized.
Material scientists improve designs of windows and doors to enhance the controllability of the temperature and sustainability of the optimal conditions.
The thermostat typically acts as both the sensor collecting feedback and the controller determining whether the process should be heating, cooling, or no intervention.
The very simplest process control requires only the process variable, or the room temperature in this case, and the set point, or the desired temperature in this case.
def thermostat(roomTemp, desiredTemp):
"""
Changes the status of the thermal control devices based
on the room temperature and desired temperature
(Python Numerical Methods, MIT license)
:type temp: Int
:type desiredTemp: Int
:rtype: String
"""
if roomTemp < desiredTemp - 5:
device = "heat"
elif roomTemp > desiredTemp + 5:
device = "AC"
else:
device = "nothing"
return device
currentT = 58
desiredT = 64
device = thermostat(currentT, desiredT)
print(
f"When the temperature is {currentT} degrees Fahrenheit, activate {device} to achieve {desiredT} degrees Fahrenheit."
)
When the temperature is 58 degrees Fahrenheit, activate heat to achieve 64 degrees Fahrenheit.
currentT = 85
desiredT = 78
device = thermostat(currentT, desiredT)
print(
f"When the temperature is {currentT} degrees Fahrenheit, activate {device} to achieve {desiredT} degrees Fahrenheit."
)
When the temperature is 85 degrees Fahrenheit, activate AC to achieve 78 degrees Fahrenheit.
currentT = 80
desiredT = 75
device = thermostat(currentT, desiredT)
print(
f"When the temperature is {currentT} degrees Fahrenheit, activate {device} to achieve {desiredT} degrees Fahrenheit."
)
When the temperature is 80 degrees Fahrenheit, activate nothing to achieve 75 degrees Fahrenheit.
Perhaps you have a roommate who is very sensitive to temperature changes. How could you change the thermostat
function to keep the room temperature closer to the set point?
def thermostat(roomTemp, desiredTemp):
"""
Changes the status of the thermal control devices based
on the room temperature and desired temperature
(Python Numerical Methods, MIT license)
:type temp: Int
:type desiredTemp: Int
:rtype: String
"""
if roomTemp < desiredTemp - 5:
device = "heat"
elif roomTemp > desiredTemp + 5:
device = "AC"
else:
device = "nothing"
return device
What are at least three other processes you can think of that would similarly rely on branching, especially in your field of study?
Other methods of flow control in Python#
Python introduced match
statements in version 3.10 as a part of structural pattern matching.
For mechanical engineers, this feature can be particularly useful for creating more readable and efficient code when dealing with simulations, data processing, or any scenario involving multiple conditions that need to be checked against specific patterns or values.
A
match
statement takes an expression and compares its value to successive patterns given in different case blocks.Itβs akin to a more powerful version of the switch statement found in other programming languages, with the added ability to match complex patterns, not just single values.
match expression:
case pattern1:
# Block of code
case pattern2:
# Block of code
# Additional cases as needed
case _:
# Block of code for the default case (optional)
Letβs consider a scenario where a mechanical engineer needs to process data from different types of sensors in a mechanical system, such as temperature, pressure, and flow sensors. Each sensor type might require a different processing algorithm.
sensor_data = ('temperature', 23.5) # Example sensor data tuple
match sensor_data:
case ('temperature', value):
print(f"Processing temperature data with value {value}Β°C")
case ('pressure', value):
print(f"Processing pressure data with value {value}psi")
case ('flow', value):
print(f"Processing flow data with value {value}L/min")
case _:
print("Unknown sensor type")
Processing temperature data with value 23.5Β°C
Advanced Pattern Matching#
Pattern matching in Python is not limited to simple value comparisons. It can include complex structures, such as lists, dictionaries, and even custom classes. This feature can be particularly powerful for mechanical engineers working with structured data, enabling concise and readable code for complex conditional logic.
simulation_results = [
{'type': 'gear', 'data': {'teeth': 32, 'material': 'steel', 'failure_mode': 'wear'}},
{'type': 'bearing', 'data': {'load': 1500, 'material': 'ceramic', 'performance': 'optimal'}},
{'type': 'shaft', 'data': {'length': 120, 'diameter': 10, 'failure_mode': 'buckling'}}
]
for result in simulation_results:
match result:
case {'type': 'gear', 'data': {'teeth': teeth, 'material': mat, 'failure_mode': 'wear'}}:
print(f"Gear with {teeth} teeth made of {mat} failed due to wear.")
case {'type': 'bearing', 'data': {'load': load, 'material': 'ceramic', 'performance': 'optimal'}}:
print(f"Ceramic bearing with load {load} N performed optimally.")
case {'type': 'shaft', 'data': {'length': length, 'diameter': dia, 'failure_mode': mode}}:
print(f"Shaft with length {length}mm and diameter {dia}mm failed due to {mode}.")
case _:
print("Unknown component or data format.")
Gear with 32 teeth made of steel failed due to wear.
Ceramic bearing with load 1500 N performed optimally.
Shaft with length 120mm and diameter 10mm failed due to buckling.
Explanation#
Pattern Matching with Dictionaries: This example demonstrates pattern matching with dictionaries, where each
case
block matches results based on both the type of component ('type'
) and details within the'data'
dictionary. This allows for very specific processing logic tailored to each component and its simulation outcomes.Variable Binding in Patterns: Notice how variables (e.g.,
teeth
,load
,length
,dia
) are directly bound within the pattern. This means that if the pattern matches, these variables are automatically assigned the corresponding values from the matched data, allowing for their immediate use within the case block.Deep Matching: The example showcases deep matching where not just the outermost dictionary is matched against, but also nested structures within the
'data'
key. This capability is particularly useful for dealing with complex data structures common in engineering analyses.
The notes for Session 5 benefitted from the availability of Python Programming and Numerical Methods: A Guide for Engineers and Scientists through the MIT License.