Class 1: Introduction to Interactive Programming Using Google Colab#
In this course, we will write and execute Python code using Google Colab—short for “Collaboratory”—rather than spending class time configuring development environments. Colab provides a browser-based coding platform that is especially well-suited to interactive programming and data-driven tasks. It supports Python natively and includes built-in libraries commonly used in engineering and data science.
Why Google Colab?#
Colab offers numerous advantages that make it ideal for classroom use:
No installation required — code runs directly in the browser
Interactive execution — edit code cells and rerun immediately
Markdown integration — include documentation and notes alongside code
Pre-installed libraries — access tools like NumPy, Pandas, and Matplotlib
Seamless cloud storage — notebooks save automatically to Google Drive
This cloud-based structure allows students to focus on learning programming concepts without worrying about local machine setup or compatibility issues.
Understanding Notebook Structure#
Google Colab notebooks are organized as a sequence of cells, which can contain either formatted text or executable code. This structure encourages an interactive, readable approach to programming—making it easy to mix explanation and execution in a single document.
A new Colab notebook will look like this:
It automatically includes a single code cell. If you mouse over the hidden “bars” between cells like we’ve done here, you’ll see the buttons to add cells.
Markdown Cells vs. Code Cells#
There are two types of cells used in Colab:
Markdown cells allow you to format explanations, instructions, or comments using rich text. These cells do not execute code, but they help make the notebook readable and instructional.
Code cells contain Python code and can be run independently. Each time a code cell is executed, Colab returns the result directly below it.
Execution Prompts#
Python code written in basic interpreters like the command-line Python shell is often preceded by prompts such as >>> for input and ... for multiline input. In contrast, Colab adopts a numbered format:
Each time a cell runs, its input/output numbers update to reflect the order of execution.
Example: Multiline Expressions#
Python allows multiline expressions using parentheses, which is particularly useful when lines are long or logically grouped:
Python Shell:
>>> (1 + 2 +
… 3 + 4)
10
In Colab:
Running Code in a Colab Notebook#
Executing Python code in a Colab notebook is simple and intuitive. Each code cell acts like a self-contained mini-program that can be edited and rerun without affecting the rest of the notebook.
How to Run a Code Cell#
To execute a code cell:
Click inside the cell and type your Python code
Press
Shift + Enterto run the cell and move to the next oneOr, click the Run button (a small ▶️ at the left of the cell, see the bottom cell in the image above)
Colab displays the result of each cell directly below the code, allowing you to verify your output immediately.
This responsive execution model allows for quick experimentation and encourages exploratory learning.
Writing Python Code: Structure and Comments#
Python code is designed to be clean and readable, following a straightforward syntax that makes it ideal for beginners and professionals alike. At its core, Python code consists of variables, expressions, functions, and control flow statements.
Using Comments to Document Your Code#
In Python, anything following a # symbol is considered a comment and is ignored by the interpreter. Comments are crucial for documenting what your code does and why—it’s a habit of good programmers.
Use comments to explain complex logic, specify units, or provide context to collaborators (and to your future self). Comments appear green in Colab so you can distinguish them from executable code.
Good Programming Practices#
Writing code that works is important—but writing code that is readable, maintainable, and debuggable is equally crucial. Good programming practices may seem like extra effort at first, but they save time and prevent errors as your projects grow in complexity.
Why Does Good Practice Matter?#
There are several compelling reasons to adopt good programming habits from the start:
Readability: Code is read more often than it’s written. Clear, well-structured code helps others (and your future self) understand your logic quickly.
Debugging: When errors occur—and they will—clean code makes finding and fixing problems much easier.
Collaboration: In team projects or shared codebases, others need to understand your work. Good practices make collaboration smoother.
Maintainability: As requirements change, well-written code is easier to modify and extend without introducing new bugs.
Professional Standards: Industry and research environments expect clean, well-documented code as a baseline competency.
Following best practices isn’t about perfection—it’s about making your engineering work more efficient and less frustrating.
Meaningful Variable Names#
One of the simplest yet most impactful ways to improve code quality is to use descriptive, meaningful variable names.
✘ Poor Names:
x = 25
y = 1.5
z = x * y
What do x, y, and z represent? Without context, this code is hard to understand.
✔ Clear Names:
hours_worked = 25
hourly_rate = 1.5
total_pay = hours_worked * hourly_rate
Now the purpose of each variable is immediately obvious. This makes debugging, collaboration, and future modifications far easier.
Guidelines for naming:
Use names that clearly describe what the variable represents
Avoid single-letter names except for very short loops or mathematical formulas
Choose names that make your code self-documenting
Use Consistent Code Formatting#
Consistent formatting makes code easier to scan and understand. Python has strong community conventions that you should follow:
Spacing: Use spaces around operators for readability
✔
a = b + c✘
a=b+c
Line Length: Keep lines as short as possible. Break long expressions into multiple lines when needed.
Indentation: Use 4 spaces for indentation (Colab handles this automatically when you press
Tab)Blank Lines: Use blank lines to separate logical sections of your code, making the structure clearer
Naming Convention: Stick to one style—either
snake_caseorcamelCase—and use it consistently throughout your code
Consistency helps your brain recognize patterns and makes errors stand out more clearly.
Break Down Complex Problems#
When faced with a complex calculation or multi-step process, resist the urge to cram everything into a single line. Breaking problems into smaller steps makes code more readable and easier to debug.
✘ One Giant Expression:
result = ((a + b) * (c - d) / (e + f)) ** 2 + sqrt(g * h)
This is hard to read, hard to debug, and hard to modify.
✔ Step-by-Step:
sum_ab = a + b
diff_cd = c - d
sum_ef = e + f
ratio = sum_ab * diff_cd / sum_ef
squared_ratio = ratio ** 2
product_gh = g * h
result = squared_ratio + sqrt(product_gh)
Each intermediate step has a clear purpose, making it easy to verify correctness and locate errors.
Use Constants for “Magic Numbers”#
When your code contains specific numeric values, ask yourself: What does this number represent? If it has a clear meaning, define it as a named constant at the top of your code.
✘ “Magic Numbers”:
if speed > 55:
print("Speeding!")
area = 3.14159 * radius ** 2
What does 55 mean? Why 3.14159?
✔ Named Constants:
SPEED_LIMIT = 55 # mph
PI = 3.14159
if speed > SPEED_LIMIT:
print("Speeding!")
area = PI * radius ** 2
Named constants make your code self-documenting and make it easy to change values in one place if needed.
Convention: Use ALL_CAPS for constant names to signal that these values should not be changed.
Error Prevention Strategies#
Catching errors early saves time and frustration. Here are some practices that help prevent bugs before they happen:
Check your types: Use
type(variable)when debugging to verify that variables hold the data types you expectTest with simple cases: Before running complex calculations, try your code with simple, known inputs/outputs to verify correctness
Print intermediate values: Use
print()statements to check calculations at each step—this helps isolate where errors occurAvoid variable name reuse: Don’t reuse variable names for different purposes within the same code block
Be careful with division: Remember the difference between
/(float division),//(integer division), and%(modulo/remainder)
These habits become second nature with practice and can save hours of debugging time.
Debugging Best Practices#
When things go wrong (and they will), a systematic approach to debugging is essential:
Read the error message carefully: Python’s error messages often tell you exactly what went wrong and where
Check the line number: Error messages point you to the line where Python detected the problem
Use print statements: Add
print()calls to display variable values at key pointsSimplify: If you can’t find the error, try simplifying your code to isolate the problem
Test incrementally: Run your code frequently as you write it, rather than writing large chunks before testing
Compare to working examples: Look at similar code that works correctly and identify differences
Remember: every programmer—no matter how experienced—spends significant time debugging. It’s a normal and valuable part of the development process.
Code Organization in Notebooks#
Colab notebooks encourage mixing code and documentation, but organization still matters:
One concept per cell: Don’t cram everything into a single cell. Break your code into logical chunks.
Use Markdown cells: Add text cells to explain what each section does—treat your notebook like a report.
Logical order: Structure your notebook with imports first, then constants, then main calculations.
Clear cell labels: Use Markdown headers (e.g.,
## Data Loading,## Analysis) to organize sections.Clean up: Remove or comment out debug
print()statements in your final version—keep output focused on results.
A well-organized notebook tells a clear story and makes it easy for others (including graders!) to follow your work.
Common Mistakes to Avoid#
As you write more code, watch out for these frequent pitfalls:
Overwriting built-ins: Don’t name variables
print,type,max,sum, etc.—these are Python’s built-in functions, and overwriting them causes confusing errors.Inconsistent naming: Pick a naming style (
snake_caseorcamelCase) and stick with it throughout your code.No comments on complex logic: If it took you time to figure out how to write the code, it will take others (or future you) time to understand it—add a comment.
Copy-paste errors: When copying similar code, double-check that you’ve updated all the variable names appropriately.
Ignoring error messages: Read error messages carefully—they often tell you exactly what’s wrong and where to look.
Awareness of these mistakes helps you avoid them and catch them quickly when they occur.
Summary: The Path to Better Code#
Good programming practices are about more than just making code work—they’re about making code understandable, maintainable, and professional. Here are the key principles:
Write for humans first: Use clear names and helpful comments
Be consistent: Follow formatting, naming, and style conventions
Break it down: Divide complex problems into simple, manageable steps
Test as you go: Don’t wait until the end to run your code
Document your thinking: Start planning out your program structure in comments first—this helps clarify your logic before you write code
Following these practices takes a bit more time upfront, but it pays dividends when debugging, collaborating, or revisiting your code later. Future you will thank present you!
Good programming practices make engineering problems easier to solve.
Declaring Variables in Python#
A variable is a named reference to data stored in memory. Variables allow you to label information and refer back to it later in your program.
Python uses assignment statements to create variables:
There’s no need to declare a type in advance—Python automatically infers it based on the assigned value. (That squiggly line is Colab telling you there’s something off with your formatting. Here, it’s expecting single quotes around the word value, because value is a string. More on that later.)
Example: Storing and Displaying Data#
This approach makes Python flexible and efficient for quick experimentation and rapid development.
Modifying Variables Dynamically#
One of the powerful features of Python in Colab notebooks is the ability to change the value of variables and immediately rerun code cells to observe the updated behavior. This dynamic workflow enables rapid experimentation and real-time debugging.
Reassigning Variable Values#
You can reassign a new value to an existing variable at any time:
Later in the notebook, you might update that value:
This approach reinforces the interactive nature of Colab notebooks. You’re not tied to a fixed sequence of execution—each cell can be run and rerun independently, which makes it easy to refine your logic, explore hypotheses, and test different outcomes on the fly.
Simultaneous Assignment#
Python also supports simultaneous assignment, allowing you to assign multiple variables in a single line. For example:
quantity = 3
cost = 5
total_cost, unit_cost = quantity * cost, cost / quantity
Note that the expressions on the right are evaluated first, and then the results are assigned to the variables on the left. Because of this, in Python, you can swap two variables without needing a temporary variable:
x = 10
y = 5
x, y = y, x
will result in x being 5 and y being 10 because the expressions on the right are evaluated before any assignments occur. In effect, Python creates a temporary tuple (y, x) and then unpacks it into x and y.
Saving and Accessing Notebooks via Google Drive#
Colab notebooks live in the cloud, which means your work is automatically saved and easily accessible from any device with internet access. Throughout this course, all assignments and coding activities will be distributed as notebook links via our course site.
Saving Your Own Copy#
To preserve your edits and submit work:
Open the shared Colab link from Blackboard.
In the notebook menu, click File → Save a Copy in Drive.
Your personal copy will be saved to a folder called “Colab Notebooks” in your Google Drive.
This copy is fully yours—you can modify, rename, or organize it however you’d like.
Accessing Work Later#
Once saved, you can return to your notebook at any time by navigating to:
Google Drive → Colab Notebooks → [Your File Name].ipynb
If you’re going to turn the file in, we recommend adding your name to the end of the original file name, which will correspond to the class it was assigned in. There’s no need to redownload or re-upload anything; your work stays synced across sessions.
💡 Tip: You can also bookmark your personalized notebook links for even faster access.
Perfect—here we go with the next section, carrying forward that same voice and clarity:
#
2. Why Engineers Need Programming#
Programming is a fundamental skill for modern engineers. Whether you’re designing mechanical systems, analyzing electrical circuits, or processing large datasets, code provides a powerful toolkit for solving problems efficiently and accurately.
How Programming Enhances Engineering Practice#
Here are just a few ways that programming empowers engineers:
Automating repetitive tasks — like data processing, simulation, or report generation
Modeling and simulating systems — such as stress analysis or heat transfer
Controlling hardware and interfaces — for robotics, sensors, or embedded systems
Analyzing and visualizing data — making sense of complex experiments or diagnostics
Mastering programming doesn’t just make tasks easier—it expands what’s possible.
Data in Programming: The Role of Variables#
To harness the power of code, you’ll first need to understand how computers store and manipulate information. That starts with variables.
A variable is like a labeled container for data: it holds a value that can be retrieved or changed over time. This makes variables fundamental to virtually every program you’ll write.
Think of a digital thermometer that updates the room temperature in real time. Each time the sensor reads a new value, it updates the variable storing that temperature.
Declaring and Updating Variables in Python#
In Python, variables are created using a simple assignment statement, binding a name to a value. There’s no need to specify a data type in advance—Python uses dynamic typing to determine the type automatically based on the assigned value.
Assignment Syntax#
This straightforward syntax allows for quick experimentation. Python evaluates the right-hand side and assigns the result to the variable on the left.
Examples#
Variables in Python can be re-assigned easily—reusing the name to reference a new value.
🔍 Note: Python doesn’t mutate the value in place—it reassigns the variable name to a new memory location containing the updated value. This detail becomes important when working with mutable and immutable data types.
Writing Readable Code: Naming Conventions#
Good variable names make code easier to understand, debug, and maintain. In this course, we’ll follow the standard naming style for Python: snake_case.
What is snake_case?#
Snake_case means writing compound names in all lowercase, separating words with underscores:
student_name = "Alice"
total_cost = 49.99
This contrasts with other styles like:
camelCase→ e.g.,studentNamePascalCase→ e.g.,StudentName
Python programmers overwhelmingly prefer snake_case for variables and function names.
Best Practices for Naming#
✅ Use names that clearly describe the variable’s role (
volume,speed_limit,sensor_value)✅ Stick with lowercase letters and underscores
❌ Avoid using Python keywords (e.g.,
print,def,if)❌ Never start a name with a number (e.g.,
3datais invalid)
Examples#
Data Types in Python#
Every piece of data in a Python program has a type—a classification that determines what kind of information it is and what operations can be performed on it. Python includes several built-in data types that are commonly used in engineering and scientific programming.
Numeric Types#
Python supports three primary numeric types:
int: Integer values (whole numbers)float: Numbers with decimal pointscomplex: Numbers with real and imaginary parts
Python also supports scientific notation for very large or small numbers:
Arithmetic Operators#
You can use a variety of math operators with numeric types—just like you would in a calculator.
Operator |
Description |
Example |
Result |
|---|---|---|---|
|
Addition |
|
|
|
Subtraction |
|
|
|
Multiplication |
|
|
|
Float Division |
|
|
|
Integer (floor) Division |
|
|
|
Remainder (modulus) |
|
|
|
Exponentiation |
|
|
These operators can be used with variables as well:
Python evaluates expressions following standard order of operations (PEMDAS), so parentheses can help group operations as needed.
Other Common Python Data Types#
Beyond numbers, Python provides built-in types for handling text, logical values, and structured collections. These are essential for representing real-world information in programs.
str: Strings (Text)
A string is a sequence of characters enclosed in quotes.
You can store names, messages, filenames—any kind of text. Strings can also include escape characters like \n for new lines.
Boolean Values#
A boolean (or bool) represents truth values—either True or False. Booleans are commonly used in comparisons and control flow.
Ordered Collections#
A list holds multiple items in a specific order. Lists are mutable, meaning you can change their contents.
Immutable Sequences#
A tuple is similar to a list but cannot be changed after it’s created.
Tuples are useful when you want to group related values that should remain fixed. Note the difference between declaring a list and a tuple. The list uses square brackets while the list uses parentheses.
Key-Value Pairs#
A dictionary maps keys to values—like a miniature database.
Unique Unordered Values#
A set is an unordered collection of unique items—duplicates are automatically removed.
These types will be explored more deeply in future lessons, but it’s helpful to start seeing how varied and flexible Python’s data structures are.
#
Constants and Immutability#
Some values in a program are intended to remain unchanged throughout its execution. While Python doesn’t enforce constants the way some languages do, there are standard conventions for signaling that a variable should not be altered.
Representing Constants in Python#
Although Python lacks a built-in const keyword, programmers use all-uppercase variable names to indicate constants:
Using uppercase helps convey intent: these values should not be reassigned during program execution. It’s a convention—Python won’t prevent changes, but the community encourages treating such values as fixed.
As discussed earlier in the “Good Programming Practices” section, using named constants helps eliminate “magic numbers”—unexplained numeric values scattered throughout your code. By defining constants like SPEED_LIMIT = 55 or PI = 3.14159 at the top of your program, you make your code more readable and maintainable.
Immutable vs. Mutable Data#
Certain data types in Python are immutable—once an object is created, it cannot be changed. Others are mutable, meaning their contents can be modified in place.
Immutable Types Include:#
int– whole numbers (e.g.,5)float– decimal numbers (e.g.,3.14)str– text (e.g.,"hello")tuple– ordered groups (e.g.,(1, 2, 3))frozenset– unchangeable version of a set
Mutable Types Include:#
list– ordered collectionsdict– key-value mappingsset– unordered, unique values
Important Clarification: Variables vs. Values#
Even though immutable types like integers and strings can’t be altered in place, variables that refer to them can still be reassigned.
In this example, x didn’t mutate the number 5; rather, Python created a new integer object (6) and reassigned the name x to it.
The same is true for strings:
This behavior will become more important as we move into collections, where mutability affects how variables interact with memory and references.
#
Python’s Built-in Functions#
Python provides a wide collection of built-in functions—ready-made tools that perform common tasks. These functions are always available and don’t require any imports. You’ve already met print() in earlier examples; now let’s explore a few others that you’ll likely use early and often.
print(): Displaying Output#
Used to send output to the screen. You can print strings, variables, or expressions.
Print is often used for debugging or giving feedback to users.
round(): Rounding Numbers#
Rounds a float to the nearest integer, or to a specified number of decimal places.
This is helpful when formatting numeric results for display or reporting.
type(): Checking a Variable’s Data Type#
Returns the type of the value referenced by a variable.
This is useful when debugging or when you’re unsure how Python is interpreting a value.
del: Deleting Variables#
Removes a variable from memory. Once deleted, a variable can’t be used until reassigned.
Use del with care—it’s not often needed in beginner programs.
A Naming Note: Don’t Shadow Built-ins
Avoid using the same names as Python’s built-in functions for your own variables:
If you accidentally overwrite one, you can recover it by restarting your Colab runtime or using del print.
Comments That Add Value#
While we introduced comments earlier, it’s important to understand what makes a comment useful versus what makes it unnecessary or redundant.
✘ Obvious Comments:
These comments don’t add value—they simply restate what the code already says clearly.
✔ Meaningful Comments:
These comments explain why the code does what it does or provide context that isn’t obvious from the code alone.
When to comment:
Explain complex logic or algorithms
Document assumptions or limitations
Clarify units or physical meanings (e.g., “distance in meters”)
Provide context that helps future readers understand your reasoning
When not to comment:
Don’t state the obvious
Don’t use comments to explain poorly named variables—rename them instead