AWS Lambda in plain English:
Think of Lambda as running code without managing a server.
Normally, to run an application, you need to:
→ Launch a server
→ Install software
→ Configure security
→ Monitor performance
→ Handle scaling
With Lambda, you simply upload your code.
AWS runs it whenever something happens.
That “something” is called an event.
For example:
• A file is uploaded to S3
• An API receives a request
• A message enters an SQS queue
• A scheduled time is reached
• A database record changes
The basic Lambda flow:
Event occurs
→ Lambda function starts
→ Code runs
→ Result is returned
→ Function stops
You do not pay for a server sitting idle.
You pay mainly when your code is actually running.
Important Lambda concepts:
Function
The code you want AWS to execute.
Trigger
The AWS service or event that starts the function.
Runtime
The programming environment used to run your code.
Examples:
→ Python
→ Node.js
→ Java
→ .NET
Execution role
The permissions your function needs.
For example, a Lambda function may need permission to:
→ Read an S3 object
→ Write to DynamoDB
→ Send an SNS notification
Environment variables
Configuration values stored outside your code.
Examples:
→ Database names
→ API endpoints
→ Application settings
Common Lambda use cases:
• Serverless APIs
• File processing
• Image resizing
• Email notifications
• Scheduled automation
• Data transformation
• Backend workflows
Example:
A user uploads an image to S3.
S3 triggers Lambda.
Lambda resizes the image.
The resized version is saved in another S3 bucket.
No server needs to run continuously.
One important detail:
Lambda is best for event-driven, short-running tasks.
It is not always the best choice for:
→ Long-running applications
→ Workloads requiring complete server control
→ Applications with constantly running processes
In simple terms:
EC2 gives you a server to manage.
Lambda runs your code when needed.
Save this if you are learning AWS.
🛡️ What are Guardrails?
Guardrails are rules and checks that an AI application applies before, during, or after the LLM generates a response.
They help ensure the AI behaves in a way that's safe, reliable, and aligned with the application's requirements.
Think of them as the application's control layer, not the model itself.
Where can guardrails be applied? ✨
Guardrails can exist throughout the AI workflow.
Before the LLM :
→ Validate user input
→ Detect prompt injection attempts
→ Remove sensitive information
→ Check permissions
During the LLM interaction :
→ Restrict which tools the model can access
→ Limit function arguments
→ Enforce structured outputs
→ Control which context is provided
After the LLM responds :
→ Validate the generated output
→ Check JSON format
→ Filter harmful or sensitive content
→ Ask for human approval before taking important actions
Why are guardrails important? ✨
Without guardrails, an LLM might :
→ Call the wrong tool
→ Generate invalid JSON
→ Leak sensitive information
→ Execute actions the user isn't allowed to perform
→ Produce responses that don't follow business rules
The application, not the model, is responsible for preventing these situations.
🏗️ Real-world examples
Different AI applications use different types of guardrails.
→ Claude Code : Confirmation before executing terminal commands.
→ Cursor : User approval before applying code changes.
→ ChatGPT : Tool permissions and structured output validation.
→ GitHub Copilot : Workspace and extension permission boundaries.
→ Bug0 : Validation of generated testing workflows and artifacts before presenting results.
Guardrails aren't just about AI safety.
They're also about enforcing business rules, validating outputs, controlling tool usage, and making AI applications predictable in production.
They make the application more reliable.
Just like validation, authentication, and authorization are essential in traditional software, Guardrails are becoming an essential part of modern AI applications.
____________________
Thank you for reading 🙌
Python Functions explained from beginner to practical use:
A function is a reusable block of code designed to perform one specific task.
Instead of writing the same logic repeatedly, you write it once and call it whenever needed.
① Creating a Function
Use the def keyword to define a function.
def greet():
print("Hello, Python!")
This creates the function, but it does not run it yet.
To execute it:
greet()
Output:
Hello, Python!
② Why Functions Matter
Without functions:
print("Welcome, Alex")
print("Welcome, Sam")
print("Welcome, John")
With a function:
def welcome(name):
print(f"Welcome, {name}")
welcome("Alex")
welcome("Sam")
welcome("John")
The second version is easier to reuse, update and maintain.
③ Parameters
Parameters are variables listed inside the function definition.
def greet(name):
print(f"Hello, {name}")
Here, name is a parameter.
It acts as a placeholder for the value the function will receive.
④ Arguments
Arguments are the actual values passed to a function.
greet("Alex")
Here, "Alex" is the argument.
Parameter:
name
Argument:
"Alex"
⑤ Multiple Parameters
A function can accept more than one value.
def introduce(name, role):
print(f"{name} works as a {role}")
introduce("Alex", "Cloud Engineer")
Output:
Alex works as a Cloud Engineer
The arguments are matched according to their position.
⑥ Returning Values
The return statement sends a result back to the caller.
def add(a, b):
return a + b
result = add(10, 5)
print(result)
Output:
15
Use return when the result needs to be stored, reused or passed somewhere else.
⑦ Print vs Return
These are not the same.
def add(a, b):
print(a + b)
This only displays the result.
def add(a, b):
return a + b
This gives the result back to the program.
You can then reuse it:
total = add(10, 5)
final_price = total * 2
A common beginner mistake is using print() when return is needed.
⑧ Default Parameters
You can provide a default value for a parameter.
def greet(name="Guest"):
print(f"Hello, {name}")
Calling it without an argument:
greet()
Output:
Hello, Guest
Calling it with an argument:
greet("Alex")
Output:
Hello, Alex
Default values make parameters optional.
⑨ Keyword Arguments
You can pass arguments using parameter names.
def create_user(name, role):
print(name, role)
create_user(
role="Developer",
name="Alex"
)
Keyword arguments make function calls easier to understand.
They also allow you to change the argument order.
⑩ Positional Arguments
Positional arguments are matched according to their position.
def subtract(a, b):
return a - b
print(subtract(10, 3))
Output:
7
Changing the order changes the result:
print(subtract(3, 10))
Output:
-7
⑪ Variable-Length Arguments
Sometimes you do not know how many arguments a function will receive.
Use *args:
def calculate_total(*numbers):
return sum(numbers)
print(calculate_total(10, 20, 30, 40))
Output:
100
*args collects positional arguments into a tuple.
⑫ Keyword Variable-Length Arguments
Use **kwargs when you want to accept multiple keyword arguments.
def show_profile(**details):
for key, value in details.items():
print(key, value)
show_profile(
name="Alex",
role="Developer",
experience=2
)
**kwargs collects keyword arguments into a dictionary.
⑬ Local Variables
Variables created inside a function are usually local.
def calculate():
result = 10 + 5
print(result)
The result variable only exists inside the function.
Trying to access it outside the function causes an error.
print(result)
⑭ Global Variables
Variables created outside functions are global.
discount = 10
def show_discount():
print(discount)
show_discount()
The function can read the global variable.
However, relying too heavily on global variables can make programs difficult to maintain.
Passing values through parameters is usually cleaner.
⑮ Functions Calling Functions
One function can call another function.
def calculate_tax(price):
return price * 0.18
def calculate_total(price):
tax = calculate_tax(price)
return price + tax
print(calculate_total(1000))
Output:
1180.0
This allows you to divide large problems into smaller tasks.
⑯ Type Hints
Type hints show what kind of values a function expects.
def add(a: int, b: int) -> int:
return a + b
This tells developers:
a should be an integer
b should be an integer
the function should return an integer
Python does not strictly enforce these hints, but they improve readability.
⑰ Docstrings
A docstring explains what a function does.
def calculate_area(length, width):
"""Calculate and return the area of a rectangle."""
return length * width
Docstrings are useful when working on larger projects or collaborating with others.
⑱ Lambda Functions
A lambda is a small anonymous function.
Normal function:
def square(number):
return number ** 2
Lambda version:
square = lambda number: number ** 2
Use lambdas for short and simple operations.
Avoid them when the logic becomes difficult to understand.
⑲ Pure Functions
A pure function depends only on its inputs and returns a predictable output.
def calculate_discount(price, discount):
return price - price * discount
The same inputs always produce the same result.
Pure functions are easier to test and debug.
⑳ Real-World Example
def calculate_order_total(
price,
quantity,
discount=0
):
subtotal = price * quantity
discount_amount = subtotal * discount
return subtotal - discount_amount
total = calculate_order_total(
price=500,
quantity=3,
discount=0.10
)
print(total)
Output:
1350.0
This function combines:
Parameters
Keyword arguments
Default values
Calculations
Return values
Functions are not just pieces of syntax.
They help you turn a large problem into smaller, reusable and testable parts.
A strong Python developer does not write more code.
They organize code better.
AWS for getting hired
• EC2 → Proof you can run apps
• S3 → Proof you understand storage
• IAM → Proof you know access control
• VPC → Proof you understand networking
• RDS → Proof you can work with databases
• Lambda → Proof you can automate tasks
• CloudFront → Proof you know content delivery
• Route 53 → Proof you understand DNS
• CloudWatch → Proof you can monitor systems
• Auto Scaling → Proof you can handle traffic
• Load Balancer → Proof you understand scalability
• DynamoDB → Proof you know NoSQL basics
Forget memorizing 200+ services.
A strong AWS project speaks louder.
13 database types explained in one sentence:
1) 𝗥𝗲𝗹𝗮𝘁𝗶𝗼𝗻𝗮𝗹
↳ Stores structured data in tables with predefined schemas & SQL queries.
2) 𝗞𝗲𝘆-𝗩𝗮𝗹𝘂𝗲
↳ Stores simple key-value pairs for ultra-fast lookups & caching.
3) 𝗖𝗼𝗹𝘂𝗺𝗻𝗮𝗿
↳ Stores data by columns instead of rows to optimize analytical queries.
4) 𝗪𝗶𝗱𝗲-𝗖𝗼𝗹𝘂𝗺𝗻
↳ Stores data in flexible column families for large-scale distributed workloads.
5) 𝗗𝗼𝗰𝘂𝗺𝗲𝗻𝘁
↳ Stores data as JSON-like documents with flexible, nested structures.
6) 𝗩𝗲𝗰𝘁𝗼𝗿
↳ Stores embeddings to enable similarity search & AI-powered retrieval.
7) 𝗧𝗶𝗺𝗲-𝗦𝗲𝗿𝗶𝗲𝘀
↳ Stores time-stamped data for metrics, logs, & event tracking.
8) 𝗜𝗺𝗺𝘂𝘁𝗮𝗯𝗹𝗲 𝗟𝗲𝗱𝗴𝗲𝗿
↳ Stores tamper-proof records where data cannot be modified or deleted.
9) 𝗚𝗿𝗮𝗽𝗵
↳ Stores relationships between entities to query connected data efficiently.
10) 𝗚𝗲𝗼𝘀𝗽𝗮𝘁𝗶𝗮𝗹
↳ Stores location-based data for geographic queries and mapping.
11) 𝗜𝗻-𝗠𝗲𝗺𝗼𝗿𝘆
↳ Stores data in RAM for extremely fast, low-latency access.
12) 𝗕𝗹𝗼𝗯
↳ Stores large unstructured data like images, videos, and files.
13) 𝗧𝗲𝘅𝘁-𝗦𝗲𝗮𝗿𝗰𝗵
↳ Indexes and retrieves text efficiently using full-text search.
Remember, most systems don’t use just one database, they combine multiple types for different workloads.
Which database type is your favorite lately?
➕ Follow me ( @NikkiSiapno ) to improve at system design.
Databricks engineers can make $180k per year!
Thats why I’m releasing a free Databricks boot camp on August 3rd!
We’ll be covering all the essentials needed to be a great AI data engineer:
- Day 1: Lakebase and production database systems
- Day 2: Context engineering and vector databases
- Day 3: AI agents on Agent Bricks
Join the boot camp for free here: https://t.co/y5SbRHdlP5