Course & Module Outcomes
Course Outcomes
By the end of this course, students will be able to:
-
CO1
Use variables, arrays and object structures appropriate to solve engineering problems.Apply · Behavioral
-
CO2
Write computer functions to meet specific calculation needs.Apply · Behavioral
-
CO3
Write computer programs to solve mathematical expressions and engineering problemsApply · Behavioral
Outcomes Alignment Map
| Module / Outcome | CO1 | CO2 | CO3 |
|---|---|---|---|
| 1 - Python Environment Setup and Language Fundamentals | |||
| Select Appropriate Python | ✓ | ||
| Configure Isolated Virtual | ✓ | ||
| Construct Valid Python | ✓ | ||
| Differentiate Among Python's | ✓ | ||
| Apply Explicit Type | ✓ | ||
| 2 - Control Flow and Python Data Structures | |||
| Construct Conditional Statements | ✓ | ||
| Implement Loops While | ✓ | ||
| Manipulate Python Lists | ✓ | ||
| Differentiate Between Lists | ✓ | ||
| Select Appropriate Python | ✓ | ||
| 3 - Functions, Comprehensions, and Functional Patterns | |||
| Construct Python Functions | ✓ | ||
| Trace Python's Legb | ✓ | ||
| Implement Recursive Function | ✓ | ||
| Produce List Dictionary | ✓ | ||
| Evaluate Apply Lambda | ✓ | ||
| 4 - Modules, File I/O, and Error Handling | |||
| Construct Custom Python | ✓ | ||
| Apply With-statement Context | ✓ | ||
| Serialize Deserialize Structured | ✓ | ||
| Implement Try-except Blocks | ✓ | ||
| Select Appropriate Standard | ✓ | ||
| 5 - NumPy for Engineering Numerical Computation | |||
| Construct Numpy Arrays | ✓ | ||
| Apply Vectorized Element-wise | ✓ | ||
| Select Subsets Array | ✓ | ||
| Solve System Linear | ✓ | ||
| Calculate Descriptive Statistics | ✓ | ||
| 6 - Data Visualization with Matplotlib and Intro to Pandas | |||
| Construct Line Plots | ✓ | ||
| Compose Multi-panel Publication-quality | ✓ | ||
| Load Csv Dataset | ✓ | ||
| Compute Descriptive Statistics | ✓ | ||
| Evaluate Distribution Relationships | ✓ | ||
| 7 - Object-Oriented Programming and AI-Assisted Coding Workflow | |||
| Construct Python Classes | ✓ | ||
| Implement Class Hierarchies | ✓ | ||
| Formulate Effective Prompts | ✓ | ||
| Evaluate Ai-generated Engineering | ✓ | ||
| Apply Systematic Debugging | ✓ | ||
| Numerical Methods with SciPy and Curve Fitting | |||
| Select Appropriate Root-finding | ✓ | ||
| Apply Scipy.integrate Functions | ✓ | ||
| Fit Both Polynomial | ✓ | ||
| Construct Residual Plots | ✓ | ||
| Design End-to-end Numerical | ✓ | ||
| Engineering Data Analysis and Simulation | |||
| Construct End-to-end Engineering | ✓ | ||
| Produce Properly Formatted | ✓ | ||
| Implement Numerical Time-stepping | ✓ | ||
| Evaluate Accuracy Numerical | ✓ | ||
| Integrate Cleaned Measured | ✓ | ||
| Machine Learning, Automation, Version Control, and Responsible AI | |||
| Distinguish Between Regression | ✓ | ||
| Construct Scikit-learn Pipeline | ✓ | ||
| Design Parameter Sweep | ✓ | ||
| Apply Core Git | ✓ | ||
| Evaluate Ai-generated Code | ✓ | ||
Module Topics & Outcomes
Module 1: 1 - Python Environment Setup and Language Fundamentals
Topics
Python Programming Environments
Covers the tools and interfaces used to write and run Python code, including IDEs and Jupyter notebooks. Learners will understand how to choose an appropriate environment for different tasks.
- What Is a Python Environment? — A Python programming environment is the combination of tools, interpreters, and interfaces that allow a developer to write, run, and debug Python code.
- Integrated Development Environments (IDEs) — An IDE is a software application that provides comprehensive tools for writing and debugging code, typically including a code editor, debugger, and project manager in one interface.
- Jupyter Notebooks — Jupyter Notebook is an open-source, browser-based environment that allows you to write and execute Python code in discrete, runnable cells alongside narrative text and visualizations.
- The Python Interpreter and REPL — The Python interpreter is the program that reads and executes Python code. When launched interactively, it provides a Read-Eval-Print Loop (REPL) where each line of code is executed immediately.
Package Management in Python
Explores how Python packages extend the language's capabilities and how to install, manage, and organize them using tools like pip and virtual environments.
- What Are Python Packages? — A Python package is a collection of modules that provide pre-written code for specific tasks, allowing developers to reuse functionality without writing it from scratch.
- Using pip to Install Packages — pip is the default package manager for Python and allows users to install, upgrade, and remove packages from the command line.
- Virtual Environments — A virtual environment is an isolated Python environment that allows different projects to have their own dependencies without conflicting with one another.
Interactive vs. Script Execution
Distinguishes between running Python code interactively in a REPL or notebook and executing standalone Python script files. Learners will understand when to use each approach.
- Interactive Execution — Interactive execution allows a programmer to type Python statements one at a time and see results immediately, making it ideal for learning, testing, and data exploration.
- Script Execution — A Python script is a plain-text file with a .py extension that contains a sequence of Python statements executed from top to bottom when the file is run.
- Choosing the Right Execution Mode — Selecting between interactive and script execution depends on the goal: interactive mode suits exploration and learning, while script mode suits repeatable, structured programs.
Variables and Assignment
Introduces how Python uses variables to store and reference data, covering naming conventions, assignment syntax, and how Python manages variable references in memory.
- What Is a Variable? — A variable is a named reference that points to a value stored in memory, allowing programmers to store, retrieve, and manipulate data throughout a program.
- Naming Rules and Conventions — Python enforces specific rules for variable names and follows community conventions documented in PEP 8 to promote readable, consistent code.
- Multiple Assignment and Unpacking — Python supports assigning multiple variables at once, either to the same value or to individual values from a sequence, using concise syntax.
Core Data Types
Covers Python's fundamental built-in data types including integers, floats, strings, and booleans, explaining their characteristics and appropriate use cases.
- Integers and Floating-Point Numbers — Python provides two primary numeric types: integers (int) for whole numbers and floating-point numbers (float) for decimals and numbers requiring fractional precision.
- Strings — A string (str) is an ordered, immutable sequence of characters used to represent text in Python, enclosed in single or double quotation marks.
- Booleans — The boolean (bool) type represents one of two truth values — True or False — and is fundamental to controlling program flow through conditionals and loops.
- The None Type — None is a special singleton value in Python that represents the absence of a value or a null result, commonly used as a default or placeholder.
- Checking Data Types with type() — The built-in type() function returns the type of any Python object, allowing programmers to inspect and verify the data type of a variable at runtime.
Operators in Python
Introduces the main categories of Python operators — arithmetic, comparison, logical, and assignment — explaining their syntax, behavior, and precedence rules.
- Arithmetic Operators — Arithmetic operators perform mathematical calculations on numeric values, including addition, subtraction, multiplication, division, and more specialized operations.
- Comparison Operators — Comparison operators evaluate the relationship between two values and return a boolean result, forming the basis of conditional logic in Python programs.
- Logical Operators — Logical operators — and, or, and not — combine or invert boolean expressions and are central to building complex conditional statements.
- Assignment Operators — Assignment operators store a value in a variable, with augmented assignment operators providing a shorthand for updating a variable's value in place.
- Operator Precedence — Python evaluates expressions according to a defined order of precedence, determining which operations are performed first when multiple operators appear in a single expression.
Type Conversion
Explains how Python handles conversion between data types, distinguishing between implicit coercion performed automatically by Python and explicit conversion performed by the programmer.
- Implicit Type Conversion — Implicit type conversion, or coercion, occurs automatically when Python converts one data type to another to complete an operation without requiring any action from the programmer.
- Explicit Type Conversion with Built-in Functions — Explicit type conversion, also called casting, uses built-in functions such as int(), float(), str(), and bool() to deliberately convert a value from one type to another.
- Common Conversion Errors and How to Avoid Them — Incorrect type conversion attempts raise exceptions in Python, so understanding which conversions are valid and how to handle failures is an essential programming skill.
Learning Outcomes
MO1
Select an appropriate Python execution environment — such as an IDE, Jupyter Notebook, or REPL — for a given programming task
MO2
Configure an isolated virtual environment and install required packages using pip
MO3
Construct valid Python variable assignments that conform to PEP 8 naming conventions and utilize multiple assignment and unpacking syntax
MO4
Differentiate among Python's core built-in data types — int, float, str, bool, and None — by using the type() function to inspect variable types in a running program
MO5
Apply explicit type conversion functions to transform values between compatible data types while identifying conversions that raise exceptions
Module 2: 2 - Control Flow and Python Data Structures
Topics
Conditional Statements
Conditional statements allow a program to make decisions by executing different code blocks based on whether a condition evaluates to true or false. This topic covers if, elif, and else constructs in Python.
- The if Statement — The if statement is the most fundamental conditional construct in Python, executing a block of code only when a specified condition is True.
- The elif Clause — The elif (else-if) clause allows a program to check multiple conditions in sequence after an initial if condition fails.
- The else Clause — The else clause defines a default block of code that executes when none of the preceding if or elif conditions are True.
- Comparison and Logical Operators — Conditions in Python are built using comparison operators (==, !=, <, >, <=, >=) and logical operators (and, or, not) to form complex Boolean expressions.
- Nested Conditionals — Conditional statements can be placed inside other conditional blocks to test additional conditions when an outer condition is True.
for Loops and the range() Function
The for loop iterates over a sequence of items, making it ideal for processing collections of data. The range() function generates numeric sequences commonly used to control loop iterations.
- The for Loop — A for loop in Python iterates over each item in a sequence — such as a list, string, or range — executing the loop body once per item.
- The range() Function — The range() function generates an immutable sequence of integers and is commonly used with for loops to repeat an action a specific number of times.
- Iterating with an Index Using enumerate() — The enumerate() function allows a for loop to access both the index and the value of each item in an iterable simultaneously.
- Looping Over Numeric Ranges in Engineering — Engineering applications frequently require iterating over a defined numeric range, such as time steps in a simulation or indices in a data array.
while Loops
A while loop repeats a block of code for as long as a specified condition remains True, making it suitable for situations where the number of iterations is not known in advance.
- The while Loop Structure — A while loop continuously executes its body until its controlling condition evaluates to False, checking the condition before each iteration.
- Infinite Loops and Loop Guards — An infinite loop occurs when a while loop's condition never becomes False, causing the program to run indefinitely without halting.
- Comparing for and while Loops — Choosing between a for loop and a while loop depends on whether the number of iterations is known in advance or determined dynamically during execution.
Loop Control: break and continue
The break and continue statements provide fine-grained control over loop execution, allowing early termination or skipping specific iterations without exiting the loop entirely.
- The break Statement — The break statement immediately terminates the innermost loop it appears in, transferring control to the first statement after the loop.
- The continue Statement — The continue statement skips the remainder of the current loop iteration and jumps directly to the next iteration's condition check.
- The else Clause on Loops — Python allows an optional else clause on both for and while loops, which executes only if the loop completed normally without encountering a break statement.
- Practical Use Cases for break and continue — In engineering and data processing, break and continue are frequently used to handle exceptions in data, implement early-exit optimizations, and process conditional sequences.
Lists
Lists are ordered, mutable sequences that can hold items of any type, making them one of the most versatile and widely used data structures in Python.
- Creating and Accessing Lists — A list is created using square brackets and can store any mix of data types. Individual elements are accessed using zero-based integer indices.
- Modifying Lists — Because lists are mutable, their elements can be changed, added, or removed after the list is created using built-in methods and direct assignment.
- List Slicing — Slicing extracts a sub-list from a list using the syntax list[start:stop:step], returning a new list containing the selected elements.
- List Comprehensions — A list comprehension provides a concise, readable way to create a new list by applying an expression to each item in an iterable, optionally filtered by a condition.
- Common List Operations and Methods — Python provides a rich set of built-in functions and list methods for sorting, searching, counting, and transforming list data.
Tuples
Tuples are ordered, immutable sequences that are ideal for storing fixed collections of data that should not be changed after creation.
- Creating and Accessing Tuples — Tuples are defined using parentheses (or simply commas) and support the same indexing and slicing operations as lists, but their contents cannot be modified.
- Immutability of Tuples — Once a tuple is created, its elements cannot be added, removed, or changed, making tuples a safer choice when data integrity is important.
- Tuple Packing and Unpacking — Tuple packing assigns multiple values into a single tuple, while tuple unpacking assigns the elements of a tuple to individual variables in one statement.
- When to Use Tuples vs. Lists — Tuples are preferred when the data represents a fixed record or should be protected from modification, while lists are better suited for collections that need to grow or change.
Dictionaries
Dictionaries store data as key-value pairs, enabling fast lookups by key rather than by position, and are ideal for representing structured, labeled data.
- Creating and Accessing Dictionaries — Dictionaries are created using curly braces with colon-separated key-value pairs. Values are retrieved by supplying the corresponding key in square brackets.
- Modifying Dictionaries — Dictionaries are mutable; entries can be added, updated, or deleted at any time using direct assignment and built-in methods.
- Iterating Over Dictionaries — Python provides dedicated methods for iterating over a dictionary's keys, values, or key-value pairs using keys(), values(), and items().
- Engineering Applications of Dictionaries — Dictionaries are well suited for mapping labeled engineering data, such as material properties, configuration parameters, or named measurement channels.
Sets and Choosing the Right Data Structure
Sets store unique, unordered elements and support efficient membership testing and set operations. This topic also provides guidance on selecting the appropriate data structure for engineering problems.
- Creating and Using Sets — A set is an unordered collection of unique elements defined with curly braces or the set() constructor. It automatically discards duplicate values.
- Set Operations — Sets support mathematical operations including union, intersection, difference, and symmetric difference, enabling powerful comparisons between groups of data.
- Membership Testing with Sets — Sets provide O(1) average-time membership testing using the in operator, making them significantly faster than lists for checking whether a value exists in a large collection.
- Comparing Core Data Structures — Lists, tuples, dictionaries, and sets each have distinct properties — ordered vs. unordered, mutable vs. immutable, indexed vs. keyed — that make them appropriate for different tasks.
- Selecting the Right Structure for Engineering Problems — Choosing the appropriate data structure improves program correctness, performance, and readability, particularly in data-intensive engineering applications.
Learning Outcomes
MO1
Construct conditional statements using if, elif, and else clauses — combined with comparison and logical operators — to control program execution flow
MO2
Implement for loops, while loops, and loop control statements (break and continue) to iterate over sequences and numeric ranges in engineering contexts
MO3
Manipulate Python lists using indexing, slicing, list comprehensions, and built-in methods to process ordered collections of data
MO4
Differentiate between lists, tuples, dictionaries, and sets based on their properties of mutability, ordering, and access method
MO5
Select the appropriate Python data structure for a given engineering problem by evaluating the correctness, performance, and readability trade-offs among lists, tuples, dictionaries, and sets
Module 3: 3 - Functions, Comprehensions, and Functional Patterns
Topics
Defining Functions
Introduces the syntax and mechanics of creating reusable functions in Python. Covers the def keyword, naming conventions, and the role of the return statement.
- The def Statement — Functions in Python are defined using the def keyword followed by a name and a parenthesized parameter list. The indented block beneath the signature forms the function body.
- The return Statement — The return statement sends a value back to the caller and immediately exits the function. A function without an explicit return statement implicitly returns None.
- Docstrings and Function Documentation — A docstring is a string literal placed as the first statement inside a function body and serves as built-in documentation. It is accessible at runtime via the function's __doc__ attribute or the help() function.
- Calling a Function — A function is invoked by writing its name followed by parentheses containing any required arguments. The interpreter jumps to the function body, executes it, and resumes at the call site with the returned value.
Parameters and Arguments
Explores the different ways values can be passed into functions, including positional, keyword, and default parameters. Establishes clear terminology between parameters and arguments.
- Positional Parameters — Positional parameters are matched to arguments in the order they appear in the function signature. The first argument maps to the first parameter, the second to the second, and so on.
- Keyword Arguments — Keyword arguments are passed by explicitly naming the parameter they correspond to, allowing arguments to be supplied in any order. This improves readability, especially in functions with many parameters.
- Default Parameter Values — A parameter can be assigned a default value in the function signature, making the argument optional at the call site. If the caller does not supply that argument, the default is used.
- Parameters vs. Arguments Terminology — Parameters are the variable names listed in the function definition, while arguments are the actual values passed when the function is called. Keeping this distinction clear helps in reading error messages and documentation.
Variable-Length Arguments: *args and **kwargs
Covers the special *args and **kwargs syntax that allows functions to accept an arbitrary number of positional or keyword arguments. Explains how these mechanisms support flexible and reusable API design.
- Collecting Positional Arguments with *args — Prefixing a parameter name with an asterisk (*) causes Python to collect all extra positional arguments into a tuple assigned to that parameter. By convention the name args is used, though any valid identifier works.
- Collecting Keyword Arguments with **kwargs — Prefixing a parameter name with two asterisks (**) causes Python to collect all extra keyword arguments into a dictionary. The keys are the argument names and the values are the supplied values.
- Combining *args and **kwargs — A function can declare both *args and **kwargs together to accept any combination of positional and keyword arguments. This pattern is common in decorators and generic wrapper functions.
- Unpacking Arguments at the Call Site — The * and ** operators can also be used at the call site to unpack a list or tuple into positional arguments and a dictionary into keyword arguments respectively. This is the inverse of the collection behavior in definitions.
Scope and Variable Visibility
Explains how Python resolves variable names using the LEGB rule and how the global and nonlocal keywords allow functions to modify variables in enclosing scopes.
- The LEGB Scope Rule — Python resolves names by searching four scopes in order: Local, Enclosing, Global, and Built-in. The first scope in which the name is found wins.
- Local Variables — Any name assigned inside a function is treated as local to that function by default, even if a global variable with the same name exists. Local variables do not affect the outer scope.
- The global Keyword — The global keyword declares that a name inside a function refers to a module-level variable rather than creating a new local one. This allows the function to read and modify the global variable.
- The nonlocal Keyword — The nonlocal keyword is used inside a nested function to refer to a variable in the nearest enclosing function scope that is not global. It enables inner functions to modify variables from their enclosing scope.
Recursion
Introduces recursion as a technique where a function calls itself to solve a problem by reducing it to smaller instances. Covers base cases, recursive cases, and practical considerations like stack depth.
- What Is Recursion? — Recursion is a programming technique in which a function calls itself as part of its own definition. It is a natural fit for problems that can be broken into smaller versions of the same problem.
- Base Cases — A base case is a condition under which the recursive function returns a result directly without making another recursive call. Every recursive function must have at least one base case to eventually terminate.
- Recursive Cases — The recursive case defines how the function calls itself with a modified argument that moves closer to the base case. The result of the recursive call is typically combined with additional computation to produce the answer.
- Recursion Depth and Limitations — Python enforces a maximum recursion depth, defaultable around 1000 calls, to prevent call stack overflow. Very deep recursion will raise a RecursionError even when the logic is correct.
Comprehensions
Teaches the concise comprehension syntax for building lists, dictionaries, and sets from iterables. Covers optional filtering conditions and nested comprehensions.
- List Comprehensions — A list comprehension provides a compact syntax for creating a new list by applying an expression to each item in an iterable. It replaces many common for-loop patterns with a single readable line.
- Dictionary Comprehensions — Dictionary comprehensions build a new dictionary by specifying a key-value expression iterated over a source iterable. They are the dict equivalent of list comprehensions.
- Set Comprehensions — Set comprehensions use curly braces without a colon to produce a set of unique values derived from an iterable. Duplicate expressions are automatically discarded because sets do not allow repeated elements.
- Filtering in Comprehensions — All three comprehension types support an optional if clause that acts as a filter, including only items for which the condition evaluates to True. Filtering replaces a nested if statement inside a for loop.
- Nested Comprehensions — Comprehensions can contain multiple for clauses to iterate over nested iterables, effectively flattening or combining data from multiple sequences. The leftmost for clause is the outermost loop.
Lambda Functions and Functional Patterns
Introduces anonymous lambda functions and the map and filter built-ins as tools for applying functional programming patterns in Python. Explains when to use these tools versus comprehensions or named functions.
- Lambda Functions — A lambda function is an anonymous function defined with the lambda keyword in a single expression. It is used when a small throwaway function is needed without the overhead of a full def statement.
- The map() Function — The built-in map() applies a function to every item in an iterable and returns a map object, a lazy iterator, that yields the transformed values. It is the functional equivalent of a transformation comprehension.
- The filter() Function — The built-in filter() applies a predicate function to each element of an iterable and returns only the elements for which the predicate returns True. It is the functional equivalent of a comprehension with an if clause.
- Combining map and filter — map() and filter() can be composed by nesting calls, applying filtering first and then transformation, or vice versa. This chains functional operations without creating intermediate lists.
- Choosing Between Comprehensions and Functional Tools — Python offers both comprehensions and map/filter as ways to transform and filter data. Choosing between them depends on readability, the existence of a named function, and team conventions.
Learning Outcomes
MO1
Construct Python functions using the def keyword, appropriate parameter types (positional, keyword, default, *args, and **kwargs), and explicit return statements to produce reusable, documented code
MO2
Trace Python's LEGB scope rule to predict which value a variable name resolves to within nested and global function contexts
MO3
Implement a recursive function by identifying the base case and recursive case for a given problem
MO4
Produce list, dictionary, and set comprehensions — including filter clauses and nested iteration — to transform data from existing iterables
MO5
Evaluate when to apply lambda functions, map(), or filter() versus comprehensions for a given data-transformation task based on readability and functional requirements
Module 4: 4 - Modules, File I/O, and Error Handling
Topics
Introduction to Python Modules
Explains what modules are, why they are used, and how Python locates and loads them at runtime.
- What Is a Module? — A module is a single Python file containing definitions, functions, classes, and variables that can be reused in other scripts.
- Importing Modules with import — The import statement loads a module into the current namespace, making its contents accessible via dot notation.
- Selective Imports with from…import — The from…import syntax lets you import specific names from a module directly into the current namespace.
- Module Aliases — The 'as' keyword creates a shorter or more descriptive alias for an imported module or name.
- The Module Search Path — When Python encounters an import statement it searches a sequence of directories defined in sys.path to locate the module file.
Writing and Using Custom Modules
Covers how to design, write, and import your own Python modules to share reusable engineering functions across projects.
- Creating a Custom Module File — A custom module is created by writing functions, classes, or constants in a .py file and saving it in a location accessible to your scripts.
- The __name__ == '__main__' Guard — This guard allows a module file to contain both reusable code and a standalone test or demo block that only executes when the file is run directly.
- Organizing Functions and Constants — Group related functions and constants logically within a module to make the interface clear to other developers and scripts.
- Importing Your Custom Module — Once saved in the correct directory, a custom module is imported using the same syntax as any standard library module.
- Documenting a Custom Module — Good documentation within a module enables other engineers to understand and correctly use its functions without reading the implementation.
Using Standard Library Modules
Introduces key modules included with Python that are immediately useful for engineering scripting tasks without additional installation.
- The math Module — The math module provides mathematical functions and constants commonly needed in engineering calculations.
- The os and os.path Modules — The os module provides operating-system-independent functions for interacting with the file system and environment.
- The sys Module — The sys module exposes interpreter-level variables and functions, including command-line arguments and the module search path.
- The datetime Module — The datetime module supplies classes for manipulating dates and times, which is useful for timestamping engineering data logs.
- The random Module — The random module generates pseudo-random numbers and provides tools for random sampling, useful in simulations and testing.
File I/O with the with Statement
Explains how to open, read, and write text files safely using Python's with-statement context manager to guarantee proper resource cleanup.
- Opening Files and File Modes — Python's built-in open() function returns a file object that provides methods for reading and writing; the mode argument determines how the file is accessed.
- The with Statement Context Manager — The with statement ensures a file is automatically closed when the indented block exits, even if an exception occurs.
- Reading Text Files — File objects provide multiple methods for reading text content depending on whether you need the entire file, one line, or all lines as a list.
- Writing Text Files — Opening a file in write or append mode allows you to output strings to the file using the write or writelines methods.
- Working with File Paths Using pathlib — The pathlib module provides an object-oriented interface for constructing and manipulating file paths that works consistently across operating systems.
Reading and Writing CSV Files
Covers using Python's built-in csv module to read tabular data from CSV files and write structured results, a common task in engineering data workflows.
- What Is a CSV File? — A CSV (Comma-Separated Values) file stores tabular data as plain text, with each row on a new line and columns separated by a delimiter, typically a comma.
- Reading CSV Files with csv.reader — csv.reader wraps a file object and returns an iterator that yields each row as a list of strings.
- Reading CSV Files with csv.DictReader — csv.DictReader reads each row as an ordered dictionary, using the header row as keys, which makes column access by name more readable.
- Writing CSV Files with csv.writer — csv.writer provides methods to write rows to a CSV file, handling quoting and delimiter escaping automatically.
- Writing CSV Files with csv.DictWriter — csv.DictWriter writes dictionaries as CSV rows, with field names specified at construction time.
Working with JSON
Introduces JSON as a human-readable data interchange format and demonstrates how Python's json module serializes and deserializes data for configuration files and APIs.
- What Is JSON? — JSON (JavaScript Object Notation) is a lightweight, text-based format for representing structured data using key-value pairs, arrays, and nested objects.
- Parsing JSON with json.loads and json.load — Python's json module converts a JSON string or file into native Python data structures using the loads and load functions.
- Serializing Data with json.dumps and json.dump — The json module converts Python objects into JSON-formatted strings or writes them to a file using dumps and dump.
- JSON for Configuration Files — Storing simulation parameters or tool settings in a JSON file allows engineers to modify inputs without editing source code.
- Limitations of Python's json Module — Not all Python objects can be directly serialized to JSON; certain types require custom handling or conversion before they can be encoded.
Error Handling with try-except
Explains Python's exception handling model and demonstrates how to use try-except blocks to build resilient engineering scripts that recover gracefully from runtime errors.
- What Is an Exception? — An exception is a runtime error that interrupts normal program flow; if not handled, it terminates the script and displays a traceback.
- Basic try-except Structure — A try block contains code that might raise an exception; the except block defines how to respond if a specific exception type is raised.
- The else and finally Clauses — The optional else clause runs only if no exception was raised; the finally clause runs unconditionally and is used for cleanup actions.
- Accessing Exception Information — Using 'as' in an except clause binds the exception object to a variable, providing access to its message and attributes for logging or debugging.
- Raising Exceptions — The raise statement lets you deliberately trigger an exception when your code detects an invalid condition, signaling errors clearly to calling code.
- Practical Error Handling in Engineering Scripts — Combining try-except with file I/O, user input, and numeric operations produces robust scripts that handle real-world data quality issues gracefully.
Learning Outcomes
MO1
Construct a custom Python module containing reusable engineering functions, organized with a __name__ == '__main__' guard and module-level documentation
MO2
Apply the with-statement context manager to read from and write to text and CSV files using Python's built-in open() function and csv module
MO3
Serialize and deserialize structured engineering data between Python objects and JSON format using the json module's load, loads, dump, and dumps functions
MO4
Implement try-except blocks with else, finally, and raise clauses to handle runtime exceptions in scripts that perform file I/O and numeric operations
MO5
Select appropriate standard library modules — including math, os, datetime, and pathlib — to accomplish specified engineering scripting tasks
Module 5: 5 - NumPy for Engineering Numerical Computation
Topics
Numpy Functions
A summary of Numpy functions
- Mathematical and Arithmetic Functions — NumPy provides a rich set of universal functions (ufuncs) for performing element-wise mathematical operations on arrays. These include basic arithmetic as well as advanced mathematical computations commonly used in engineering analysis.
- Statistical Functions — NumPy includes a comprehensive suite of statistical functions that allow engineers to analyze datasets, compute descriptive statistics, and understand data distributions. These functions operate directly on arrays and support axis-based computations.
- Linear Algebra Functions — NumPy's numpy.linalg module provides essential linear algebra operations used extensively in structural analysis, control systems, and signal processing. These functions handle matrix operations that are fundamental to solving engineering problems.
- Array Manipulation Functions — NumPy offers a wide range of functions for reshaping, joining, splitting, and transforming arrays, enabling engineers to prepare and restructure data for computational workflows. These functions are essential for adapting data to the required format of algorithms and simulations.
- Sorting and Searching Functions — NumPy provides functions to sort array elements and search for values meeting specific criteria, which are frequently needed in data preprocessing and engineering signal analysis. These functions support multi-dimensional arrays and offer control over sorting algorithms.
- Input/Output and Data Loading Functions — NumPy supports saving and loading array data through a set of I/O functions that interface with binary and text file formats, facilitating data persistence and interoperability in engineering projects. These functions allow engineers to store simulation results and reload experimental datasets efficiently.
Introduction to NumPy and the ndarray
Covers what NumPy is, why it is the cornerstone of numerical engineering computation in Python, and how the ndarray differs fundamentally from a Python list.
- What Is NumPy? — NumPy is an open-source Python library that provides a high-performance multidimensional array object and a collection of routines for fast mathematical operations on those arrays.
- The ndarray Object — The ndarray (n-dimensional array) is NumPy's primary data structure, storing elements of a single data type in a contiguous block of memory.
- NumPy Arrays vs. Python Lists — While Python lists are flexible containers that can hold mixed types, NumPy arrays are typed, contiguous, and designed for numerical batch operations.
- Key Array Attributes — Understanding an array's metadata attributes is essential before performing any computation or manipulation.
Creating NumPy Arrays
Explores the full range of array construction methods, from converting Python sequences to using specialized initialization functions that generate arrays of specific values or ranges.
- Creating Arrays from Python Sequences — The most direct way to create a NumPy array is by passing a Python list or tuple to np.array(), which infers the shape and dtype automatically.
- Range and Linspace Functions — np.arange() and np.linspace() generate arrays of evenly spaced values and are essential for creating domain variables in engineering simulations.
- Constant-Value Initialization Functions — NumPy provides convenience functions to create arrays pre-filled with zeros, ones, or arbitrary constants, which are commonly needed to initialize result buffers in iterative engineering algorithms.
- Identity and Diagonal Matrices — For linear algebra workflows, NumPy provides direct constructors for identity and diagonal matrices that appear frequently in engineering mathematics.
- Random Array Generation — NumPy's random module enables generation of arrays populated with random values drawn from various statistical distributions, critical for Monte Carlo simulations and testing.
Element-Wise Operations and Universal Functions
Describes how NumPy performs arithmetic and mathematical operations element-by-element using ufuncs, enabling vectorized computation without explicit Python loops.
- Vectorized Arithmetic — Arithmetic operators applied to NumPy arrays act element-wise, computing operations across all elements simultaneously without any Python-level loop.
- Universal Functions (ufuncs) — Ufuncs are NumPy functions that operate element-wise on arrays and support additional features such as output array specification and reduction methods.
- Comparison and Boolean Operations — Comparison operators applied to arrays return boolean arrays of the same shape, which can be used directly for filtering and conditional logic.
- Aggregate Reduction Functions — NumPy provides functions that reduce an array along one or more axes, computing values such as sum, product, minimum, and maximum.
Broadcasting
Explains NumPy's broadcasting mechanism that allows arithmetic operations between arrays of different but compatible shapes without copying data.
- What Is Broadcasting? — Broadcasting is NumPy's set of rules for stretching arrays with smaller shapes to match larger arrays during arithmetic, enabling operations between arrays of different dimensions.
- Broadcasting Rules — NumPy aligns shapes from the trailing (rightmost) dimension and applies three rules to determine whether two arrays can be broadcast together.
- Common Broadcasting Patterns in Engineering — Broadcasting naturally handles many recurring engineering patterns, such as subtracting a mean vector from every row of a matrix or scaling columns by different factors.
- Avoiding Broadcasting Errors — Mismatched shapes are a frequent source of bugs; understanding shape mismatches and how to inspect and fix them prevents runtime errors.
Indexing, Slicing, and Fancy Indexing
Covers all methods for accessing and selecting subsets of array elements, from basic integer indexing and slices to advanced Boolean and integer-array indexing.
- Basic Integer Indexing — Individual array elements are accessed with integer indices, using zero-based indexing and supporting negative indices to count from the end.
- Slicing Arrays — Slices extract contiguous subarrays using the start:stop:step syntax and return a view into the original array, not a copy.
- Boolean (Mask) Indexing — A boolean array of the same shape as the target can be used as an index to select elements where the mask is True, returning a flattened 1-D array of matching elements.
- Fancy (Integer Array) Indexing — Fancy indexing uses an array of integer indices to select arbitrary elements or rows in any order, enabling non-contiguous and reordered selections.
- np.where and Conditional Selection — np.where() provides a vectorized conditional expression that selects elements from two arrays based on a boolean condition, similar to a ternary operator applied element-wise.
Reshaping, Transposing, and Array Manipulation
Explains how to change the shape and layout of arrays without altering their data, including reshape, transpose, flatten, and stacking operations fundamental to preparing data for engineering algorithms.
- Reshaping Arrays — The reshape() method returns a new view of the array with a different shape, provided the total number of elements remains the same.
- Transposing Arrays — Transposition permutes the axes of an array; for 2-D arrays this swaps rows and columns, and is accessed via the .T attribute or np.transpose().
- Flattening and Raveling — flatten() and ravel() both return 1-D versions of a multidimensional array, but differ in whether they return a copy or a view.
- Stacking and Splitting Arrays — NumPy provides functions to combine multiple arrays along existing or new axes, and to split a single array into multiple sub-arrays.
- Adding and Removing Dimensions — np.newaxis and np.expand_dims() insert size-1 dimensions to adjust array rank for broadcasting or function compatibility.
Linear Algebra with NumPy
Covers NumPy's linear algebra capabilities, including matrix multiplication, decompositions, solving linear systems, and computing norms and determinants as needed for engineering analysis.
- Matrix Multiplication — NumPy supports matrix multiplication via the @ operator and np.matmul(), which perform the standard dot product across rows and columns, distinct from element-wise multiplication.
- Solving Linear Systems — np.linalg.solve(A, b) efficiently solves the linear system Ax = b for x using LU factorization, which is the standard approach for engineering systems of equations.
- Eigenvalues and Eigenvectors — np.linalg.eig() and np.linalg.eigh() compute eigenvalues and eigenvectors of square matrices, used extensively in structural analysis, vibration problems, and principal component analysis.
- Matrix Decompositions — NumPy provides LU (via solve), QR, SVD, and Cholesky decompositions through the np.linalg submodule, enabling factorization-based approaches to engineering computations.
- Norms and Determinants — np.linalg.norm() computes vector and matrix norms used for convergence checks and condition assessment, while np.linalg.det() computes the scalar determinant.
Statistical and Mathematical Functions
Introduces NumPy's built-in statistical descriptors and mathematical functions that enable rapid characterization of engineering data and evaluation of mathematical expressions over arrays.
- Descriptive Statistics — NumPy provides array-level functions for computing mean, median, variance, and standard deviation along specified axes, forming the basis for engineering data characterization.
- Min, Max, and Sorting — Functions for finding extrema and sorting arrays are fundamental to data analysis, threshold detection, and ranked ordering of engineering results.
- Trigonometric and Exponential Functions — NumPy includes a comprehensive set of element-wise mathematical functions for trigonometry, exponentials, and logarithms, essential for evaluating engineering formulas over arrays.
- Correlation and Covariance — np.corrcoef() and np.cov() compute correlation and covariance matrices between variables, enabling assessment of relationships in multi-channel engineering data.
- Polynomial Evaluation and Fitting — np.polyval() evaluates a polynomial with given coefficients over an array of values, and np.polyfit() fits a least-squares polynomial to data, supporting common engineering curve-fitting tasks.
Learning Outcomes
MO1
Construct NumPy arrays using creation functions such as np.array(), np.arange(), np.linspace(), and constant-value initializers appropriate to a given engineering computation context
MO2
Apply vectorized element-wise operations and broadcasting rules to perform arithmetic across arrays of compatible but different shapes without explicit Python loops
MO3
Select subsets of array data using integer indexing, slicing, Boolean masking, and fancy indexing to extract or filter engineering datasets
MO4
Solve a system of linear equations and compute eigenvalues of a square matrix using NumPy's numpy.linalg functions
MO5
Calculate descriptive statistics and evaluate trigonometric or polynomial functions over arrays to characterize engineering data
Module 6: 6 - Data Visualization with Matplotlib and Intro to Pandas
Topics
Introduction to Matplotlib and the pyplot Interface
Introduces the matplotlib library and its pyplot module, explaining how the interface manages the figure and axes objects that underlie every plot.
- What is Matplotlib? — Matplotlib is a comprehensive Python library for creating static, animated, and interactive visualizations. It is the foundational plotting library in the scientific Python ecosystem.
- The pyplot Module — The pyplot module provides a state-based interface to matplotlib, allowing users to create and modify figures with simple function calls. It is typically imported as plt.
- Figures and Axes Objects — In matplotlib, a Figure is the top-level container for all plot elements, while an Axes is the region within the figure where data is plotted. Understanding this hierarchy is essential for building complex visualizations.
- Displaying and Saving Figures — Once a plot is constructed, it can be rendered to the screen with plt.show() or saved to a file with plt.savefig(). Proper use of these functions ensures figures appear and are preserved correctly.
Line Plots and Scatter Plots
Covers the creation and customization of line plots and scatter plots, the two most common chart types for visualizing continuous and relational engineering data.
- Creating a Basic Line Plot — A line plot is created using plt.plot(x, y), which connects data points with line segments. It is ideal for showing trends over a continuous variable such as time or distance.
- Customizing Line Plots — Line plots can be customized with keyword arguments to control color, line width, style, and markers. Meaningful labels and titles improve interpretability.
- Creating a Scatter Plot — A scatter plot is created with plt.scatter(x, y) and displays individual data points without connecting lines. It is useful for exploring correlations and distributions between two variables.
- Axis Limits and Scaling — Controlling the visible range of axes ensures that important data features are not clipped or obscured. Matplotlib provides functions to set both linear and logarithmic scales.
Bar Charts and Histograms
Explains how to create bar charts for categorical comparisons and histograms for examining the distribution of numerical data in engineering contexts.
- Creating a Bar Chart — Bar charts are created with plt.bar(categories, values) and are used to compare discrete groups or categories. They are commonly used to display experimental results across different conditions.
- Annotating Bar Charts — Adding value labels or annotations to bar charts makes them easier to interpret, especially in technical reports. matplotlib provides text placement functions for this purpose.
- Creating a Histogram — Histograms are created with plt.hist(data, bins=n) and display the frequency distribution of a single continuous variable. They are essential for understanding data spread and identifying outliers in engineering measurements.
- Comparing Distributions with Histograms — Multiple datasets can be compared by overlaying histograms on the same axes. Proper use of transparency and color enables effective visual comparison of distributions.
Subplots and Figure Layout
Demonstrates how to create multi-panel figures using subplots, enabling side-by-side comparison of different plots within a single publication-ready figure.
- Creating Subplots with plt.subplots() — The plt.subplots(nrows, ncols) function creates a Figure and a grid of Axes objects in one call. It is the recommended approach for building multi-panel layouts.
- Plotting on Individual Axes — When using subplots, plotting commands are called on individual Axes objects rather than on plt directly. This object-oriented approach provides precise control over each panel.
- Adjusting Layout and Spacing — Subplot panels can overlap or clip labels if spacing is not adjusted. matplotlib provides tools to automatically or manually correct figure layout.
- Using GridSpec for Complex Layouts — For non-uniform subplot grids, matplotlib.gridspec.GridSpec allows plots of different sizes to share a figure. This is useful for dashboard-style engineering figures.
Publication-Quality Figure Styling
Covers techniques for elevating plot aesthetics to meet publication and report standards, including style sheets, custom colors, annotations, and saving high-resolution outputs.
- Using Style Sheets — Matplotlib includes built-in style sheets that instantly apply consistent aesthetics to all figures in a script. Selecting an appropriate style reduces manual customization effort.
- Customizing Colors and Colormaps — Color choices affect both the aesthetic quality and accessibility of a figure. Matplotlib supports named colors, hex codes, RGB tuples, and scientific colormaps.
- Fonts, Tick Marks, and Spines — Fine-tuning typography and axis decorations distinguishes a presentation-ready figure from a draft plot. Matplotlib allows control over font size, tick frequency, and axis border (spine) visibility.
- Saving High-Resolution Figures — Exporting figures at sufficient resolution is critical for print publications and technical reports. The plt.savefig() function supports multiple formats and resolution settings.
Introduction to Pandas: Series and DataFrames
Introduces the pandas library and its two primary data structures — Series and DataFrame — which form the foundation for data manipulation and analysis in Python.
- What is Pandas? — Pandas is a Python library built on NumPy that provides high-performance, easy-to-use data structures for working with labeled and relational data. It is the standard tool for tabular data analysis in Python.
- The Pandas Series — A Series is a one-dimensional labeled array capable of holding data of any type. It behaves like a NumPy array but with an associated index that labels each element.
- The Pandas DataFrame — A DataFrame is a two-dimensional labeled data structure with columns of potentially different types, analogous to a spreadsheet or SQL table. It is the primary pandas object for engineering datasets.
- Inspecting a DataFrame — Pandas provides several methods for quickly exploring the structure and content of a newly loaded dataset. These are essential first steps in any data analysis workflow.
Reading, Filtering, and Sorting Data with Pandas
Demonstrates how to load datasets from files and then select, filter, and sort rows and columns to extract meaningful subsets for engineering analysis.
- Reading Data from Files — Pandas provides read functions that import data from common file formats directly into a DataFrame. Reading CSV files is the most common operation in engineering data workflows.
- Selecting Columns and Rows — Pandas provides multiple methods for selecting subsets of a DataFrame by column name or row index. Mastery of these selection methods is fundamental to data manipulation.
- Filtering Rows with Boolean Conditions — Boolean indexing allows rows to be selected based on conditions applied to one or more columns. This is the standard method for subsetting engineering data by threshold or category.
- Sorting DataFrames — Sorting a DataFrame rearranges rows based on the values in one or more columns. Sorted data is easier to inspect and is required as a preprocessing step for some analyses.
- Adding and Modifying Columns — New columns can be added to a DataFrame through direct assignment, enabling derived variables to be computed from existing data. This is essential for feature engineering and unit conversions.
Descriptive Statistics with Pandas
Covers pandas methods for computing summary statistics, aggregating grouped data, and identifying missing values in engineering datasets.
- Summary Statistics with describe() — The df.describe() method computes count, mean, standard deviation, min, max, and quartiles for all numeric columns simultaneously. It provides a rapid overview of dataset characteristics.
- Aggregation with groupby() — The groupby() method splits a DataFrame into groups based on column values and applies aggregate functions to each group. It is the pandas equivalent of SQL GROUP BY.
- Handling Missing Values — Missing values represented as NaN are common in real engineering datasets from sensor dropouts or incomplete records. Pandas provides methods to detect, remove, or fill missing data.
- Correlation and Relationships — Pandas can compute pairwise correlations between numeric columns, providing a quick measure of linear relationships within an engineering dataset.
- Plotting Directly from Pandas — Pandas DataFrames and Series have built-in plot methods that call matplotlib internally, enabling quick exploratory visualizations with minimal code.
Learning Outcomes
MO1
Construct line plots, scatter plots, bar charts, and histograms using Matplotlib's pyplot interface with appropriate axis labels, titles, and customization parameters
MO2
Compose multi-panel publication-quality figures using plt.subplots() and GridSpec with correctly adjusted layout, styling, and high-resolution export settings
MO3
Load a CSV dataset into a Pandas DataFrame and apply column selection, Boolean row filtering, and sorting operations to extract targeted subsets of engineering data
MO4
Compute descriptive statistics and grouped aggregations on a Pandas DataFrame using describe() and groupby() to summarize engineering dataset characteristics
MO5
Evaluate the distribution and relationships within an engineering dataset by interpreting histograms, correlation values, and grouped summary statistics generated with Matplotlib and Pandas
Module 7: 7 - Object-Oriented Programming and AI-Assisted Coding Workflow
Topics
Foundations of Object-Oriented Programming
Introduces the fundamental concepts of OOP, explaining why it is a powerful paradigm for structuring engineering software. Covers the building blocks of classes, objects, attributes, and methods.
- What Is Object-Oriented Programming? — Object-oriented programming (OOP) is a programming paradigm that organizes software around objects rather than functions and logic alone. It allows engineers to model real-world entities in code in an intuitive and reusable way.
- Classes and Instances — A class is a blueprint that defines the structure and behavior of a type of object, while an instance is a specific object created from that blueprint. Understanding the distinction between a class definition and an instantiated object is foundational to OOP.
- Attributes — Attributes are variables that belong to an object and store its state or properties. In engineering contexts, attributes might represent physical properties such as a beam's length, material, or cross-sectional area.
- Methods — Methods are functions defined inside a class that describe the behaviors or operations an object can perform. They allow objects to act on their own data and interact with other objects.
- The Constructor Method __init__ — The __init__ method is a special method automatically called when a new instance is created. It initializes the object's attributes, ensuring every instance starts in a valid, well-defined state.
Modeling Engineering Objects with Classes
Demonstrates how OOP concepts are applied to represent real-world engineering entities such as structural beams and sensors as Python classes. Emphasizes practical class design for engineering problem-solving.
- Designing an Engineering Class — Good class design begins by identifying the properties and behaviors of the engineering object being modeled. A systematic design process leads to classes that are intuitive, reusable, and aligned with engineering domain knowledge.
- Implementing a Beam Class — A structural beam can be modeled as a Python class with attributes for geometry and material, and methods that compute engineering quantities such as moment of inertia or deflection. This example ties OOP syntax directly to familiar engineering concepts.
- Implementing a Sensor Class — Sensors in an engineering system can be modeled as objects with attributes describing their type, location, and measurement range, and methods for reading or validating data. Modeling sensors as classes supports scalable, maintainable monitoring system code.
- Using Objects Together in Engineering Systems — Real engineering programs often involve multiple interacting objects, such as sensors attached to beams or loads applied to structural members. Designing classes to work together models the relationships present in actual engineering systems.
- String Representation with __str__ and __repr__ — Implementing __str__ and __repr__ methods gives objects meaningful text representations, making debugging and logging significantly more informative. For engineering objects, these methods can display key attribute values in a readable format.
Inheritance and Class Hierarchies
Explains how inheritance allows new classes to build upon and extend existing ones, reducing duplication and reflecting natural hierarchies in engineering domains. Covers single inheritance, method overriding, and the use of super().
- The Concept of Inheritance — Inheritance allows a child class to automatically receive the attributes and methods of a parent class, then extend or modify them as needed. This mechanism captures the 'is-a' relationship between engineering object types.
- Defining Subclasses — A subclass is defined by passing the parent class as an argument in the class declaration. The subclass can introduce new attributes and methods while inheriting everything already defined in the parent.
- Calling the Parent Constructor with super() — The super() function allows a subclass to call the parent class's __init__ and other methods, ensuring parent initialization logic runs before the subclass adds its own setup. This prevents duplication and maintains proper object state.
- Method Overriding — Method overriding allows a subclass to provide its own implementation of a method already defined in the parent class. This is how different beam types can each calculate moment of inertia using geometry-specific formulas.
- When to Use Inheritance Versus Composition — Choosing between inheritance and composition is an important design decision. Inheritance suits 'is-a' relationships, while composition suits 'has-a' relationships, and selecting the right approach keeps code maintainable and logically sound.
- Practical Inheritance Example: Sensor Hierarchy — A sensor hierarchy illustrates inheritance in action: a base Sensor class defines common attributes and a read_value() method, while subclasses such as TemperatureSensor and StrainGaugeSensor override read_value() with type-specific logic.
Introduction to AI-Assisted Coding Tools
Introduces GitHub Copilot and ChatGPT as AI coding assistants and explains how they integrate into the engineering programming workflow. Establishes the capabilities and limitations of each tool.
- What Is GitHub Copilot? — GitHub Copilot is an AI-powered code completion tool integrated directly into code editors such as VS Code. It suggests code in real time as the programmer types, based on context from the current file and comments.
- What Is ChatGPT for Coding? — ChatGPT is a conversational AI that can generate code, explain concepts, suggest fixes, and answer programming questions in natural language. Unlike Copilot, it is used in a separate chat interface rather than within the editor.
- Capabilities and Limitations of AI Coding Assistants — AI coding assistants are powerful productivity tools but have well-documented limitations including generating plausible but incorrect code, using outdated library versions, and lacking domain-specific engineering judgment.
- Setting Up the AI-Assisted Coding Environment — Integrating AI tools into a development environment requires installing the appropriate extensions and configuring access credentials. A properly set-up environment allows seamless use of Copilot within the editor alongside ChatGPT in a browser or API.
AI-Assisted Code Generation Workflow
Establishes a structured workflow for using AI tools to generate, refine, and integrate code for engineering programming tasks. Focuses on effective prompting strategies and iterative development practices.
- Writing Effective Prompts for Code Generation — The quality of AI-generated code is directly tied to the quality of the prompt provided. Effective prompts are specific, include relevant context, state constraints, and describe expected inputs and outputs clearly.
- Using Comments and Docstrings to Guide Copilot — GitHub Copilot uses inline comments and docstrings as high-quality contextual signals to generate relevant code suggestions. Writing descriptive comments before a function or method body is one of the most effective Copilot usage patterns.
- Iterative Refinement of AI-Generated Code — AI-generated code rarely meets all requirements on the first attempt and should be treated as a draft to be iteratively refined. Reviewing, testing, and re-prompting are essential steps in the workflow.
- Generating Boilerplate and Class Scaffolding — AI tools are especially effective at generating repetitive boilerplate code such as class definitions, __init__ methods, property accessors, and __str__ implementations. This accelerates the setup phase of engineering class design.
- Using AI for Test Case Generation — AI tools can generate unit test cases for engineering classes, helping engineers verify that methods return correct results across a range of inputs. Prompt the tool to create tests covering typical values, edge cases, and boundary conditions.
AI-Assisted Debugging
Covers how to use AI tools to interpret error messages, identify bugs, and reason through incorrect program behavior. Establishes a systematic debugging approach that combines AI assistance with engineer-led analysis.
- Reading and Interpreting Error Messages — Python error messages contain precise information about the type of error, the file, the line number, and a description of the problem. Learning to read tracebacks systematically is a prerequisite for effective debugging with or without AI assistance.
- Prompting AI Tools to Explain Errors — Pasting an error message and the relevant code into ChatGPT and asking for an explanation is an effective first debugging step. AI tools can quickly identify common error patterns and suggest likely causes.
- Common OOP Errors in Engineering Code — Certain error types arise frequently when working with classes, including AttributeError from misspelled attribute names, TypeError from incorrect method signatures, and errors from failing to call super() in subclass constructors.
- Systematic Debugging Strategy — Effective debugging follows a systematic process: reproduce the error reliably, isolate the failing component, form a hypothesis about the cause, test the hypothesis, and apply and verify a fix. AI tools support but do not replace this process.
Responsible Use and Verification of AI-Generated Code
Establishes the ethical responsibilities and practical verification practices engineers must apply when using AI-generated code. Emphasizes that engineering judgment and accountability cannot be delegated to AI tools.
- Why Verification Is Non-Negotiable in Engineering — Engineering software underpins decisions about physical systems where errors can have safety, financial, or environmental consequences. AI-generated code must be rigorously verified because the tools have no awareness of engineering standards, safety factors, or physical constraints.
- Hand Calculation Verification — The most direct verification method is computing expected outputs by hand and comparing them against the program's results. Hand calculations catch numerical errors, wrong formulas, and incorrect unit handling in AI-generated engineering code.
- Code Review Practices for AI-Generated Code — Code review involves systematically reading through generated code line by line to understand what it does, checking for logical errors, inappropriate assumptions, and missing edge case handling. This is a critical quality gate before any code is integrated.
- Testing Strategies for Engineering Classes — Structured testing using Python's unittest or pytest frameworks provides systematic and repeatable verification of class behavior. Writing tests that cover typical values, boundary conditions, and known failure modes builds confidence in the code.
- Academic and Professional Integrity in AI-Assisted Coding — Using AI tools responsibly includes understanding and following institutional policies on academic integrity and professional standards on attribution. Representing AI-generated code as entirely one's own original work without disclosure may violate ethical obligations.
- Building a Responsible AI-Assisted Workflow Summary — A responsible AI-assisted engineering coding workflow integrates AI tools as productivity aids within a framework of human judgment, systematic verification, and professional accountability. The engineer remains the decision-maker throughout.
Learning Outcomes
MO1
Construct Python classes that model engineering objects — such as structural beams or sensors — by defining attributes, methods, and a constructor using the __init__ method
MO2
Implement class hierarchies using inheritance, method overriding, and super() to represent 'is-a' relationships among engineering object types
MO3
Formulate effective prompts for AI coding assistants to generate class scaffolding and test cases for engineering programming tasks
MO4
Evaluate AI-generated engineering code by comparing program outputs against hand calculations and applying structured code review to identify logical errors or invalid assumptions
MO5
Apply a systematic debugging strategy — including interpreting Python tracebacks and using AI tools to explain common OOP errors — to diagnose and correct faults in class-based engineering programs
Module 8: 8 - Numerical Methods with SciPy and Curve Fitting
Topics
Introduction to SciPy for Numerical Computing
Introduces the SciPy library, its ecosystem, and how it extends NumPy to support numerical methods used in engineering and science.
- What is SciPy? — SciPy is an open-source Python library built on top of NumPy that provides a wide collection of algorithms for scientific and technical computing.
- SciPy vs NumPy: Complementary Roles — While NumPy handles array creation and basic mathematical operations, SciPy provides higher-level algorithms such as optimization, integration, and signal processing.
- Installing and Importing SciPy Submodules — SciPy submodules must be imported explicitly; importing the top-level scipy package does not automatically load all submodules.
- Overview of Numerical Problem Categories — This module focuses on three core numerical problem types: root finding, numerical integration (including ODEs), and curve fitting.
Root Finding with scipy.optimize
Covers scalar and multivariate root-finding methods available in scipy.optimize, including bracket-based and derivative-based approaches.
- Concept of Root Finding — Root finding is the process of locating values of x such that f(x) = 0, a fundamental task in engineering analysis such as finding equilibrium points or solving implicit equations.
- Bracket-Based Methods: brentq and bisect — Bracket-based methods require an interval [a, b] where the function changes sign, guaranteeing convergence to a root within that interval.
- Derivative-Based Methods: fsolve and newton — Derivative-based methods such as Newton-Raphson use the function's slope to converge rapidly to a root but may fail if started far from the solution.
- General Scalar Minimization and root_scalar — scipy.optimize.root_scalar provides a unified interface for choosing among multiple root-finding algorithms using a common function signature.
- Practical Considerations for Root Finding — Choosing an appropriate root-finding method depends on function continuity, availability of derivatives, and whether a bracketing interval can be identified.
Numerical Integration with scipy.integrate
Covers numerical quadrature for definite integrals and the integration of systems of ordinary differential equations using scipy.integrate.
- Numerical Quadrature: quad and dblquad — scipy.integrate.quad computes definite integrals of scalar functions over a finite or infinite interval using adaptive Gaussian quadrature.
- Integrating Tabular Data: simpson and trapezoid — When data is given as discrete arrays rather than a function, methods such as simpson and trapezoid approximate the integral from the sample points.
- Introduction to Ordinary Differential Equations (ODEs) — An ODE describes how a quantity changes with respect to an independent variable, and solve_ivp integrates such equations forward from a set of initial conditions.
- Solving ODEs with solve_ivp — scipy.integrate.solve_ivp is the modern interface for integrating systems of ODEs, supporting multiple integration methods and dense output.
- Defining the Derivative Function for solve_ivp — The user-defined function passed to solve_ivp must accept time t and state vector y and return the vector of derivatives dy/dt.
- Interpreting and Visualizing ODE Solutions — Once solve_ivp returns a result, the solution arrays can be plotted with Matplotlib to visualize the system's transient and steady-state behavior.
Linear Curve Fitting with numpy.polyfit
Explains polynomial regression using numpy.polyfit, including model selection, coefficient interpretation, and generating fitted curves for visualization.
- What is Curve Fitting? — Curve fitting finds the parameters of a mathematical model that minimize the difference between the model's predictions and observed data points.
- Using numpy.polyfit for Polynomial Regression — numpy.polyfit fits a polynomial of specified degree to x-y data using the least-squares method and returns the polynomial coefficients.
- Selecting Polynomial Degree — Choosing the right polynomial degree requires balancing fit accuracy with model simplicity, guided by domain knowledge and residual analysis.
- Linearization of Nonlinear Data — Some nonlinear relationships such as exponential or power-law models can be transformed into linear form, allowing numpy.polyfit to be applied after a variable substitution.
- Generating and Plotting Fitted Curves — After obtaining polynomial coefficients, a smooth fitted curve is generated by evaluating the polynomial on a dense array of x values and overlaying it on the scatter plot of the data.
Nonlinear Curve Fitting with scipy.optimize.curve_fit
Covers fitting arbitrary nonlinear models to data using scipy.optimize.curve_fit, including defining model functions, interpreting fit parameters, and assessing uncertainty.
- When to Use Nonlinear Fitting — Nonlinear curve fitting is required when the relationship between variables cannot be described by a polynomial or linearized form, and the model has parameters that appear nonlinearly.
- Defining a Model Function for curve_fit — The user supplies a Python function that takes the independent variable as its first argument followed by the model parameters, returning the predicted dependent variable values.
- Calling curve_fit and Interpreting Output — scipy.optimize.curve_fit returns the optimal parameter array popt and the covariance matrix pcov, which together describe the best-fit model and parameter uncertainty.
- Setting Initial Guesses and Bounds — Providing good initial parameter estimates via the p0 argument and restricting parameter ranges with bounds improves convergence and prevents physically unreasonable solutions.
- Handling Convergence Failures — If curve_fit cannot converge, it raises a RuntimeError; diagnosing and resolving convergence failures is an important practical skill.
Residuals Analysis
Explains how to compute, visualize, and interpret residuals to evaluate curve-fit quality and identify model inadequacy on engineering datasets.
- What are Residuals? — Residuals are the differences between observed data values and the corresponding values predicted by the fitted model, quantifying the pointwise error of the fit.
- Computing Residuals in Python — Residuals are computed by evaluating the fitted model at the original x data points and subtracting the predicted values from the observed y values.
- Residual Plots and What They Reveal — Plotting residuals against the independent variable (or fitted values) is the primary diagnostic tool for evaluating whether the chosen model is appropriate.
- Quantitative Fit Metrics — Alongside visual residual plots, quantitative metrics such as the coefficient of determination R² and root mean square error (RMSE) provide summary measures of fit quality.
- Applying Residuals Analysis to Engineering Datasets — On real engineering datasets, residuals analysis guides iterative model improvement by revealing systematic errors tied to physical phenomena not yet captured by the model.
- Overfitting and Model Complexity — Increasing model complexity will always reduce residuals on training data, but may degrade predictive performance on new data—a phenomenon known as overfitting.
Applying Numerical Methods to Engineering Datasets
Brings together root finding, integration, ODE solving, and curve fitting in end-to-end workflows applied to realistic engineering problems.
- Structuring an End-to-End Numerical Workflow — A complete numerical workflow involves loading and inspecting data, selecting and applying an appropriate method, validating results, and communicating outputs clearly.
- Loading and Preprocessing Engineering Data — Real engineering datasets typically require preprocessing steps such as unit conversion, removal of missing values, and normalization before applying numerical methods.
- Combining Root Finding and Integration — Some engineering problems require both root finding and integration, for example locating where a cumulative quantity reaches a threshold by combining quad with a root solver.
- Fitting ODE Model Parameters to Experimental Data — A powerful workflow combines solve_ivp with curve_fit to estimate parameters of a dynamic model from time-series measurements.
- Communicating Numerical Results in Engineering Reports — Effective communication of numerical results requires presenting fitted parameters with uncertainties, fit quality metrics, and clearly labeled plots that support engineering decisions.
Learning Outcomes
MO1
Select an appropriate root-finding method from scipy.optimize (such as brentq, bisect, or fsolve) based on the continuity of the function, availability of derivatives, and the existence of a bracketing interval
MO2
Apply scipy.integrate functions (quad, simpson, trapezoid, or solve_ivp) to compute definite integrals and solve initial value ODE problems from engineering datasets
MO3
Fit both polynomial and nonlinear models to engineering data using numpy.polyfit and scipy.optimize.curve_fit, including defining model functions, supplying initial parameter guesses, and extracting fitted coefficients
MO4
Construct residual plots and calculate quantitative fit metrics (R² and RMSE) to diagnose model adequacy and identify overfitting in curve-fitting results
MO5
Design an end-to-end numerical workflow that integrates data preprocessing, method selection, parameter estimation, and clearly labeled result visualization to address a realistic engineering problem
Module 9: 9 - Engineering Data Analysis and Simulation
Topics
Introduction to Engineering Data Workflows
Establishes the end-to-end pipeline from raw data acquisition to actionable insight. Introduces the key Python libraries used throughout the module.
- The Engineering Data Pipeline — A structured data pipeline guides engineers from raw measurements to validated conclusions. Understanding each stage prevents errors from propagating downstream.
- Overview of pandas — pandas is the primary Python library for structured data manipulation, providing DataFrame and Series objects suited to tabular and time-series engineering data.
- Overview of NumPy — NumPy provides the foundational n-dimensional array structure and mathematical functions required for numerical engineering computation in Python.
- Overview of matplotlib — matplotlib is Python's foundational plotting library, enabling creation of static, animated, and interactive visualizations suitable for engineering reports.
- Setting Up the Python Environment — A reproducible environment ensures that all library versions are consistent across team members and computing platforms.
Loading and Inspecting Engineering Data
Covers the practical techniques for importing CSV and time-series data files into Python and performing initial inspection to understand data structure and quality.
- Reading CSV Files with pandas — The pd.read_csv() function is the primary method for loading comma-separated engineering datasets into a DataFrame for analysis.
- Initial Data Inspection — Before any analysis, engineers must inspect the structure and content of a loaded DataFrame to understand its shape, types, and completeness.
- Working with Time-Series Indices — Engineering time-series data is most powerful when the DataFrame index is a DatetimeIndex, enabling time-based slicing and resampling.
- Selecting and Filtering Data — Subsetting a DataFrame to relevant rows and columns is a fundamental skill for focusing analysis on the engineering variables of interest.
- Importing Data from Multiple Sources — Engineering projects often combine data from multiple CSV files, sensors, or logging systems that must be merged into a single coherent dataset.
Data Cleaning and Preprocessing
Addresses the identification and correction of common data quality issues including missing values, outliers, incorrect types, and inconsistent formatting found in raw engineering datasets.
- Detecting and Handling Missing Values — Missing values are ubiquitous in engineering data due to sensor faults, communication dropouts, or logging gaps, and must be addressed before analysis.
- Identifying and Treating Outliers — Outliers in engineering datasets can represent genuine extreme events or instrument errors and must be carefully evaluated before removal or correction.
- Correcting Data Types — Incorrectly inferred data types prevent numerical operations and must be corrected as an early step in the cleaning process.
- Handling Duplicate Records — Duplicate rows corrupt statistical summaries and simulation inputs and must be identified and removed as part of standard data cleaning.
- Normalizing and Scaling Data — Engineering signals recorded in different units or on vastly different scales must be normalized before comparison, visualization, or use as simulation inputs.
- Resampling and Aggregating Time-Series Data — Engineering time-series data is often recorded at irregular intervals or at higher frequencies than required for analysis, necessitating resampling to a uniform grid.
Visualizing Engineering Data with matplotlib
Teaches the construction of clear, informative plots for communicating engineering data patterns, trends, distributions, and relationships using matplotlib and pandas plotting utilities.
- Line Plots for Time-Series Data — Line plots are the standard visualization for time-series engineering data, clearly showing how a measured variable evolves over time.
- Scatter Plots for Correlation Analysis — Scatter plots reveal relationships and correlations between two engineering variables, such as load versus deflection or temperature versus resistance.
- Histograms and Distribution Plots — Histograms and density plots characterize the statistical distribution of engineering measurements, supporting quality control and reliability analysis.
- Subplots and Multi-Panel Figures — Engineering reports often require multiple related plots arranged in a grid to allow side-by-side comparison of different signals or analysis results.
- Formatting and Annotating Plots — Proper formatting, labeling, and annotation transform a basic plot into a professional engineering figure ready for reports or publications.
- Visualizing Simulation Results Alongside Measured Data — Overlaying simulated and measured data on the same plot is the primary method for validating simulation models against physical experiments.
Time-Stepping Simulation Fundamentals
Introduces the principles of numerical time-stepping methods used to simulate dynamic engineering systems governed by ordinary differential equations, with emphasis on implementation in Python.
- Ordinary Differential Equations in Engineering — Many engineering systems are governed by ordinary differential equations (ODEs) that describe how state variables such as position, current, or temperature change over time.
- Euler's Method — Euler's method is the simplest explicit time-stepping scheme, approximating the next state by stepping forward in time along the current derivative.
- Runge-Kutta Methods — Runge-Kutta methods, particularly the classical fourth-order RK4 scheme, provide substantially higher accuracy than Euler's method for the same step size.
- Implementing a Time-Stepping Loop — A time-stepping simulation requires a structured loop that advances the system state from initial conditions to the final simulation time using the chosen numerical method.
- Step Size Selection and Accuracy — Choosing an appropriate time step is a critical engineering decision balancing simulation accuracy against computational cost.
- Using scipy for ODE Integration — SciPy's integrate module provides robust, adaptive ODE solvers that serve as reference implementations for validating custom time-stepping code.
Simulating Mechanical Systems
Applies time-stepping methods to model fundamental mechanical systems including spring-mass-damper oscillators, analyzing dynamic behavior and comparing numerical results to analytical solutions.
- The Spring-Mass-Damper System — The spring-mass-damper is the canonical mechanical dynamic system, described by a second-order linear ODE that governs displacement over time under applied forces.
- Underdamped, Critically Damped, and Overdamped Responses — The damping ratio determines three qualitatively different responses to initial displacement or applied force that have distinct engineering implications.
- Analytical Solution for Free Vibration — The analytical closed-form solution for the underdamped free vibration case provides the exact benchmark against which numerical simulations are compared.
- Forced Vibration and Resonance — When an external periodic force is applied, the system response depends strongly on the ratio of forcing frequency to natural frequency, reaching maximum amplitude at resonance.
- Numerical Implementation of the Mechanical Model — Converting the second-order mechanical ODE into a state-space form and implementing a time-stepping loop in Python produces the simulated displacement and velocity time histories.
Simulating Electrical Systems
Applies time-stepping simulation to model RC and RLC electrical circuits, computing voltage and current transient responses and validating results against analytical solutions.
- The RC Circuit — The RC circuit is the simplest first-order electrical system, described by a first-order ODE governing the voltage across the capacitor during charging or discharging.
- The RLC Circuit — The RLC circuit is a second-order system exhibiting resonance, damping, and oscillatory behavior mathematically equivalent to the spring-mass-damper mechanical system.
- Implementing the Electrical Simulation — Numerical simulation of RC and RLC circuits follows the same state-space time-stepping approach used for mechanical systems, with electrical quantities replacing mechanical ones.
- Frequency Domain Analysis — While time-stepping produces time-domain results, frequency-domain analysis using Fourier transforms provides complementary insight into circuit filtering characteristics.
- Validation Against Analytical Solutions — Analytical solutions for RC and RLC circuits under standard inputs provide exact benchmarks for assessing the accuracy of time-stepping implementations.
Simulating Thermal Systems
Applies first- and second-order ODE-based simulation to model heat transfer in lumped-parameter thermal systems, including Newton's law of cooling and multi-node conduction networks.
- Lumped Parameter Thermal Models — Lumped parameter thermal models treat a body as having a single uniform temperature, valid when internal conduction resistance is small compared to surface convection resistance.
- Newton's Law of Cooling — Newton's law of cooling governs the temperature of a lumped-parameter body cooling or heating in a surrounding fluid, producing a first-order exponential response.
- Simulating Cooling and Heating Transients — Implementing the Newton's law ODE in a time-stepping loop produces the simulated temperature-time history for cooling or heating scenarios.
- Multi-Node Thermal Networks — When a system has multiple thermal masses connected by conductive or convective resistances, it forms a multi-node network described by coupled first-order ODEs.
- Comparison with Analytical and Experimental Data — Validating thermal simulations against analytical solutions and where available measured temperature data confirms model accuracy and identifies parameter calibration needs.
- Connecting Data Analysis to Thermal Simulation — Measured temperature data loaded and cleaned using pandas can serve directly as inputs or validation benchmarks for thermal simulation models, closing the loop between data analysis and simulation.
Learning Outcomes
MO1
Construct an end-to-end engineering data pipeline in Python using pandas and NumPy that loads, cleans, and preprocesses raw CSV or time-series datasets for analysis
MO2
Produce properly formatted and annotated matplotlib figures that communicate time-series trends, statistical distributions, and variable correlations from engineering datasets
MO3
Implement a numerical time-stepping simulation in Python using Euler's method or RK4 to solve ordinary differential equations governing mechanical, electrical, or thermal engineering systems
MO4
Evaluate the accuracy of a numerical simulation by comparing time-stepping results against analytical solutions and identifying the effect of step size on simulation error
MO5
Integrate cleaned measured data with simulation outputs to validate a dynamic system model by overlaying experimental and simulated responses on a single annotated plot
Module 10: 10 - Machine Learning, Automation, Version Control, and Responsible AI
Topics
Foundations of Supervised Machine Learning
Introduces the core concepts of supervised learning, distinguishing between regression and classification tasks and explaining how labeled training data drives model development.
- What Is Supervised Learning? — Supervised learning is a machine learning paradigm in which a model is trained on labeled input-output pairs to learn a mapping from features to targets.
- Regression vs. Classification — Regression predicts a continuous numerical output, while classification predicts a discrete category or class label.
- Features, Labels, and Training Data — Features are the measurable input variables used to make predictions, while labels are the corresponding known outputs used during training.
- Bias-Variance Trade-off — The bias-variance trade-off describes the tension between a model that is too simple (high bias) and one that is too complex (high variance).
- Model Evaluation Metrics — Selecting appropriate evaluation metrics is essential for understanding how well a model performs on the intended engineering task.
Machine Learning with scikit-learn
Covers the practical use of the scikit-learn library to build, train, and evaluate regression and classification models in engineering contexts.
- The scikit-learn API Design — scikit-learn provides a consistent estimator API in which every model object exposes fit, predict, and score methods, making it straightforward to swap algorithms.
- Data Preprocessing and Pipelines — Raw engineering data often requires scaling, encoding, or imputation before it can be fed into a machine learning model, and scikit-learn pipelines chain these steps with the estimator.
- Regression Models in scikit-learn — scikit-learn offers a range of regression estimators suitable for engineering data, from linear models to ensemble methods.
- Classification Models in scikit-learn — Classification estimators in scikit-learn assign input samples to discrete classes and are evaluated using metrics such as accuracy, precision, and recall.
- Hyperparameter Tuning — Hyperparameters are model configuration settings that are not learned from data and must be set before training; tuning them improves model performance.
- Model Interpretability and Feature Importance — Understanding which features drive model predictions is critical in engineering applications where decisions have physical and safety consequences.
Engineering Automation and Parameter Sweep Pipelines
Introduces strategies for automating repetitive engineering computations and systematically exploring parameter spaces using scripted pipelines.
- Why Automate Engineering Workflows? — Automation replaces manual, error-prone repetition with reliable, reproducible scripts that can execute complex sequences of engineering tasks consistently.
- Designing a Parameter Sweep — A parameter sweep systematically varies one or more input parameters across a defined range and records the corresponding outputs to map system behavior.
- Integrating ML Models into Automation Pipelines — Trained machine learning models can be embedded in automation pipelines to provide fast surrogate predictions in place of expensive simulations or experiments.
- Handling Large Result Sets — Parameter sweeps can generate large volumes of output data that require efficient storage, querying, and summarization strategies.
- Scheduling and Running Long Jobs — Engineering automation scripts that take significant time to run benefit from progress tracking, logging, and the ability to resume after interruption.
Git and GitHub Version Control
Establishes foundational and collaborative version control practices using Git locally and GitHub as a remote repository platform for engineering code projects.
- Why Version Control Matters for Engineers — Version control systems track every change made to a codebase, enabling engineers to review history, revert mistakes, and collaborate without overwriting each other's work.
- Core Git Concepts and Commands — Git operates through a staging area and a local repository; understanding the add, commit, status, and log commands forms the foundation of daily Git use.
- Branching and Merging — Branches allow engineers to develop features or experiments in isolation from the main codebase, and merging integrates completed work back into the main branch.
- Working with GitHub Remote Repositories — GitHub hosts remote copies of Git repositories, enabling cloud backup, sharing, and team collaboration through push and pull operations.
- Pull Requests and Code Review — Pull requests on GitHub are a formal mechanism for proposing changes, inviting peer review, and merging approved work into a shared branch.
- Repository Hygiene and .gitignore — Good repository hygiene ensures that only relevant source files are tracked, avoiding clutter from generated outputs, credentials, or environment-specific files.
Responsible AI Integration in Engineering Practice
Consolidates the ethical, professional, and technical obligations engineers must uphold when using AI tools, including verification of AI-generated code and accountability for outcomes.
- The Role of AI Tools in Engineering Workflows — AI coding assistants and generative tools can accelerate engineering software development, but they introduce new responsibilities around verification and professional judgment.
- Verification of AI-Generated Code — Every piece of code produced by an AI assistant must be critically reviewed, tested, and validated before it is used in any engineering computation or product.
- Recognizing Hallucinations and Errors — AI language models can confidently produce incorrect code, fabricated function names, or physically unreasonable results—a phenomenon known as hallucination.
- Professional Engineering Accountability — Licensed and professional engineers bear legal and ethical responsibility for the work they produce and cannot transfer that responsibility to an AI tool.
- Bias, Fairness, and Equity in Engineering ML Systems — Machine learning models trained on historical data can inherit and amplify societal biases, leading to unfair or discriminatory outcomes in engineering systems that affect people.
- Transparent Documentation and Reproducibility — Responsible AI practice requires that models, datasets, training procedures, and validation results be documented thoroughly so that others can understand, audit, and reproduce the work.
- Integrating Responsible AI Habits into Daily Practice — Responsible AI is not a separate checklist but a set of habits—verification, documentation, skepticism, and ethical reflection—that should be embedded in every engineering workflow.
Learning Outcomes
MO1
Distinguish between regression and classification tasks by identifying the appropriate supervised learning approach for a given engineering problem based on the nature of the target variable
MO2
Construct a scikit-learn pipeline that chains preprocessing steps with a regression or classification estimator to train and evaluate a model on engineering data
MO3
Design a parameter sweep automation script that systematically varies input parameters, executes the corresponding computations, and stores the resulting outputs for analysis
MO4
Apply core Git commands—including add, commit, branch, merge, push, and pull—to manage version history and collaborate on an engineering code repository hosted on GitHub
MO5
Evaluate AI-generated code for correctness, hallucinations, and engineering validity before incorporating it into a computational workflow, citing the professional accountability obligations that require such verification