Sunday, August 23, 2026

Week 14 Notes


# 
# Python Problem Solver
# Week 14 Example 1: Email Address Validator
#
def validate_email():
    # Step 1: Input a string
    email = input("Enter an email address: ")
    # Step 2: Scan for "@" signs and count them
    at_count = email.count('@')
    if at_count != 1:
        print("Invalid: email must contain exactly one '@' sign.")
        return
    at_pos = email.index('@')
    # Step 3: Scan for "." before and after the "@"
    #   The rules require at least one "." AFTER the "@".
    dot_after = '.' in email[at_pos + 1:]
    if not dot_after:
        print("Invalid: email must contain a '.' after the '@' sign.")
        return
    # Step 4: Scan for invalid characters (spaces and "#")
    #if " " in email or "#" in email:
    for ch in email:
        if ch == ' ' or ch == '#':
            print("Invalid: email cannot contain spaces or '#' signs.")
            return
    # Step 5: Check "@" position and its relative position with "."
    #   - "@" cannot be first
    #   - at least 1 character between "@" and the next "."
    if at_pos == 0:
        print("Invalid: '@' cannot be in the first position.")
        return
    next_dot = email.index('.', at_pos + 1)   # first "." after the "@"
    if next_dot - at_pos < 2:                 # e.g. "a@.com" -> nothing between
        print("Invalid: there must be at least 1 character between '@' and '.'.")
        return
    # Step 6: Check "." position (cannot end with ".")
    if email.endswith('.'):
        print("Invalid: email cannot end with a '.' sign.")
        return
    # Step 7: Confirm valid
    print("Valid email address.")

validate_email()



# 
# Python Problem Solver
# Week 14 Example 2: Sieve of Eratosthenes
#
def sieve(n):
   # Create a boolean list to track the prime status of all numbers pup to n
   numbers = [True] * (n + 1)
   # 0 and 1 are not prime numbers  
   numbers[0] = False
   numbers[1] = False
   
   # Sieve of Eratosthenes algorithm
   for i in range(2,n//2 + 1):
      if numbers[i]:
         # Mark all multiples of i as non-prime
         for j in range(i*2, n + 1, i):
            numbers[j] = False
   # Combine all prime numbers in a list
   primes = []
   for i in range(2, n + 1):
      if numbers[i]:
         primes.append(i)
   
   return primes
# Main program starts here
n = 100
primes = sieve(n)
print("Prime numbers up to " + str(n) + ":")
for prime in primes:
   print(prime, end=' ')


Saturday, August 15, 2026

Week 13 Assignments

Week 13 Notes


# 
# Python Problem Solver
# Week 13 Example 1: Art Class (2021 AIO P2)
#
N = int(input())
minx, maxx, miny, maxy = 0, 10001, 0, 10001
for i in range(N):
    x, y = map(int, input().strip().split())
    maxx = min(maxx, x)
    minx = max(minx, x)
    maxy = min(maxy, y)
    miny = max(miny, y)
print((maxx - minx) * (maxy - miny))

Saturday, August 8, 2026

Week 12 Assignments


Week 12 Notes


# 
# Python Problem Solver
# Week 12 Example 1: Text Flag 
#
from colorama import init, Fore, Back, Style
brightness = Style.NORMAL
s = "      "
for _ in range(5):
    color = Fore.BLACK + Back.BLUE
    print(f"{brightness}{color}{s}{Style.RESET_ALL}", end = "")
    color = Fore.BLACK + Back.WHITE
    print(f"{brightness}{color}{s}{Style.RESET_ALL}", end = "")
    color = Fore.BLACK + Back.RED
    print(f"{brightness}{color}{s}{Style.RESET_ALL}")


# 
# Python Problem Solver
# Week 12 Example 4: Circular Maze
#
import turtle
myPen = turtle.Turtle()
#myPen.speed(100)
screen = turtle.Screen()
screen.setup(800, 600)
screen.bgpic("images/circular-maze.png")
myPen.pensize(3)
myPen.color("#cc0088")
myPen.penup()
myPen.goto(-190,20)
myPen.pendown()
myPen.setheading(0)
def drawArc(radius,startingAngle,angle):
   myPen.setheading(startingAngle+90)
   myPen.circle(radius,angle) 
#Completing the maze...
myPen.forward(25)
drawArc(165,175,-160)
myPen.setheading(195)
myPen.forward(40)
drawArc(125,20,165)
myPen.setheading(190)
myPen.forward(50)
# Complete the code from here...
input()

Saturday, August 1, 2026

Week 11 Assignments

Week 11 Notes


# 
# Python Problem Solver
# Week 11 Example 2: Conway's Game of Life
#
import turtle
import time
from random import randint

gridSize = 15
myPen = turtle.Turtle()
turtle.tracer(0)
myPen.speed(0)
myPen.color("#000000")
topLeft_x=-180
topLeft_y=180

def glider():
    grid = []
    grid.append([0,1,0,0,0,0,0,0,0,0])
    grid.append([0,0,1,0,0,0,0,0,0,0])
    grid.append([1,1,1,0,0,0,0,0,0,0])
    grid.append([0,0,0,0,0,0,0,0,0,0])
    grid.append([0,0,0,0,0,0,0,0,0,0])
    grid.append([0,0,0,0,0,0,0,0,0,0])
    grid.append([0,0,0,0,0,0,0,0,0,0])
    grid.append([0,0,0,0,0,0,0,0,0,0])
    grid.append([0,0,0,0,0,0,0,0,0,0])
    grid.append([0,0,0,0,0,0,0,0,0,0])
    return grid

# This function draws a box by drawing each side of the square and using the fill function
def box(intDim):
    myPen.begin_fill()
    # 0 deg.
    myPen.forward(intDim)
    myPen.left(90)
    # 90 deg.
    myPen.forward(intDim)
    myPen.left(90)
    # 180 deg.
    myPen.forward(intDim)
    myPen.left(90)
    # 270 deg.
    myPen.forward(intDim)
    myPen.end_fill()
    myPen.setheading(0)

#Draw the grid on screen (intDim is the width of a cell on the grid)
def drawGrid(grid,intDim):  
    global gridSize  
    #Clear the screen  
    myPen.clear()  
    for i in range(0,gridSize+1):
        myPen.penup()    
        myPen.goto(topLeft_x,topLeft_y-i*intDim)    
        myPen.pendown()    
        myPen.goto(topLeft_x+gridSize*intDim,topLeft_y-i*intDim)  
    for i in range(0,gridSize+1):    
        myPen.penup()    
        myPen.goto(topLeft_x+i*intDim,topLeft_y)
        myPen.pendown()
        myPen.goto(topLeft_x+i*intDim,topLeft_y-gridSize*intDim)
    for i in range(0,gridSize):
        myPen.penup()
        myPen.goto(topLeft_x+i*intDim+10,topLeft_y+10)
        myPen.write(chr(65+i))
    for i in range(1,gridSize+1):
        myPen.penup()
        myPen.goto(topLeft_x-15,topLeft_y-i*intDim+10)
        myPen.write(str(i))
    myPen.setheading(0)
    myPen.goto(topLeft_x,topLeft_y-intDim)
    for row in range (0,gridSize):
        for col in range (0,gridSize):
            if grid[row][col]>0:
                box(intDim)
            myPen.penup()
            myPen.forward(intDim)
            myPen.pendown()
        myPen.setheading(270)
        myPen.penup()
        myPen.forward(intDim)
        myPen.setheading(180)
        myPen.forward(intDim*gridSize)
        myPen.setheading(0)
        myPen.pendown()

def checkCell(row,col,grid):
    global gridSize
    # We will count neighbours except when at the edge of the grid 
    minRow=0
    if row>1:
        minRow=row-1
    maxRow=gridSize-1
    if row<gridSize-2:
        maxRow=row+1
    minCol=0
    if col>1:
        minCol=col-1
    maxCol=gridSize-1
    if col<gridSize-2:
        maxCol=col+1
  
    #C ount the number of neighbours
    neighbours=0-grid[row][col]  
    for nrow in range(minRow,maxRow+1):
        for ncol in range(minCol,maxCol+1):
            neighbours += grid[nrow][ncol]
    # Apply the four key rules of Conway's Game of Life
    # 1.Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
    if grid[row][col]==1 and neighbours<2:
        return 0
    #2. Any live cell with two or three live neighbours lives on to the next generation.
    elif grid[row][col]==1 and (neighbours==2 or neighbours==3):
        return 1
    #3. Any live cell with more than three live neighbours dies, as if by overpopulation.    
    elif grid[row][col]==1 and neighbours>3:
         return 0
    #4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
    elif grid[row][col]==0 and neighbours==3:
        return 1
    else:
         return 0

####################### MAIN PROGRAM STARTS HERE ######################
print("##########################")
print("Select a Starting Pattern:")
print("  2: Glider")
choice = input("Your Choice (1-5)?")

if choice=="2":
    gridSize = 10
    currentgrid=glider()
else:
    print("Invalid Choice!")
# Initialise the nextgrid
nextgrid = []
for row in range(0, gridSize):
    nextgrid.append([])
    for col in range(0, gridSize):
        nextgrid[row].append(0)

#Start animating the grid
while True:
    drawGrid(currentgrid, 25) #25 is the width of each square on the grid
    myPen.getscreen().update()
    time.sleep(0.5)
    # Generate Next Grid using the four key rules of Conway's Game of Life
    for row in range(0, gridSize):
        for col in range(0, gridSize):
            nextgrid[row][col] = checkCell(row, col, currentgrid)  
    # Swap grids (nextgrid becomes currentgrid)
    tmpgrid = currentgrid
    currentgrid = nextgrid
    nextgrid = tmpgrid



# 
# Python Problem Solver
# Week 11 Example 1: Naming Species
#

def left(string, num):
    return string[:num]

def right(string, num):
    return string[-num:]

def substr(string, start, num):
    return string[start:start+num]

str1 = input("Input a string: ")
n = int(input("Input number of characters: "))

str2 = left(str1, n)
print(f"left({str1},{n}) = {str2}")
str2 = right(str1, n)
print(f"right({str1},{n}) = {str2}")
s = int(input("Start position for substr: "))
str2 = substr(str1, s, n)
print(f"substr({str1},{s},{n}) = {str2}")

Term 2 Term Test