Course Content
Module 1 – Getting Started with Python
introduced the fundamentals of Python, giving beginners a clear understanding of how the language works and how to start writing simple programs. Python was highlighted as a beginner-friendly language with simple syntax, making it easy to read and write code.
0/7
Module 2 – Introduction to Python Programming
In this Introduction to Python module, learners explore Python’s clear, readable syntax and powerful features. Beginning with installation and a simple “Hello, World!” script, you will progress through variables, control flow and functions using step-by-step examples. By the end, you will be equipped to write your own Python programmes, automate routine tasks and tap into an extensive library ecosystem for real-world projects.
0/7
Basic Command for Command prompt, PowerShell, Zsh(macOS)
0/1
Module 3 – Variables, Data Types and Basic Operations
In the Variables, Data Types and Basic Operations in Python module, learners explore how to store and manage data using variables, master fundamental types such as integers, floats, strings and booleans, and perform arithmetic, comparison and logical operations step by step. Clear explanations, real world examples and hands on exercises guide you through writing and debugging code. By the end of this module, you will be ready to build dynamic Python programs and automate everyday tasks.
0/6
Module 4 – Control Flow – Conditions and Loops
Control flow structures determine the order in which your program’s code executes. With conditional statements, you can make decisions and execute certain code blocks only when specific conditions are met. Loops allow you to repeat actions efficiently without writing redundant code. In this module, we will explore fundamental control flow concepts in Python in a step-by-step manner, similar to Microsoft’s learning curriculum. By the end, you’ll understand how to use if, elif, and else statements (including nested conditions) for decision-making, how truthy and falsy values work in Boolean logic, how to construct for loops (using range() and iterating over collections), how to use while loops along with loop control statements (break and continue), and how to leverage list comprehensions and generator expressions for concise looping. Finally, we’ll apply these concepts in a practical exercise to build an interactive decision-making system. Each section below includes explanations, code examples, and mini-exercises to reinforce the concepts, all formatted for clarity and easy follow-along.
0/8
Day 1 Summary
We covered Modules 1, 2 & Module 3 (Lesson 1 & 2)
0/1
Module 5 – Functions and Code Organisation
Imagine you need to clean up a messy data set or send a personalised email to each customer. Instead of writing the same steps over and over, you can create a function and call it whenever you need. In this lesson on Functions and Code Organisation, you will learn how to define functions, pass and return information, document your work and group related code into modules for easy reuse and maintenance.
0/10
Day 2 Summary
Summary for Day 21 Aug 2025
0/1
Day 3 Summary
Summary of Day 28 Aug 2025
0/1
Module 7 – Working with Files and Folders
In this lesson, we will learn how to manipulate files and directories using Python. We’ll explore common file operations using the os module, and see how the pathlib module provides an object-oriented way to handle file paths. We’ll also use the glob module for pattern-based file searches and learn file I/O operations for text, CSV, and binary files. Additionally, we’ll introduce the calendar and time modules to work with dates and timestamps. Finally, an interactive lab will tie everything together by automating a folder backup and cleanup task. Follow the step-by-step sections below for each subtopic, try out the code examples, and explore the guided lab at the end.
0/9
Module 8 – Error Handling and Debugging Techniques
In this lesson, we will learn how to handle errors in Python programs and how to debug code effectively. Errors are inevitable, but knowing how to manage them ensures our programs don't crash unexpectedly. We will cover the difference between syntax errors and exceptions, how to use try, except, else, and finally blocks to catch and handle exceptions, and how to raise your own exceptions (including creating custom exception classes). We’ll also explore debugging strategies: using simple print statements or the logging module to trace your program’s execution, and using Python’s interactive debugger pdb to step through code. By following best practices for error handling and debugging, you can write resilient, maintainable code. Throughout this lesson, try the examples and exercises to practice these techniques.
0/9
Day 4 Summary
0/1
Module 9 – Automating Excel and PDFs with Python
In this lesson, you will learn how to automate common communication and reporting tasks using Python. We will cover sending notifications via email, messaging platforms, and SMS, as well as manipulating Excel spreadsheets and PDF files programmatically. Each section below includes step-by-step explanations, code examples, and interactive exercises to reinforce your understanding. By the end of this lesson, you’ll be able to send emails with attachments, integrate with Slack/Microsoft Teams, send SMS alerts, and automate Excel/PDF workflows.
0/9
Day 5 Summary
0/1
Mini Project: Build your own Automation Tool
The project incorporates two common automation tasks – Contact Management and Student Tasks Tracking
0/2
Day 6 Summary
0/1
Introduction to Python Programming (Copy 1)

Function Arguments: Positional, Keyword, Default, and Variable-Length

When calling functions, you can pass input values known as arguments to the function’s parameters. Python functions support several ways to pass arguments:

Positional Arguments: These are the most common way to pass values to parameters. You provide the arguments in the same order as the function’s parameter list. Each argument is assigned to the corresponding parameter by position. For example, in greet("Alice", 21), "Alice" is assigned to the first parametername, and 21 the second parameter age. The order matters with positional arguments. If a function has multiple parameters without default values, you must pass arguments for each, in the correct sequence.

Keyword Arguments: Python also allows you to specify arguments by the parameter name, using the form param=value when calling the function. In this case, the order of arguments doesn’t matter, because each is matched by name. For instance, the The greet function defined earlier could be called as greet(age=21, name="Alice") and it would have the same effect as before, explicitly assigning name="Alice" and age=21. Keyword arguments must follow any positional arguments in a function call. This means you can’t provide a positional argument after you’ve started providing keywords. All keywords used must correspond to parameters in the function definition, and no parameter should receive a value more than once. For example, calling greet("Alice", name="Bob") would produce an error because the name parameter is given a value twice (once positionally as "Alice" and once as "Bob").

Default Arguments: A function can specify default values for certain parameters. These parameters become optional — the caller can omit them and the default will be used. You define a default by using the syntax param=value in the function definition. For example:

def power(base, exponent=2):
    return base ** exponent

Here, exponent has a default value of 2. You can call power(5) With just one argument, and it will assume the exponent 2 (returning 25); or you can override the default by calling power(5, 3) to get 125. Default values are evaluated at function definition time, not at call time. This means if you use a mutable object (like a list or dict) as a default, that same object is reused across calls, which can lead to surprising behaviour. For instance, using a list as a default parameter will accumulate changes between calls. It’s generally safer to use immutable types or None as defaults and handle mutable initialisation inside the function. Important to note: if a function has some parameters with defaults and some without, the ones without a default (required params) must come first in the definition. When calling, you can choose to omit some arguments if their parameters have defaults, but you cannot skip a required parameter.

Variable-Length Arguments: Sometimes you want a function to accept an arbitrary number of arguments. Python provides special syntax for this: use * to pack positional variable arguments and ** to pack keyword variable arguments. In the function definition, *args will collect any extra positional arguments passed by the caller into a tuple named args, and **kwargs will collect any extra keyword arguments into a dictionary named kwargs. For example:

def example(*args, **kwargs):
    print("Positional arguments (tuple):", args)
    print("Keyword arguments (dict):", kwargs)

example(10, 20, 30, color="blue", size="M")

Output:

Positional arguments (tuple): (10, 20, 30)
Keyword arguments (dict): {'color': 'blue', 'size': 'M'}

In this call, 10, 20, 30 were packed into the args tuple, and the named arguments were packed into the kwargs dictionary. Inside the function, you can iterate over args or kwargs to handle an arbitrary number of inputs. The usage of *args and **kwargs is common for functions that need to accept flexible arguments. Python’s standard library uses this in many places. For instance, a famous illustration is:

def cheeseshop(kind, *arguments, **keywords):
    print("-- Do you have any", kind, "?")
    print("-- I'm sorry, we're all out of", kind)
    for arg in arguments:
        print(arg)
    print("-" * 40)
    for kw in keywords:
        print(kw, ":", keywords[kw])

# Calling the function with various extra arguments:
cheeseshop("Limburger", "It's very runny, sir.", "It's really very, VERY runny, sir.",
           shopkeeper="Michael Palin", client="John Cleese", sketch="Cheese Shop Sketch")

In this call, "Limburger" is mapped to the first parameter kind, two extra string arguments are collected in arguments, and three keyword arguments are collected in keywords. The function prints a dialog, then iterates through the arguments tuple and keywords dict to print them. The output (abridged) would be:

-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch

As seen above, the variable-length parameters allow the function to handle any number of extra arguments gracefully. Note that if you use *args and **kwargs in the function signature, they should come after any regular parameters (and *args must come before **kwargs). Also, Python allows combining regular, default, * and ** parameters in advanced ways (including keyword-only or positional-only parameters using special markers), but those are more advanced features beyond our current scope.

Summary: With these argument passing techniques, you have flexibility in how you call functions. Positional arguments are simple but fixed-order; keyword arguments add clarity and can skip optional parameters; default arguments provide fallback values; and *args/**kwargs Let you design functions that accept a variable number of inputs. Always ensure that the way you call a function matches its definition. If you mix argument types, remember the rule that positional arguments come first, followed by keyword arguments.