Friday, May 15, 2026
Cohort 3 | Project CloudIgnite Topics: Python Functions, Exception Handling, Conditionals, Loops, Caesar Cipher, SCP Upload to EC2 Duration: ~3 hours
Key Takeaways
- Functions:
def name(params): ... return value; four types (with/without args and return) - Exception handling:
try/exceptprevents crashes; wrap suspected lines; give user-friendly feedback - Caesar cipher: encrypt by shifting characters; decrypt by reversing shift; modulo
%for wrap-around random.randint(1, 100)for random numbers; binary search = always find answer in ~6 guesses for 1–50- SCP:
scp -i key.pem file.py ec2-user@ip:/path/— upload files to EC2 over SSH - Security Group issue encountered: port 22 blocked; fixed by editing inbound rules to allow SSH from anywhere
Table of Contents
- Python Functions
- Exception Handling
- Conditionals (Lab 114)
- Loops & Random (Lab 115)
- Caesar Cipher Implementation
- Uploading Files to EC2 via SCP
1. Python Functions
Why Use Functions?
- Avoid repeating the same block of code
- Improve code reusability and readability
- Organise code into modular units
Types of Functions
| Type | Arguments | Return Value |
|---|---|---|
| No args, no return | ✗ | ✗ |
| Args, no return | ✓ | ✗ |
| No args, with return | ✗ | ✓ |
| Args, with return | ✓ | ✓ |
Built-in Functions (Examples)
print(), input(), int(), len(), range(), sum(), exit()
Defining a Custom Function
def function_name(parameters):
# code block
return value
Example – Summation:
def summation(nums):
x = 0
for num in nums:
x += num
return x
nums3 = [1, 2, 3, 4]
result = summation(nums3)
Key Rules
- Use
defkeyword to define a function - Function names are not reserved but avoid naming conflicts with built-ins
- A function always returns a single value (can be a composite type)
returnis the exit point — code after a reachedreturnwon't execute- Order matters in Python: a function must be defined before it is called
- Arguments are the inputs to a function; return value is the output
Using Built-in sum()
total = sum(nums1) # default start = 0
total = sum(nums2, start=total) # pass previous total as start value
total = sum(nums1 + nums2 + nums3) # combine lists
2. Exception Handling
What is an Exception?
A runtime error — not a syntax error — caused by unexpected behaviour (e.g. dividing by zero, missing file, failed API call).
try / except Block
def div(a, b):
try:
c = a / b
except:
return "Value of B cannot be zero"
return c
print(div(10, 0)) # "Value of B cannot be zero"
print(div(10, 2)) # 5.0
Common Scenarios Requiring Exception Handling
- Division by zero
- Reading a file that doesn't exist
- API call failing due to network issues or server error (non-200 response)
- Empty string passed where a number is expected
Key Points
- Identify suspected lines and wrap them in
try/except - Always give user-friendly feedback instead of crashing the program
throw(raise) alone doesn't solve the problem — you must also catch it- Advanced topics (covered later): custom exceptions, global exception handlers
3. Conditionals (Lab 114)
if / elif / else
user_reply = input("Would you like to buy: stamps, envelope, or copy? ").lower()
if user_reply == "stamps":
print("We have many stamp designs to choose from.")
elif user_reply == "envelope":
print("We have many envelope sizes to choose from.")
elif user_reply == "copy":
copies = int(input("How many copies do you need? "))
print(f"Here are {copies} copies.")
else:
print("Thank you. Please come again.")
Case-Insensitive Comparison
Use .lower() to normalise input before comparing:
if user_reply.lower() == "yes":
Recursive Input Validation
def question():
user_reply = input("Please enter yes or no: ")
if user_reply.lower() == "yes":
print("User says Yes.")
elif user_reply.lower() == "no":
print("User says No.")
else:
print("Invalid input. Try again.")
question() # recursive call
question()
4. Loops & Random (Lab 115)
Importing a Module
import random
Generating a Random Integer
num = random.randint(1, 100) # random number between 1 and 100 (inclusive)
for Loop with range()
for x in range(0, 11): # 0 to 10
print(x)
for x in range(0, 11, 2): # 0, 2, 4, 6, 8, 10 (step of 2)
print(x)
for x in range(10, -1, -1): # 10 down to 0 (descending)
print(x)
while Loop — Number Guessing Game
import random
num = random.randint(1, 50)
is_guess_correct = False
while not is_guess_correct:
guess = input("Guess a number between 1 and 50: ")
if guess == "":
continue
guess = int(guess)
if guess == num:
print(f"{guess} is correct!")
is_guess_correct = True
elif guess < num:
print("Too low!")
else:
print("Too high!")
Binary Search Strategy (Optimal Guessing)
With a range of 1–50, you can always find the answer in ~6 guesses by halving the search space each time — this is the binary search algorithm.
Each guess eliminates half the remaining possibilities.
continue vs break
continue— skip the rest of the current iteration, go to nextbreak— exit the loop entirely- Alternatively, update a Boolean flag to exit a
whileloop cleanly
5. Caesar Cipher Implementation
A simple encryption technique that shifts each character in the alphabet by a fixed key.
Helper Functions
# Double a character
def get_double_alphabet(alphabet):
return alphabet + alphabet
# Get message from user
def get_message():
string_to_encrypt = input("Please enter a message to encrypt: ")
return string_to_encrypt
# Get cipher key from user
def get_cipher_key():
shift_amount = int(input("Enter a key: "))
return shift_amount
Encrypt Function
def encrypt_message(message, key, alphabet):
encrypted_message = ""
for current_char in message.upper():
position = alphabet.find(current_char)
new_position = position + key
encrypted_message += alphabet[new_position]
return encrypted_message
Decrypt Function
def decrypt_message(encrypted_message, key, alphabet):
message = ""
for current_char in encrypted_message:
position = alphabet.find(current_char)
actual_position = position - key
message += alphabet[actual_position]
return message
Usage
alphabet = ['A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
message = get_message()
key = get_cipher_key()
encrypted = encrypt_message(message, key, alphabet)
decrypted = decrypt_message(encrypted, key, alphabet)
print(f"Encrypted: {encrypted}")
print(f"Decrypted: {decrypted}")
⚠️ Known limitation: If the shifted position exceeds the alphabet length (index > 25), the code will crash. Modulo (
%) can be used to wrap around — to be covered in the next session.
6. Uploading Files to EC2 via SCP ☁️
This section is directly relevant to AWS Cloud Practitioner knowledge areas (see note below).
SCP Command (Secure Copy Protocol)
Used to upload local files to a remote EC2 instance over SSH.
scp -i labsuser.pem lab114.py ec2-user@<EC2-PUBLIC-IP>:/path/to/destination/
Steps
- Download the
.pemkey file from the AWS lab - Change file permissions (Linux/macOS):
chmod 400 labsuser.pem - Find your EC2 public IP from the AWS console
- Get the destination path on EC2 using
pwd - Run the
scpcommand from your local terminal
Why It Didn't Work (In-Lab Issue)
- Port 22 (SSH) was blocked by the EC2 Security Group rules
- The Security Group only allowed SSH from a specific source IP, not from anywhere
- Fix: Edit the Security Group inbound rules → add SSH rule with source
0.0.0.0/0(Anywhere) - Instructor did not have IAM permissions to edit the Security Group — highlighting the principle of least privilege
Check Current Linux User
whoami
AWS re/Start → CLF-C02 Relevance
The following content from today's session connects to the AWS Certified Cloud Practitioner (CLF-C02) exam objectives:
| Topic Covered in Class | CLF-C02 Domain |
|---|---|
| EC2 Instances – launching, connecting, identifying running instances | Domain 3: Cloud Technology & Services |
| Security Groups – inbound rules, port 22 (SSH), source IP restrictions | Domain 2: Security & Compliance |
| IAM Permissions – instructor lacked permission to edit security group (least privilege principle) | Domain 2: Security & Compliance |
SCP / SSH – connecting to EC2 using a .pem key pair | Domain 3: Cloud Technology & Services |
| AWS Cloud9 – cloud-based IDE running on EC2 | Domain 3: Cloud Technology & Services |
💡 Exam Tip: Security Groups act as a virtual firewall for EC2 instances. They are stateful — if you allow inbound traffic on a port, the return traffic is automatically allowed. Know the difference between Security Groups and Network ACLs.
💡 Exam Tip: IAM (Identity and Access Management) enforces the principle of least privilege — users and roles should only have the permissions they need. The instructor's inability to edit the security group is a real-world example of this.
Action Items / Reminders
- Practice Python syntax on CodeWars problems (provided by instructor)
- Create a GitHub account before Monday
- Tomorrow (May 16): 2 PM – 6 PM — solve Python problems together
- Monday: Cover insulin calculation lab (skipped today) + GitHub walkthrough
- Handle Caesar cipher wrap-around edge case using modulo
%(next session)
May 15, 2026