Instructional Design for Python Programming

Siju Swamy

Saintgits

While the syllabus provides a roadmap of what will be taught, instructional design details the “how” and “why” of teaching each component, aiming to create a coherent and engaging learning experience. This process ensures that the course not only covers the necessary material but also aligns with educational goals and effectively supports students in achieving them. Then What is Instructional Design?. Watch the following video to get a clear understanding.

Course Title: Python Programming (for Algorithmic Thinking)

Course Description:

This lab-based one credit course introduces algorithmic thinking through Python programming. Designed for engineers, it covers fundamental programming concepts and their application to real-world problems. The course emphasizes the development of algorithms and their implementation in Python, preparing students to approach problem-solving methodically.

Course Objectives

The course objecives are:

  1. Characterize and Identify Computer Components:
    • Understand and describe the functional units and components of a computer system, including hardware, software, and language translators.
  2. Develop Proficiency in Python Programming:
    • Gain the ability to code, test, and debug simple Python programs, demonstrating proficiency in basic programming concepts and practices.
  3. Implement Control Structures:
    • Apply branching and looping statements in Python to develop programs that solve problems through conditional logic and repetitive tasks.
  4. Utilize Python Data Structures:
    • Effectively use supported data structures such as lists, dictionaries, and tuples to organize and manage data in Python programs.

Course Outcomes

After the successful completion of the course, the graduate will be able to:

  1. Design and Implement Algorithms:
    • Develop, analyze, and apply algorithms to solve a variety of computational problems using Python.
  2. Program Efficiently in Python:
    • Write, debug, and optimize Python code, utilizing core programming constructs and data structures effectively.
  3. Apply Data Structures and Functions:
    • Use Python’s data structures, such as lists, tuples, and dictionaries, and modularize code with functions for efficient problem-solving.
  4. Utilize Development Tools:
    • Leverage development tools like GitHub and Raptor for effective coding, documentation, and algorithm visualization.

Course Introduction

To introduce the “Python Programming for Algorithmic Thinking” course to students from various branches, begin by explaining the universal relevance of algorithmic thinking in everyday problem-solving. Use a simple context, such as organizing a group project: just as you would plan tasks and delegate responsibilities to ensure the project is completed efficiently and effectively, algorithmic thinking involves creating systematic methods to solve problems. A block diagram representing this example is given below.

graph TD
    A[Start Project] --> B[Identify Objectives]
    B --> C[Break Down Tasks]
    C --> D[Assign Responsibilities]
    D --> E[Set Deadlines]
    E --> F[Execute Tasks]
    F --> G[Monitor Progress]
    G --> H[Review and Adjust]
    H --> I[Complete Project]
    I --> J[Project Successful]

    style A fill:#f9f,stroke:#333,stroke-width:2px,color:#000;
    style B fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style C fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style D fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style E fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style F fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style G fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style H fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style I fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style J fill:#cfc,stroke:#333,stroke-width:2px,color:#000;
Figure 1: State diagram to successfully finish a project.

Emphasize that the (the algorithmic thinking) skills learned will be valuable across all engineering disciplines, enhancing their problem-solving capabilities and preparing them for complex challenges in their academic and professional careers. This approach will help students appreciate the broad applicability of the course content and encourage active participation.

A Seven-in-One Problem!

In this context, we will explore how algorithmic thinking can be applied across different engineering branches using a common example. Each branch of engineering plays a critical role in developing and implementing this system, demonstrating the relevance and application of algorithms in diverse fields. Let us formulate the context and problem statement as follows.

Context:

A city wants to implement a smart traffic management system to improve traffic flow and reduce congestion at intersections. The system will use sensors and data analysis to control traffic lights dynamically.

Problem:

Design an algorithm to manage traffic lights at a busy intersection based on real-time traffic data from sensors. The goal is to optimize traffic flow and minimize waiting times for vehicles.

Steps for Algorithmic Thinking:

1. Civil Engineering

  • Problem: Design the layout of the intersection to ensure efficient traffic flow.
  • Algorithm: Develop an algorithm to determine optimal road layouts and signal timings based on traffic volume and road capacity.

The block diagram is shown in Fig- 2

graph TD
    A[Design Intersection Layout] --> B[Analyze Traffic Volume]
    B --> C[Determine Optimal Signal Timings]
    C --> D[Implement Traffic Light Control]
    D --> E[Monitor Traffic Flow]
    E --> F[Adjust Layout Based on Data]

    style A fill:#f9f,stroke:#333,stroke-width:2px,color:#000;
    style B fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style C fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style D fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style E fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style F fill:#cfc,stroke:#333,stroke-width:2px,color:#000;
Figure 2: State diagram for Civil Engineering Tribe.

2. Mechanical Engineering:

  • Problem: Create a mechanism for automated traffic lights that can withstand varying weather conditions.
  • Algorithm: Develop an algorithm to control the mechanical parts of traffic lights and adjust for environmental factors.

The block diagram is shown in Fig- 3

graph TD
    A[Design Traffic Light Mechanism] --> B[Select Durable Materials]
    B --> C[Create Weather-Resistant Design]
    C --> D[Develop Control Mechanism]
    D --> E[Automate Traffic Light Adjustments]
    E --> F[Test Mechanism for Reliability]

    style A fill:#f9f,stroke:#333,stroke-width:2px,color:#000;
    style B fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style C fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style D fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style E fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style F fill:#cfc,stroke:#333,stroke-width:2px,color:#000;
Figure 3: State diagram for Mechanical Engineering Tribe.

3. Chemical Engineering:

  • Problem: Design materials for road signs and sensors that are durable and effective.
  • Algorithm: Develop an algorithm to evaluate and select materials based on their chemical properties and environmental impact.

The block diagram is shown in Fig- 4

graph TD
    A[Design Road Signs and Sensors] --> B[Evaluate Material Properties]
    B --> C[Select Chemical-Resistant Materials]
    C --> D[Ensure Environmental Impact]
    D --> E[Test Durability]
    E --> F[Implement in Traffic System]

    style A fill:#f9f,stroke:#333,stroke-width:2px,color:#000;
    style B fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style C fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style D fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style E fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style F fill:#cfc,stroke:#333,stroke-width:2px,color:#000;
Figure 4: State diagram for Chemical Engineering Tribe.

4. Food Technology:

  • Problem: Ensure that traffic management systems in areas with food distribution centers do not disrupt deliveries.
  • Algorithm: Create an algorithm to prioritize traffic flow for delivery vehicles during peak hours to avoid delays.

The block diagram is shown in Fig- 5

graph TD
    A[Assess Impact on Delivery Routes] --> B[Prioritize Delivery Vehicles]
    B --> C[Design Traffic Light Scheduling]
    C --> D[Implement Scheduling in System]
    D --> E[Monitor Delivery Efficiency]
    E --> F[Adjust Based on Feedback]

    style A fill:#f9f,stroke:#333,stroke-width:2px,color:#000;
    style B fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style C fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style D fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style E fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style F fill:#cfc,stroke:#333,stroke-width:2px,color:#000;
Figure 5: State diagram for Food Engineering Tribe.

5. Electronics and Communication:

  • Problem: Implement sensor networks and communication systems for data collection and signal control.
  • Algorithm: Develop algorithms for data transmission, sensor data integration, and communication between traffic lights and control systems.

The block diagram is shown in Fig- 6

graph TD
    A[Implement Sensor Network] --> B[Design Data Transmission System]
    B --> C[Integrate Sensors with Traffic Lights]
    C --> D[Develop Communication Protocols]
    D --> E[Ensure Reliable Data Transfer]
    E --> F[Optimize Communication System]

    style A fill:#f9f,stroke:#333,stroke-width:2px,color:#000;
    style B fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style C fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style D fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style E fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style F fill:#cfc,stroke:#333,stroke-width:2px,color:#000;
Figure 6: State diagram for Electronics and Communication Engineering Tribe.

6. Robotics and Automation:

  • Problem: Automate the adjustment of traffic lights based on real-time data.
  • Algorithm: Design an algorithm to control automated systems that adjust traffic lights dynamically based on sensor data and predefined rules.

The block diagram is shown in Fig- 7

graph TD
    A[Develop Automation System] --> B[Create Real-Time Adjustment Algorithms]
    B --> C[Integrate with Traffic Lights]
    C --> D[Test for Dynamic Control]
    D --> E[Optimize Automation for Traffic Flow]
    E --> F[Monitor and Refine System]

    style A fill:#f9f,stroke:#333,stroke-width:2px,color:#000;
    style B fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style C fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style D fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style E fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style F fill:#cfc,stroke:#333,stroke-width:2px,color:#000;
Figure 7: State diagram for Robotics Tribe.

7. Computer Science:

  • Problem: Create a software system to process traffic data and control traffic lights.
  • Algorithm: Develop a software algorithm that processes data from traffic sensors, makes real-time decisions on traffic light timings, and adjusts signals to optimize traffic flow.

The block diagram is shown in Fig- 8

graph TD
    A[Develop Software System] --> B[Process Traffic Data]
    B --> C[Implement Decision-Making Algorithms]
    C --> D[Control Traffic Lights Based on Data]
    D --> E[Test and Debug System]
    E --> F[Deploy and Monitor System]

    style A fill:#f9f,stroke:#333,stroke-width:2px,color:#000;
    style B fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style C fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style D fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style E fill:#ccf,stroke:#333,stroke-width:2px,color:#000;
    style F fill:#cfc,stroke:#333,stroke-width:2px,color:#000;
Figure 8: State diagram for Computer Science Tribe.

Expected Partial Outcome

By designing and implementing algorithms for this traffic management system, engineers from various branches contribute to creating a more efficient and responsive traffic control system. Each branch applies algorithmic thinking to address specific aspects of the problem, demonstrating the relevance and application of algorithms in real-world scenarios.

Key Takeaway

By engaging with the various engineering contexts illustrated through algorithmic thinking, students will gain a deeper appreciation for how structured problem-solving can lead to better planning, efficient design, and successful execution in real-world scenarios. Algorithmic thinking is not just about writing code but about systematically breaking down complex challenges into manageable steps, which is crucial for effective engineering solutions. Understanding and applying this approach will empower students to tackle problems more efficiently, optimize processes, and enhance their ability to innovate across different engineering disciplines.

Wait a second…

Friends, do you ever think this instructional design might seem impractical? Let me challenge that idea. Time can feel like a stubborn illusion, but have you ever wondered how your students really perceive it? Imagine seeing their experience from their perspective. Do they feel confined by the rigid structures we often impose, or do they crave a more dynamic approach? By understanding how they truly think and engage with our sessions, we might find that what seems impractical to us could actually be exactly what they need to thrive. Let’s open our minds to how changing our approach can make a real difference in their learning experience. Just watch the following video.

The next session will focus on translating the conceptual framework of algorithmic thinking into a computational framework. This transition will involve exploring the fundamental components and functions of computer systems, which are essential for implementing algorithms in a practical programming environment.

Conceptual to Computational

Algorithmic thinking offers a robust conceptual framework for addressing complex problems through systematic decomposition into manageable steps. This method allows for effective planning, design, and implementation of solutions. However, transitioning from conceptual frameworks to practical applications necessitates a foundational understanding of computer systems.

To effectively translate algorithmic concepts into computational implementations, it is essential to grasp how computer systems operate. Knowledge of computer architecture, software types, and various programming tools is crucial for converting algorithms into executable programs and optimizing these solutions.

This course will introduce the basic components and functions of computer systems, including hardware, software, and programming environments. This foundational understanding will bridge the gap between theoretical algorithmic thinking and practical computational implementation, facilitating the effective application of algorithms in programming tasks.

Familiarization of Computer System, Editors, Various Language Translators

Knowledge of computer architecture, including the roles of input/output devices, memory, and various types of software, enables programmers to write more efficient and effective code. This understanding helps in debugging, optimizing performance, and leveraging system resources effectively. By grasping how language translators like compilers, interpreters, and assemblers work, programmers can better appreciate how their code is transformed into executable instructions and troubleshoot issues with greater precision.

The poetry of programming

To showcase how the new generation views and engages with technology, we can draw inspiration from Linda Liukas’ TEDx talk. In her presentation, Liukas passionately argues that a significant movement in technology is underway, emphasizing the need for inclusive and diverse participation, especially from younger generations. Her vision of technology, framed as the “poetry of code,” highlights how creativity and diversity can shape a more vibrant and innovative tech landscape. By including her TEDx video, we can provide a compelling testimonial that illustrates how the next generation perceives and interacts with technology, reinforcing the importance of adapting our instructional designs to better connect with their perspectives and aspirations.

Introduction to Computer Architecture

1. Block Diagram of Computer: The block diagram of a computer provides a visual representation of its major components and their interconnections. It typically includes the Central Processing Unit (CPU), Memory, Input Devices, Output Devices, and Storage Units. This diagram helps in understanding the flow of data and control signals within the computer system. A sample block diagram is shown in Fig- 9.

Figure 9: Block Diagram of a Computer

2. Hardware: Hardware refers to the physical components of a computer system. It includes the CPU, motherboard, RAM, hard drives, input devices (such as keyboards and mice), output devices (such as monitors and printers), and peripheral devices. Understanding hardware is crucial for comprehending how software interacts with physical components to perform tasks.

3. Input and Output Devices: - Input Devices: These are devices used to enter data into a computer. Common examples include keyboards, mice, scanners, and microphones. - Output Devices: These devices display or output data from the computer. Examples include monitors, printers, and speakers.

4. Memory: Memory in a computer system is used to store data and instructions. It includes: - Primary Memory (RAM): Volatile memory that temporarily holds data and instructions currently in use. - Secondary Memory (Storage): Non-volatile memory used for long-term data storage, such as hard drives and SSDs.

Software

1. Types of Software: - System Software: Includes operating systems (e.g., Windows, macOS, Linux) that manage hardware resources and provide a platform for running applications. - Application Software: Programs designed for end-users to perform specific tasks, such as word processors, web browsers, and games.

2. High-Level Languages: High-level programming languages are designed to be easy for humans to read and write. Examples include Python, Java, and C++. They are used to write programs that are compiled or interpreted into machine code.

3. Low-Level Languages: Low-level languages are closer to machine code and provide less abstraction from the hardware. Examples include assembly language, which is specific to a particular computer architecture and provides a symbolic representation of machine instructions.

4. Assembly Languages: Assembly language is a low-level programming language that uses symbolic names for instructions and data. It is specific to a computer architecture and is used to write programs that interact directly with hardware.

Language Translators

1. Compiler: A compiler is a program that translates high-level source code into machine code or intermediate code that can be executed by the computer. It performs syntax checking, optimization, and generates executable files.

2. Interpreter: An interpreter translates high-level source code into machine code line-by-line or statement-by-statement at runtime. It does not produce an executable file but directly executes the instructions. Examples include Python interpreters.

3. Assembler: An assembler translates assembly language code into machine code. It converts symbolic instructions into binary instructions that the computer’s CPU can execute.

Need and Significance of Technical Know-how on Computer System

Understanding the fundamentals of computer systems, including hardware components, software types, and language translators, is crucial for engineers as they move from conceptual ideas to practical, computer-based solutions. Familiarity with computer architecture helps engineers grasp how different hardware elements interact and how data flows through the system. Knowledge of software types and language translators enables engineers to select appropriate programming tools and languages for implementing their algorithms efficiently.

Before delving into the development of algorithms and flow charts, it is essential to understand the fundamental concepts of the computer system, as they provide the groundwork for translating conceptual ideas into computational solutions. The knowledge of computer architecture, memory, and software helps in effectively implementing and visualizing algorithms within a computer system.

With this foundational understanding in place, the focus shifts to developing algorithms and flow charts, which are designed with specific structures to facilitate standardization.

Developing Algorithms and Flow Charts

In the computational framework, standardizing the step-by-step process of algorithmic thinking is crucial for ensuring consistency and clarity in program development.

Introduction to Algorithms

1. What is an Algorithm?

An algorithm is a well-defined sequence of steps or instructions designed to perform a specific task or solve a particular problem. It serves as a blueprint for writing computer programs. Algorithms are essential for problem-solving as they provide a clear and systematic approach to achieving desired outcomes.

2. Properties of a Good Algorithm

A well-constructed algorithm possesses several key properties: - Finiteness: The algorithm must have a finite number of steps and should terminate after a certain number of operations. - Definiteness: Each step of the algorithm should be precisely defined and unambiguous. - Input: The algorithm should accept zero or more inputs, which are the data necessary for its execution. - Output: The algorithm should produce at least one output, which is the result or solution of the problem. - Effectiveness: Each step of the algorithm should be basic enough to be executed within a finite amount of time.

Introduction to Flow Charts

1. What is a Flow Chart?

A flow chart is a visual representation of an algorithm, using various symbols to denote different types of operations or steps. Flow charts help in understanding and communicating the logic of an algorithm more clearly by illustrating the flow of control and decision-making process.

2. Key Symbols in Flow Charts

  • Oval: Represents the start and end points of the flow chart.
  • Rectangle: Indicates a process or action step.
  • Diamond: Denotes a decision point, where branching occurs based on conditions.
  • Parallelogram: Used for input and output operations.
  • Arrow: Shows the direction of flow between steps.

Standardizing Algorithmic Thinking

In the computational framework, algorithms and flow charts are designed with a specific structure to ensure that the problem-solving approach is standardized. This standardization helps in maintaining consistency in how algorithms are developed, communicated, and executed. By adhering to these standardized structures, engineers and programmers can more effectively design, analyze, and implement solutions, ensuring that the computational processes are efficient and reliable.

In the upcoming sessions, students will have the opportunity to explore more examples and apply the principles of algorithmic thinking and flowchart design to a variety of problems.

1. Crossing a Traffic Signal

Problem: Write the algorithm and flowchart for the program to determine whether a pedestrian can cross the road based on the traffic signal color.

Algorithm:

  1. Start
  2. Observe the traffic signal color
  3. If the signal is green, “Cross the road”
  4. Else if the signal is yellow, “Wait”
  5. Else if the signal is red, “wait”
  6. End

Flowchart: Flowchart for this program is shown in Fig- 10.

flowchart TD
    A((Start)) --> B{Check traffic light color}
    B -- Red --> C[Wait]
    B -- Yellow --> D[Wait]
    B -- Green --> E[Cross the road]
    C --> B
    D --> B
    E --> F((Stop))
    
    %% Define styles
    classDef startEnd fill:#ffffff,stroke:#000000,color:#000000;
    classDef inputOutput fill:#f0f0f0,stroke:#000000,color:#000000;
    classDef decision fill:#e0e0e0,stroke:#000000,color:#000000;
    
    %% Apply styles to nodes
    class A,H startEnd;
    class B,D,F,G inputOutput;
    class C,E decision;
Figure 10: Flowchart of the program to cross the trafic signal.

2. Finding the Maximum of Two Numbers

Problem: Write the algorithm and draw the flowchart for the program that takes two numbers as input and prints the larger of the two.

Algorithm:

  1. Start
  2. Input two numbers, A and B
  3. If A is greater than B, print A
  4. Otherwise, print B
  5. End

Flowchart

Flowchart for this program is shown in Fig- 11.

flowchart TD
    A([Start]) --> B[Input A and B]
    B --> C{Is A > B?}
    C -- Yes --> D[Print A]
    C -- No --> E[Print B]
    D --> F([End])
    E --> F
    
    %% Define styles
    classDef startEnd fill:#ffffff,stroke:#000000,color:#000000;
    classDef inputOutput fill:#f0f0f0,stroke:#000000,color:#000000;
    classDef decision fill:#e0e0e0,stroke:#000000,color:#000000;
    
    %% Apply styles to nodes
    class A,F startEnd;
    class B,D,E inputOutput;
    class C decision;
Figure 11: Flowchart of the program to find larger of two numbers.

3. Finding the Largest of Three Numbers

Problem: Write a program that takes three numbers as input and prints the largest of the three.

Algorithm:

  1. Start
  2. Input three numbers, A, B, and C
  3. If A is greater than B and A is greater than C, print A
  4. Else if B is greater than A and B is greater than C, print B
  5. Otherwise, print C
  6. End

Flowchart: Flowchart for this program is shown in Fig- 12.

flowchart TD
    A([Start]) --> B[Input A, B, and C]
    B --> C{Is A > B?}
    C -->|Yes| D{Is A > C?}
    C -->|No| E{Is B > C?}
    D -- Yes --> F[Print A]
    D -- No --> G[Print C]
    E -- Yes --> H[Print B]
    E -- No --> G
    F --> I([End])
    H --> I
    G --> I
    
    %% Define styles
    classDef startEnd fill:#ffffff,stroke:#000000,color:#000000;
    classDef inputOutput fill:#f0f0f0,stroke:#000000,color:#000000;
    classDef decision fill:#e0e0e0,stroke:#000000,color:#000000;
    
    %% Apply styles to nodes
    class A,I startEnd;
    class B,F,H inputOutput;
    class C,D,E decision;
Figure 12: Flowchart of the program to find largest of three numbers.

4. Class Joining Dilema

Problem: Write the algorithm and draw the flowchart for the program to determine whether a student will join a class based on whether their favorite teacher and best friend are in the class.

Algorithm:

  1. Start
  2. Observe the presence of the favorite teacher
  3. Observe the presence of the best friend
  4. If both the favorite teacher and the best friend are present, “Join the class”
  5. Else, “Do not join the class”
  6. End

Flowchart: Flowchart for this program is shown in Fig- 13.

flowchart TD
    A([Start]) --> B{Is favourite teacher in class?}
    B -- Yes --> C{Is best friend in class?}
    C -- Yes --> D[Joins class]
    B -- No --> E[Does not join class]
    C -- No --> E[Does not join class]
    E --> F([Stop])
    %% Define styles
    classDef startEnd fill:#ffffff,stroke:#000000,color:#000000;
    classDef inputOutput fill:#f0f0f0,stroke:#000000,color:#000000;
    classDef decision fill:#e0e0e0,stroke:#000000,color:#000000;
    
    %% Apply styles to nodes
    class A,I startEnd;
    class B,F,H inputOutput;
    class C,D,E decision;
Figure 13: Flowchart of the program to join the class

Transition from Algorithmic Thinking to Programming

The algorithmic thinking process involves breaking down a problem into a series of logical steps, as illustrated by our flowcharts. This conceptual framework is very important for defining clear, sequential instructions to solve a problem. However, to bring these concepts into a practical domain, we need to translate them into a programming language that can execute these instructions.

Transition from Algorithmic Thinking to Programming

Algorithmic thinking involves deconstructing problems into logical, sequential steps, as demonstrated by our flowcharts. Converting these concepts into a practical programming language allows us to execute these steps effectively. Historically, high-level programming languages like C, C++, and Java have been instrumental in translating algorithms into executable code. Here’s a comparison of these languages with Python, highlighting why Python is particularly suitable for computational thinking in engineering. Advantages of Python over other popular programming languages is explained in the following video.

Historical Context and Comparison

C Language

Developed in the early 1970s, C is one of the earliest high-level programming languages. It provides a foundation for many modern languages and is known for its performance and low-level memory manipulation capabilities. C requires explicit management of memory and pointers, which adds complexity to code. While powerful, it lacks some of the high-level abstractions and simplicity found in Python.

C++ Language

An extension of C, C++ was developed in the early 1980s and introduced object-oriented programming features. It allows for complex data modeling and high-performance applications. C++ offers more control over system resources but at the cost of increased complexity. It involves managing object-oriented concepts and memory explicitly, which can be challenging for beginners.

Java Language

Developed in the mid-1990s, Java is known for its portability across platforms, thanks to the Java Virtual Machine (JVM). It emphasizes object-oriented programming and has extensive libraries. Java’s syntax is more verbose compared to Python. It requires managing class structures and access modifiers, which can make code less straightforward to write and read.

Why Python is Preferred for Computational Thinking?

Python, created by Guido van Rossum and first released in 1991, emerged from a desire to develop a language that was both easy to read and write, while also being powerful enough to handle complex tasks. It was inspired by the ABC language, which van Rossum had worked on during his time at Centrum Wiskunde & Informatica (CWI) in the Netherlands. Python’s base code was written in C, which provides a solid foundation for its extensive standard library and cross-platform capabilities. The language emphasizes readability and simplicity, featuring an elegant syntax that allows programmers to express concepts in fewer lines of code compared to many other languages. This design philosophy has contributed to Python’s widespread adoption across various fields, from web development to scientific computing and engineering. Popular features of Python programming language are:

1. Readability and Simplicity

Python’s syntax is designed to be clear and intuitive, resembling natural language. This simplicity allows engineers to focus on the logic of their algorithms without being bogged down by complex syntax. For computational thinking, where clarity and understanding are crucial, Python’s readability reduces cognitive load, making it easier to implement and debug algorithms.

2. Versatility and Ease of Use

Python supports multiple programming paradigms, including procedural, object-oriented, and functional programming. Its versatility makes it suitable for a wide range of applications, from simple scripts to complex systems. This adaptability is particularly useful in engineering, where problems often span different domains and require diverse approaches.

3. Rich Libraries and Frameworks

Python’s extensive standard library and third-party modules simplify many tasks. Libraries such as NumPy for numerical computations, pandas for data manipulation, and Matplotlib for visualization provide powerful tools for engineers. These libraries streamline the implementation of complex algorithms and data handling, making Python an efficient choice for solving engineering problems.

Verdict

The historical languages like C, C++, and Java have their strengths, Python’s readability, versatility, and extensive libraries make it particularly well-suited for computational thinking in engineering. By transitioning from conceptual algorithmic thinking to practical Python programming, engineers can effectively apply and implement their problem-solving strategies in a straightforward and efficient manner.

Future sessions will delve into various Python examples, reinforcing the practical application of these concepts and preparing students for advanced problem-solving in their respective engineering fields.

Just a second…

Programming extends beyond mere coding, which involves translating instructions into a form that computers can execute. While coding focuses on syntax and grammar, programming encompasses the entire process of solving problems, from understanding the problem and designing algorithms to implementing and testing solutions. This broader view highlights the importance of logical thinking, a skill central to effective programming. According to Lesli Lambort, “Programming is not just about writing code; it’s about creating solutions through a logical process.” This involves breaking down complex problems, understanding their components, and systematically building solutions. Just watch what Labort saying on this topic.

Python Fundamentals

Python Programming Overview

Python is a high-level, interpreted programming language that was created by Guido van Rossum and first released in 1991. Its design philosophy emphasizes code readability and simplicity, making it an excellent choice for both beginners and experienced developers. Over the years, Python has undergone significant development and improvement, with major releases adding new features and optimizations. The language’s versatility and ease of use have made it popular in various domains, including web development, data science, artificial intelligence, scientific computing, automation, and more. Python’s extensive standard library and active community contribute to its widespread adoption, making it one of the most popular programming languages in the world today.

Variables

In Python, variables are used to store data that can be used and manipulated throughout a program. Variables do not need explicit declaration to reserve memory space. The declaration happens automatically when a value is assigned to a variable.

Basic Input/Output Functions

Python provides built-in functions for basic input and output operations. The print() function is used to display output, while the input() function is used to take input from the user.

Output with print() function

# Printing text
print("Hello, World!")

# Printing multiple values
x = 5
y = 10
print("The value of x is:", x, "and the value of y is:", y)

Example 2

# Assigning values to variables
a = 10
b = 20.5
name = "Alice"

# Printing the values
print("Values Stored in the Variables:")
print(a)
print(b)
print(name)

Input with input() Function:

# Taking input from the user
name = input("Enter your name: ")
print("Hello, " + name + "!")

# Taking numerical input
age = int(input("Enter your age: "))
print("You are", age, "years old.")

Note

The print() function in Python, defined in the built-in __builtin__ module, is used to display output on the screen, providing a simple way to output text and variable values to the console.

Combining Variables and Input/Output

us can combine variables and input/output functions to create interactive programs.

Example: Find sum of two numbers

# Program to calculate the sum of two numbers
num1 = float(input("Enter first number: "))
num2 = float(input("Enter second number: "))

# Calculate sum
sum = num1 + num2

# Display the result
print("The sum of", num1, "and", num2, "is", sum)

Python Programming Style

Indentation

Python uses indentation to define the blocks of code. Proper indentation is crucial as it affects the program’s flow. Use 4 spaces per indentation level. For example consider the conditional statement below to find the larger among two numbers \(a\) and \(b\). Here to encapsulate the if part, we just use an indendation of 4 white spaces, similar for the else part.

if a > b:
    print("a is greater than b")
else:
    print("b is greater than or equal to a")

Comments

Use comments to explain user code. Comments begin with the # symbol and extend to the end of the line. Write comments that are clear and concise. See the example:

# This is a comment
a = 10  # This is an inline comment

Here the first line is just a comment. But in the second line, the comment is used to explain what that line of code do!

Variable Naming

Use meaningful variable names to make the code more understandable. Variable names should be in lowercase with words separated by underscores. Two examples are given below.

student_name = "John"
total_score = 95

Consistent Style

Follow the PEP 8 style guide for Python code to maintain consistency and readability. Use blank lines to separate different sections of usr code. See the following example of function definition:


def calculate_sum(x, y):
    return x + y

result = calculate_sum(5, 3)
print(result)

Basic Datatypes in Python

In Python, a datatype is a classification that specifies which type of value a variable can hold. Understanding datatypes is essential as it helps in performing appropriate operations on variables. Python supports various built-in datatypes, which can be categorized into several groups.

Numeric Types

Numeric types represent data that consists of numbers. Python has three distinct numeric types:

  1. Integers (int):
    • Whole numbers, positive or negative, without decimals.
    • Example: a = 10, b = -5.
  2. Floating Point Numbers (float):
    • Numbers that contain a decimal point.
    • Example: pi = 3.14, temperature = -7.5.
  3. Complex Numbers (complex):
    • Numbers with a real and an imaginary part.
    • Example: z = 3 + 4j.
# Examples of numeric types
a = 10         # Integer
pi = 3.14      # Float
z = 3 + 4j     # Complex

How to find datatype of a variable?

To get the type of a variable in Python, you can use the built-in type() function.

The basic syntax looks like this:

type(variable_name)

We can try this function in the above example as follows.

# Examples of numeric types
a = 10         # Integer
pi = 3.14      # Float
z = 3 + 4j     # Complex
# extract datatype

type(a)
type(pi)
type(z)

Sequence Types

Sequence types are used to store multiple items in a single variable. Python has several sequence types, including:

String Type

Strings in Python are sequences of characters enclosed in quotes. They are used to handle and manipulate textual data.

Characteristics of Strings

  • Ordered: Characters in a string have a defined order.
  • Immutable: Strings cannot be modified after they are created.
  • Heterogeneous: Strings can include any combination of letters, numbers, and symbols.

Creating Strings

Strings can be created using single quotes, double quotes, or triple quotes for multiline strings.

Example:

# Creating strings with different types of quotes
single_quoted = 'Hello, World!'
double_quoted = "Hello, World!"
multiline_string = """This is a
multiline string"""

Accessing String Characters

Characters in a string are accessed using their index, with the first character having an index of 0. Negative indexing can be used to access characters from the end.

Example:

# Accessing characters in a string
first_char = single_quoted[0]  # Output: 'H'
last_char = single_quoted[-1]  # Output: '!'

Common String Methods

Python provides various methods for string manipulation:

  1. upper(): Converts all characters to uppercase.
  2. lower(): Converts all characters to lowercase.
  3. strip(): Removes leading and trailing whitespace.
  4. replace(old, new): Replaces occurrences of a substring with another substring.
  5. split(separator): Splits the string into a list based on a separator.

Example:

# Using string methods
text = "   hello, world!   "
uppercase_text = text.upper()       # Result: "   HELLO, WORLD!   "
stripped_text = text.strip()        # Result: "hello, world!"
replaced_text = text.replace("world", "Python")  # Result: "   hello, Python!   "
words = text.split(",")             # Result: ['hello', ' world!   ']

List Type

Lists are one of the most versatile and commonly used sequence types in Python. They allow for the storage and manipulation of ordered collections of items.

Characteristics of Lists

  • Ordered: The items in a list have a defined order, which will not change unless explicitly modified.
  • Mutable: The content of a list can be changed after its creation (i.e., items can be added, removed, or modified).
  • Dynamic: Lists can grow or shrink in size as items are added or removed.
  • Heterogeneous: Items in a list can be of different data types (e.g., integers, strings, floats).

Creating Lists

Lists are created by placing comma-separated values inside square brackets.

Example:

# Creating a list of fruits
fruits = ["apple", "banana", "cherry"]

# Creating a mixed list
mixed_list = [1, "Hello", 3.14]

Accessing List Items

List items are accessed using their index, with the first item having an index of 0.

Example:


# Accessing the first item
first_fruit = fruits[0]  # Output: "apple"

# Accessing the last item
last_fruit = fruits[-1]  # Output: "cherry"

Modifying Lists

Lists can be modified by changing the value of specific items, adding new items, or removing existing items.

Example:

# Changing the value of an item
fruits[1] = "blueberry"  # fruits is now ["apple", "blueberry", "cherry"]

# Adding a new item
fruits.append("orange")  # fruits is now ["apple", "blueberry", "cherry", "orange"]

# Removing an item
fruits.remove("blueberry")  # fruits is now ["apple", "cherry", "orange"]

List Methods

Python provides several built-in methods to work with lists:

  1. append(item): Adds an item to the end of the list.
  2. insert(index, item): Inserts an item at a specified index.
  3. remove(item): Removes the first occurrence of an item.
  4. pop(index): Removes and returns the item at the specified index.
  5. sort(): Sorts the list in ascending order.
  6. reverse(): Reverses the order of the list.

Example:

# Using list methods
numbers = [5, 2, 9, 1]

numbers.append(4)     # numbers is now [5, 2, 9, 1, 4]
numbers.sort()        # numbers is now [1, 2, 4, 5, 9]
numbers.reverse()     # numbers is now [9, 5, 4, 2, 1]
first_number = numbers.pop(0)  # first_number is 9, numbers is now [5, 4, 2, 1]

Tuple Type

Tuples are a built-in sequence type in Python that is used to store an ordered collection of items. Unlike lists, tuples are immutable, which means their contents cannot be changed after creation.

Characteristics of Tuples

  • Ordered: Tuples maintain the order of items, which is consistent throughout their lifetime.
  • Immutable: Once a tuple is created, its contents cannot be modified. This includes adding, removing, or changing items.
  • Fixed Size: The size of a tuple is fixed; it cannot grow or shrink after creation.
  • Heterogeneous: Tuples can contain items of different data types, such as integers, strings, and floats.

Creating Tuples

Tuples are created by placing comma-separated values inside parentheses. Single-element tuples require a trailing comma.

Example:

# Creating a tuple with multiple items
coordinates = (10, 20, 30)

# Creating a single-element tuple
single_element_tuple = (5,)

# Creating a tuple with mixed data types
mixed_tuple = (1, "Hello", 3.14)

Accessing Tuple Items

Tuple items are accessed using their index, with the first item having an index of 0. Negative indexing can be used to access items from the end.

Example:

# Accessing the first item
x = coordinates[0]  # Output: 10

# Accessing the last item
z = coordinates[-1]  # Output: 30

Modifying Tuples

Since tuples are immutable, their contents cannot be modified. However, us can create new tuples by combining or slicing existing ones.

Example:

# Combining tuples
new_coordinates = coordinates + (40, 50)  # Result: (10, 20, 30, 40, 50)

# Slicing tuples
sub_tuple = coordinates[1:3]  # Result: (20, 30)

Tuple Methods

Tuples have a limited set of built-in methods compared to lists:

  1. count(item): Returns the number of occurrences of the specified item.
  2. index(item): Returns the index of the first occurrence of the specified item.

Example:

# Using tuple methods
numbers = (1, 2, 3, 1, 2, 1)

# Counting occurrences of an item
count_1 = numbers.count(1)  # Result: 3

# Finding the index of an item
index_2 = numbers.index(2)  # Result: 1

Mapping Types

Mapping types in Python are used to store data in key-value pairs. Unlike sequences, mappings do not maintain an order and are designed for quick lookups of data.

Dictionary (dict)

The primary mapping type in Python is the dict. Dictionaries store data as key-value pairs, where each key must be unique, and keys are used to access their corresponding values.

Characteristics of Dictionaries

  • Unordered: The order of items is not guaranteed and may vary.
  • Mutable: us can add, remove, and change items after creation.
  • Keys: Must be unique and immutable (e.g., strings, numbers, tuples).
  • Values: Can be of any data type and can be duplicated.

Creating Dictionaries

Dictionaries are created using curly braces {} with key-value pairs separated by colons :.

Example:

# Creating a dictionary
student = {
    "name": "Alice",
    "age": 21,
    "major": "Computer Science"
}

Accessing and Modifying Dictionary Items

Items in a dictionary are accessed using their keys. us can also modify, add, or remove items.

Example:

# Accessing a value
name = student["name"]  # Output: "Alice"

# Modifying a value
student["age"] = 22  # Updates the age to 22

# Adding a new key-value pair
student["graduation_year"] = 2024

# Removing a key-value pair
del student["major"]

Dictionary Methods

Python provides several built-in methods to work with dictionaries:

  1. keys(): Returns a view object of all keys.
  2. values(): Returns a view object of all values.
  3. items(): Returns a view object of all key-value pairs.
  4. get(key, default): Returns the value for the specified key, or a default value if the key is not found.
  5. pop(key, default): Removes and returns the value for the specified key, or a default value if the key is not found.

Example:

# Using dictionary methods
keys = student.keys()        # Result: dict_keys(['name', 'age', 'graduation_year'])
values = student.values()    # Result: dict_values(['Alice', 22, 2024])
items = student.items()      # Result: dict_items([('name', 'Alice'), ('age', 22), ('graduation_year', 2024)])
name = student.get("name")  # Result: "Alice"
age = student.pop("age")    # Result: 22

Set Types

Sets are a built-in data type in Python used to store unique, unordered collections of items. They are particularly useful for operations involving membership tests, set operations, and removing duplicates.

Characteristics of Sets

  • Unordered : The items in a set do not have a specific order and may change.
  • Mutable : us can add or remove items from a set after its creation.
  • Unique : Sets do not allow duplicate items; all items must be unique.
  • Unindexed : Sets do not support indexing or slicing.

Creating Sets

Sets are created using curly braces {} with comma-separated values, or using the set() function.

Example:

# Creating a set using curly braces
fruits = {"apple", "banana", "cherry"}

# Creating a set using the set() function
numbers = set([1, 2, 3, 4, 5])

Accessing and Modifying Set Items

While us cannot access individual items by index, us can check for membership and perform operations like adding or removing items.

Example:

# Checking membership
has_apple = "apple" in fruits  # Output: True

# Adding an item
fruits.add("orange")

# Removing an item
fruits.remove("banana")  # Raises KeyError if item is not present

Set Operations Sets support various mathematical set operations, such as union, intersection, and difference.

Example:

# Union of two sets
set1 = {1, 2, 3}
set2 = {3, 4, 5}
union = set1 | set2  # Result: {1, 2, 3, 4, 5}

# Intersection of two sets
intersection = set1 & set2  # Result: {3}

# Difference between two sets
difference = set1 - set2  # Result: {1, 2}

# Symmetric difference (items in either set, but not in both)
symmetric_difference = set1 ^ set2  # Result: {1, 2, 4, 5}

Set Methods

Python provides several built-in methods for set operations:

  1. add(item): Adds an item to the set.
  2. remove(item): Removes an item from the set; raises KeyError if item is not present.
  3. discard(item): Removes an item from the set if present; does not raise an error if item is not found.
  4. pop(): Removes and returns an arbitrary item from the set.
  5. clear(): Removes all items from the set.

Example:

# Using set methods
set1 = {1, 2, 3}

set1.add(4)        # set1 is now {1, 2, 3, 4}
set1.remove(2)     # set1 is now {1, 3, 4}
set1.discard(5)    # No error, set1 remains {1, 3, 4}
item = set1.pop()  # Removes and returns an arbitrary item, e.g., 1
set1.clear()      # set1 is now an empty set {}

## Frozen Sets

Frozen sets are a built-in data type in Python that are similar to sets but are immutable. Once created, a frozen set cannot be modified, making it suitable for use as a key in dictionaries or as elements of other sets.

Characteristics of Frozen Sets

  • Unordered : The items in a frozen set do not have a specific order and may change.
  • Immutable : Unlike regular sets, frozen sets cannot be altered after creation. No items can be added or removed.
  • Unique : Like sets, frozen sets do not allow duplicate items; all items must be unique.
  • Unindexed : Frozen sets do not support indexing or slicing.

Creating Frozen Sets

Frozen sets are created using the frozenset() function, which takes an iterable as an argument.

Example:

# Creating a frozen set
numbers = frozenset([1, 2, 3, 4, 5])

# Creating a frozen set from a set
fruits = frozenset({"apple", "banana", "cherry"})

Accessing and Modifying Frozen Set Items

Frozen sets do not support modification operations such as adding or removing items. However, us can perform membership tests and other set operations.

Example:

# Checking membership
has_apple = "apple" in fruits  # Output: True

# Since frozenset is immutable, us cannot use add() or remove() methods

Set Operations with Frozen Sets

Frozen sets support various mathematical set operations similar to regular sets, such as union, intersection, and difference. These operations return new frozen sets and do not modify the original ones.

Example:

# Union of two frozen sets
set1 = frozenset([1, 2, 3])
set2 = frozenset([3, 4, 5])
union = set1 | set2  # Result: frozenset({1, 2, 3, 4, 5})

# Intersection of two frozen sets
intersection = set1 & set2  # Result: frozenset({3})

# Difference between two frozen sets
difference = set1 - set2  # Result: frozenset({1, 2})

# Symmetric difference (items in either set, but not in both)
symmetric_difference = set1 ^ set2  # Result: frozenset({1, 2, 4, 5})

Frozen Set Methods

Frozen sets have a subset of the methods available to regular sets. The available methods include:

  1. copy() : Returns a shallow copy of the frozen set.
  2. difference(other) : Returns a new frozen set with elements in the original frozen set but not in other.
  3. intersection(other) : Returns a new frozen set with elements common to both frozen sets.
  4. union(other) : Returns a new frozen set with elements from both frozen sets.
  5. symmetric_difference(other) : Returns a new frozen set with elements in either frozen set but not in both.

Example:

# Using frozen set methods
set1 = frozenset([1, 2, 3])
set2 = frozenset([3, 4, 5])

# Getting the difference
difference = set1.difference(set2)  # Result: frozenset({1, 2})

# Getting the intersection
intersection = set1.intersection(set2)  # Result: frozenset({3})

# Getting the union
union = set1.union(set2)  # Result: frozenset({1, 2, 3, 4, 5})

# Getting the symmetric difference
symmetric_difference = set1.symmetric_difference(set2)  # Result: frozenset({1, 2, 4, 5})

Control Structures in Python

Control structures in Python allow us to control the flow of execution in our programs. They help manage decision-making, looping, and the execution of code blocks based on certain conditions. Python provides several key control structures: if statements, for loops, while loops, and control flow statements like break, continue, and pass.

Conditional Statements

Conditional statements are used to execute code based on certain conditions. The primary conditional statement in Python is the if statement, which can be combined with elif and else to handle multiple conditions.

Syntax:

if condition:
    # Code block to execute if condition is True
elif another_condition:
    # Code block to execute if another_condition is True
else:
    # Code block to execute if none of the above conditions are True

Example: Program to classify a person based on his/her age.

age = 20

if age < 18:
    print("us are a minor.")
elif age < 65:
    print("us are an adult.")
else:
    print("us are a senior citizen.")

Looping Statements

Looping statements are used to repeat a block of code multiple times. Python supports for loops and while loops.

For Loop

The for loop iterates over a sequence (like a list, tuple, or string) and executes a block of code for each item in the sequence.

Syntax:

for item in sequence:
    # Code block to execute for each item

Example: Program to print names of fruits saved in a list.

# Iterating over a list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

While Loop

The while loop repeatedly executes a block of code as long as a specified condition is True.

Syntax:

while condition:
    # Code block to execute while condition is True

Example: Print all counting numbers less than 5.

# Counting from 0 to 4
count = 0
while count < 5:
    print(count)
    count += 1

Control Flow Statements

Control flow statements alter the flow of execution within loops and conditionals.

Break Statement

The break statement exits the current loop, regardless of the loop’s condition.

Example: Program to exit from the printing of whole numbers less than 10, while trigger 5.

for i in range(10):
    if i == 5:
        break
    print(i)
# Output: 0 1 2 3 4

Continue Statement

The continue statement skips the rest of the code inside the current loop iteration and proceeds to the next iteration.

Example: Program to print all the whole numbers in the range 5 except 2.

for i in range(5):
    if i == 2:
        continue
    print(i) 
# Output: 0 1 3 4

Pass Statement

The pass statement is a placeholder that does nothing and is used when a statement is syntactically required but no action is needed.

Example: Program to print all the whole numbers in the range 5 except 3.

for i in range(5):
    if i == 3:
        pass  # Placeholder for future code
    else:
        print(i)
# Output: 0 1 2 4

Cautions When Using Control Flow Structures

Control flow structures are essential in Python programming for directing the flow of execution. However, improper use of these structures can lead to errors, inefficiencies, and unintended behaviors. Here are some cautions to keep in mind:

Infinite Loops

  • Issue: A while loop with a condition that never becomes False can lead to an infinite loop, which will cause the program to hang or become unresponsive.
  • Caution: Always ensure that the condition in a while loop will eventually become False, and include logic within the loop to modify the condition.

Example:

# Infinite loop example
count = 0
while count < 5:
    print(count)
    # Missing count increment, causing an infinite loop

Functions in Python Programming

Functions are a fundamental concept in Python programming that enable code reuse, modularity, and organization. They allow us to encapsulate a block of code that performs a specific task, which can be executed whenever needed. Functions are essential for writing clean, maintainable, and scalable code, making them a cornerstone of effective programming practices.

What is a Function?

A function is a named block of code designed to perform a specific task. Functions can take inputs, called parameters or arguments, and can return outputs, which are the results of the computation or task performed by the function. By defining functions, we can write code once and reuse it multiple times, which enhances both efficiency and readability.

Defining a Function

In Python, functions are defined using the def keyword, followed by the function name, parentheses containing any parameters, and a colon. The function body, which contains the code to be executed, is indented below the function definition.

Syntax:

def function_name(parameters):
    # Code block
    return result

Example:

def greet(name):
    """
    Returns a greeting message for the given name.
    """
    return f"Hello, {name}!"

Relevance of functions in Programming

  1. Code Reusability : Functions allow us to define a piece of code once and reuse it in multiple places. This reduces redundancy and helps maintain consistency across our codebase.

  2. Modularity : Functions break down complex problems into smaller, manageable pieces. Each function can be focused on a specific task, making it easier to understand and maintain the code.

  3. Abstraction : Functions enable us to abstract away the implementation details. We can use a function without needing to know its internal workings, which simplifies the code we write and enhances readability.

  4. Testing and Debugging : Functions allow us to test individual components of our code separately. This isolation helps in identifying and fixing bugs more efficiently.

  5. Library Creation : Functions are the building blocks of libraries and modules. By organizing related functions into libraries, we can create reusable components that can be shared and utilized across different projects.

Example: Creating a Simple Library

Stage 1: Define Functions in a Module

# my_library.py

def add(a, b):
    """
    Returns the sum of two numbers.
    """
    return a + b

def multiply(a, b):
    """
    Returns the product of two numbers.
    """
    return a * b

Stage 2: Use the Library in Another Program

# main.py

import my_library

result_sum = my_library.add(5, 3)
result_product = my_library.multiply(5, 3)

print(f"Sum: {result_sum}")
print(f"Product: {result_product}")