Introduction to Computing

Chapter 6
Programming Fundamentals

Bachelor Program in Mechatronics Engineering
Introduction to Computing   •   Bachelor

Programming Fundamentals

Introduction

Programming is the systematic construction of instructions that a computer can execute to transform inputs into outputs. For mechatronics engineers, programming connects physical systems—sensors, actuators, motors, controllers, and communication networks—with algorithms that interpret measurements and make decisions. A temperature-control system, for example, may read a sensor, compare the reading with a set point, calculate an error, and adjust a heater. These activities require variables, expressions, control structures, functions, collections, files, modular design, and reliable error handling.

This chapter uses Python-like notation because it is readable and widely used in engineering education. The underlying ideas apply to C, C++, Java, MATLAB, and embedded languages, although syntax and memory behavior differ.

Learning Objectives

After studying this chapter, you should be able to:

  • distinguish variables, constants, data types, and expressions;
  • construct programs using sequence, selection, and iteration;
  • design and call functions with parameters and return values;
  • use arrays, lists, dictionaries, and sets appropriately;
  • read and write text files safely;
  • organize code into modules;
  • explain basic object-oriented concepts;
  • identify and handle common exceptions;
  • evaluate programs for correctness, readability, maintainability, and safety.

1. Programs, Algorithms, and the Execution Model

An algorithm is a finite, ordered procedure for solving a problem. A program is an algorithm expressed in a programming language together with the data and instructions needed for execution. A useful engineering workflow is:

  1. specify the problem and assumptions;
  2. identify inputs, outputs, and constraints;
  3. design an algorithm using pseudocode or a flowchart;
  4. implement the algorithm;
  5. test normal, boundary, and erroneous cases;
  6. document and maintain the result.

Most imperative programs can be understood through three control patterns:

  • Sequence: instructions execute in order.
  • Selection: a condition chooses between alternatives.
  • Iteration: a group of instructions repeats.

For example, a sensor-monitoring algorithm might be described as: read temperature; if it exceeds the limit, switch on cooling; otherwise switch cooling off; record the result; repeat. This description is independent of a particular language.

A program operates on state. State consists of values stored in memory at a particular time. An assignment changes state. In x = x + 1, the symbol x on the left means “replace the stored value,” whereas x on the right means “use the current value.”

2. Variables, Constants, and Data Types

A variable is a named reference to a value. A declaration or assignment associates a name with data. In Python-like syntax:

speed = 1500
voltage = 24.0
motor_enabled = True
label = "Motor A"

The data type determines what values are valid and what operations are meaningful. Common types are shown below.

TypeTypical valuesCommon use
Integer-3, 0, 42counts, indexes, whole units
Floating-point3.14, -0.02measured or calculated real quantities
BooleanTrue, Falseconditions and status
String"ready"text and identifiers
List/array[2, 4, 6]ordered collection
Dictionary/map{"id": 7}key–value records
None/nullNoneabsence of a value

A constant is a value that should not change during a computation, such as a conversion factor or safety limit. Some languages enforce constants; in Python, uppercase naming communicates intent:

MAX_TEMPERATURE = 80.0
GRAVITY = 9.80665

Names should be descriptive, consistent, and case-sensitive. A name such as current_A communicates more than i, especially in engineering code. Units should be explicit in names or documentation. Storing millimeters in one variable and meters in another without clear naming is a frequent source of faults.

Numeric Representation and Precision

Integers represent whole numbers exactly within their supported range. Floating-point values approximate real numbers using finite binary representation. Consequently, direct equality comparisons can be unsafe:

0.1 + 0.2 == 0.3       # may be False in binary floating-point

For measurements, compare within a tolerance. If x and y are values and ε is a nonnegative tolerance, they may be considered equal when:

|x − y| ≤ ε

The tolerance must reflect measurement resolution, numerical error, and the engineering decision being made. It is not universally correct to choose an arbitrary value.

3. Operators and Expressions

An expression combines values, variables, and operators to produce a result. Arithmetic operators include addition, subtraction, multiplication, division, integer division, remainder, and exponentiation. Relational operators compare values; logical operators combine Boolean conditions.

power = voltage * current
safe = temperature <= MAX_TEMPERATURE and current < 5.0

Operator precedence determines evaluation order, but parentheses improve clarity and prevent mistakes. The expression a + b c normally multiplies before adding; (a + b) c gives a different result.

A Boolean condition should express a meaningful engineering rule. For example:

if pressure < MIN_PRESSURE:
    raise_alarm()

Short-circuit evaluation is important. In x != 0 and y / x > 2, the second condition is evaluated only if x is not zero, preventing division by zero. However, safety-critical software should not rely only on implicit behavior; explicit validation and tests are preferable.

4. Control Structures

Selection

Selection executes different statements according to conditions.

if temperature > 80:
    state = "overheat"
elif temperature < 5:
    state = "too_cold"
else:
    state = "normal"

Conditions should be mutually understandable. Overlapping ranges, reversed inequalities, and missing boundary cases can produce unsafe behavior. Decide explicitly whether a boundary such as 80 °C belongs to the normal or alarm region.

Iteration

A for loop is suitable when iterating over a collection or known range:

for reading in readings:
    total += reading

A while loop is suitable when repetition depends on a condition:

while system_enabled:
    reading = read_sensor()
    control(reading)

Every while loop should have a demonstrably reachable termination condition unless it is intentionally an embedded service loop. A loop invariant is a statement that remains true during iteration; for a running sum, the invariant may be that total equals the sum of all readings processed so far.

break terminates a loop, and continue skips to the next iteration. These statements can be useful but excessive use may obscure control flow. In industrial systems, loops should also address communication timeouts, watchdogs, and loss of sensor data.

Worked Example: Average and Alarm Decision

Suppose four temperature readings are 21.0, 22.5, 23.0, and 21.5 °C. The arithmetic mean is:

x̄ = (x₁ + x₂ + … + xₙ) ÷ n

where xᵢ is reading i and n is the number of readings. Here, the sum is 88.0 °C and n = 4, so x̄ = 22.0 °C. A program can calculate the mean and compare it with an alarm threshold:

readings = [21.0, 22.5, 23.0, 21.5]
average = sum(readings) / len(readings)
if average > 30.0:
    print("Alarm")
else:
    print("Normal")

This calculation assumes that all readings are valid, expressed in the same unit, and equally weighted. It does not by itself detect a dangerous individual peak; a real design may check both the average and the maximum.

5. Functions and Modularity

A function is a named, reusable block that performs one coherent task. Parameters provide inputs, and a return value communicates a result.

def convert_mm_to_millimetres(value_m):
    return value_m * 1000.0

The example name is intentionally illustrative; a better function for converting metres to millimetres would be:

def metres_to_millimetres(value_m):
    return value_m * 1000.0

Functions reduce duplication and make testing easier. A good function generally has a clear purpose, limited side effects, meaningful names, and documented assumptions. Validate arguments at the boundary:

def set_speed(speed_rpm):
    if speed_rpm < 0:
        raise ValueError("speed cannot be negative")
    return speed_rpm

A local variable exists within a function’s scope. A global variable is accessible broadly and can create hidden dependencies; it should be minimized. Passing values explicitly makes data flow easier to inspect.

A module is a file containing related definitions. A larger system might contain sensors.py, control.py, logging_utils.py, and main.py. Modularity separates concerns: sensor acquisition should not be tightly mixed with user-interface code or file formatting. This improves reuse, testing, and maintenance.

6. Arrays and Collections

An array stores an ordered sequence, commonly with elements of the same type and efficient indexed access. Many languages use zero-based indexing, so the first element has index 0. If an array has n elements, valid indexes are 0 through n − 1.

Python lists are flexible collections:

forces = [10.2, 11.0, 9.8]
forces.append(10.5)
first = forces[0]

A two-dimensional list can represent a table, but numerical libraries may provide safer and faster matrix structures. A tuple represents an ordered collection that is not intended to change. A set stores unique elements and is useful for membership tests. A dictionary maps keys to values:

sensor = {"id": "T01", "unit": "degC", "value": 24.6}
print(sensor["value"])

Choose a collection according to the required operation. Use a list for order, a set for uniqueness, and a dictionary for lookup by meaningful key. Validate indexes and keys, and avoid modifying a collection while iterating over it unless the language and algorithm explicitly support that operation.

7. Files and Persistent Data

Variables normally disappear when a program terminates. Files provide persistent storage for configuration, logs, calibration data, and test results. A safe file workflow is open, read or write, and close. A context manager closes the file even if an error occurs:

with open("readings.csv", "r", encoding="utf-8") as file:
    for line in file:
        process(line)

When writing:

with open("log.txt", "a", encoding="utf-8") as file:
    file.write("24.6\n")

The mode "w" normally replaces an existing file, while "a" appends. Engineers must consider permissions, storage limits, interrupted writes, malformed records, timestamps, and data integrity. CSV is human-readable but requires attention to delimiters, quoted fields, and units. JSON is useful for structured configuration, but it is not automatically safe to load from untrusted sources.

Never construct file paths from unvalidated user input without considering path traversal. Logs may contain personal or operationally sensitive information and should be protected accordingly.

8. Basic Object-Oriented Concepts

Object-oriented programming organizes software around objects that combine state and behavior. A class is a blueprint; an object is an instance of that class. Encapsulation groups data and operations and controls how state is changed.

class Motor:
    def __init__(self, identifier, maximum_rpm):
        self.identifier = identifier
        self.maximum_rpm = maximum_rpm
        self.speed_rpm = 0

    def set_speed(self, requested_rpm):
        if not 0 <= requested_rpm <= self.maximum_rpm:
            raise ValueError("speed outside permitted range")
        self.speed_rpm = requested_rpm

Here, each Motor object has its own attributes and uses the set_speed method to enforce a constraint. Inheritance allows a class to derive behavior from another class, but composition—building a system from cooperating objects—is often easier to maintain. Polymorphism allows objects with a common interface to be used interchangeably. These benefits do not justify unnecessary complexity; a small script may be clearer without classes.

In mechatronics, classes can represent sensors, actuators, trajectories, and controllers. Hardware abstraction is especially valuable: a control algorithm can call sensor.read() without depending on whether the sensor is simulated, connected through USB, or attached to a microcontroller.

9. Exceptions, Validation, and Reliability

An exception is an event indicating that normal execution cannot continue safely, such as invalid input, a missing file, or division by zero. Handling an exception means deciding how the program should recover, report, or safely stop.

try:
    with open("config.txt", "r", encoding="utf-8") as file:
        configuration = file.read()
except FileNotFoundError:
    configuration = "default"
except OSError as error:
    report_error(error)

Catch specific exceptions rather than hiding all errors with a broad handler. Do not use exceptions as a substitute for ordinary validation. A robust program distinguishes recoverable conditions from dangerous ones. If a sensor fails in a machine-control system, the safe response may be to disable motion and notify an operator, not to continue with a guessed value.

Assertions document assumptions during development, but they should not replace operational safety checks. Testing should include normal inputs, boundary values, invalid types, missing files, communication failures, and repeated operation. Logging should include enough context to diagnose faults without exposing credentials or sensitive data.

10. An Integrated Application: Conveyor Inspection Logger

The following is an illustrative case, not a production safety-certified system.

Background and Problem

A small conveyor transports components past a sensor. The controller records each component’s measured length and classifies it as acceptable when its length lies between 48.0 mm and 52.0 mm. The system must count accepted and rejected components and save a log.

Analysis and Approach

The design requires constants for limits, a function for classification, a collection for records, a loop for processing, and file output. Measurements must be numeric and expressed in millimetres. A value exactly equal to a limit is accepted because the specification uses inclusive bounds.

LOWER_MM = 48.0
UPPER_MM = 52.0


def classify(length_mm):
    if not isinstance(length_mm, (int, float)):
        raise TypeError("length must be numeric")
    return "accepted" if LOWER_MM <= length_mm <= UPPER_MM else "rejected"


def process_batch(measurements):
    records = []
    counts = {"accepted": 0, "rejected": 0}
    for length in measurements:
        try:
            status = classify(length)
            counts[status] += 1
            records.append({"length_mm": length, "status": status})
        except (TypeError, ValueError) as error:
            records.append({"length_mm": length, "status": "invalid", "error": str(error)})
    return records, counts

measurements = [49.5, 52.0, 47.8, 50.1]
records, counts = process_batch(measurements)

The outcome is three accepted components and one rejected component. The boundary value 52.0 mm is accepted. In a real system, invalid measurements would require a defined physical response, such as stopping the conveyor or routing the component for inspection. A production implementation would also add timestamps, calibration status, sensor diagnostics, atomic logging, access control, and tests.

Learning Points

The case demonstrates separation of concerns: classification is isolated in a function, batch processing manages iteration and counting, and records preserve traceability. It also shows why requirements must define units and boundary behavior. A program can be syntactically correct yet operationally wrong if these decisions remain implicit.

11. Professional Practice, Ethics, and Contemporary Tools

Programming in engineering has direct safety consequences. Incorrect units, unchecked sensor values, race conditions, or silent exception handling can damage equipment or injure people. Professional practice therefore includes requirements traceability, code review, version control, automated tests, static analysis, and documented change control. Safety-related systems may be governed by organizational procedures and standards such as IEC 61508 or sector-specific regulations; the applicable standard depends on the industry and system risk.

Security is also part of correctness. Protect credentials, validate external input, restrict file and network permissions, and update dependencies. Avoid embedding secrets in source code.

Artificial-intelligence coding assistants can suggest code, tests, or explanations, but generated code may contain incorrect assumptions, insecure patterns, licensing concerns, or fabricated library behavior. Engineers remain responsible for reviewing, testing, documenting, and approving every program. Use AI as an aid to reasoning, not as a substitute for requirements analysis and verification.

Best practices include:

  • choose clear names and consistent formatting;
  • keep functions small and cohesive;
  • state units and assumptions;
  • validate at system boundaries;
  • test boundaries and failure modes;
  • use version control and peer review;
  • separate hardware interfaces from algorithms;
  • record decisions and limitations;
  • fail safely when uncertainty affects physical risk.

Chapter Summary

Programming transforms algorithms and data into executable behavior. Variables store state, data types define valid representations, and expressions calculate results. Sequence, selection, and iteration provide fundamental control flow. Functions and modules support abstraction, reuse, testing, and separation of concerns. Arrays and collections organize related information, while files provide persistence. Object-oriented programming combines state and behavior in objects and can abstract hardware interfaces. Exceptions and validation support reliable responses to invalid data and environmental failures. In mechatronics, programming quality is inseparable from unit consistency, boundary analysis, safety, security, testing, and professional accountability.

Key Terms

Variable: A named reference to a value that may change.

Constant: A value intended not to change during execution.

Data type: A classification defining valid values and operations.

Expression: A combination of values and operators producing a result.

Algorithm: A finite procedure for solving a problem.

Sequence: Execution of instructions in their written order.

Selection: Conditional choice between alternative paths.

Iteration: Repeated execution of a group of instructions.

Function: A reusable unit of behavior with inputs and possible output.

Parameter: A named input accepted by a function.

Scope: The region in which a name can be accessed.

Module: A file or unit containing related program definitions.

Array: An indexed, ordered collection of elements.

Dictionary: A key–value collection.

Class: A definition describing the state and behavior of objects.

Object: An instance of a class.

Exception: An event representing an abnormal execution condition.

Encapsulation: Combining state and operations while controlling access.

Validation: Checking whether data satisfies required conditions.

Invariant: A statement that remains true during an algorithmic process.

Review Questions

Short Answer Questions

  1. What is the difference between an algorithm and a program?
  2. Why should engineering variables communicate their units?
  3. When is a while loop preferable to a for loop?
  4. What is the purpose of a function parameter?
  5. Why should exceptions be caught specifically rather than hidden broadly?

Long Answer Questions

  1. Explain sequence, selection, and iteration and illustrate each with a mechatronics example.
  2. Compare lists, sets, and dictionaries, including an appropriate use for each.
  3. Explain how functions and modules improve maintainability and testing.
  4. Describe encapsulation, inheritance, polymorphism, and composition at an introductory level.
  5. Discuss the professional responsibilities involved in deploying software that controls physical equipment.

Analytical / Application Questions

  1. Design an algorithm for a tank controller that reads level, activates a pump below a lower limit, and stops it above an upper limit. Identify boundary behavior and failure responses.
  2. A data logger occasionally receives a missing value and a negative temperature where only nonnegative values are valid. Propose validation, exception handling, and logging behavior.
  3. Refactor a single long program that reads sensors, controls actuators, displays status, and writes files into modules and functions. Justify your proposed structure.

Multiple Choice Questions with Answers

Question 1

Which control structure selects one of several possible execution paths?

A. Sequence

B. Selection

C. Iteration

D. File handling

Correct Answer: B. Selection

Question 2

If an array contains n elements and uses zero-based indexing, what is its final valid index?

A. n

B. n + 1

C. n − 1

D. 1

Correct Answer: C. n − 1

Question 3

Which collection is most appropriate for mapping a sensor identifier to its current reading?

A. Set

B. Dictionary

C. Tuple only

D. Character string

Correct Answer: B. Dictionary

Question 4

What is the main purpose of a function return value?

A. To provide a result to the calling code

B. To delete local variables

C. To open a file automatically

D. To force an infinite loop

Correct Answer: A. To provide a result to the calling code

Question 5

Which file mode normally appends new data without replacing existing content?

A. r

B. w

C. a

D. x

Correct Answer: C. a

Question 6

In the conveyor case, which measurement is accepted when the inclusive range is 48.0 mm to 52.0 mm?

A. 47.8 mm

B. 48.0 mm

C. 52.1 mm

D. 53.0 mm

Correct Answer: B. 48.0 mm

Question 7

What does encapsulation primarily achieve?

A. Combining state and behavior while controlling access

B. Guaranteeing that every program is error-free

C. Converting all numbers to strings

D. Removing the need for testing

Correct Answer: A. Combining state and behavior while controlling access

Question 8

Why can direct equality comparison of floating-point results be unsafe?

A. Floating-point values cannot be printed

B. They are often finite approximations of real numbers

C. They are always stored as integers

D. They cannot be used in conditions

Correct Answer: B. They are often finite approximations of real numbers

Question 9

Which response is generally most appropriate for a dangerous sensor failure in a physical system?

A. Silently continue with an arbitrary value

B. Ignore the failure permanently

C. Apply a defined safe-state response and report the fault

D. Delete the sensor record

Correct Answer: C. Apply a defined safe-state response and report the fault

Question 10

What is a key advantage of separating hardware interfaces from control algorithms?

A. It prevents all hardware failures

B. It makes algorithms easier to test and replace across interfaces

C. It eliminates the need for data types

D. It guarantees faster execution

Correct Answer: B. It makes algorithms easier to test and replace across interfaces

Introduction to Computing
Chapter 6 of 15