Creating Functions
A function is a named block of code you can call whenever you need it. Instead of copying the same loop every time you want a square, you define it once in a function.
func drawSquare() { for _ in 1...4 { pen.addLine(distance: 100) pen.turn(degrees: 90) } } // Call it as many times as you like: drawSquare() pen.move(distance: 120) drawSquare()
Functions promote DRY code — Don't Repeat Yourself. If you need to change the square size, you only change it in one place.
| Standard | Connection |
|---|---|
| Functions & Modelling | A function in programming is analogous to a function in mathematics: it encapsulates a process. Calling a function repeatedly mirrors evaluating f(x) for multiple inputs. |
Octagons
Write a function called drawOctagon() that draws a regular octagon (8 sides, exterior angle 45°). Call it three times to draw a row of three octagons.
func drawOctagon() { for _ in 1...8 { pen.addLine(distance: 80) pen.turn(degrees: 45) } } drawOctagon() pen.move(distance: 100) drawOctagon() pen.move(distance: 100) drawOctagon()
| Standard | Connection |
|---|---|
| Geometry — Regular Polygons | A regular octagon has 8 sides and exterior angles of 360°/8 = 45°. Its interior angles are 180° − 45° = 135°. |
Parameters
Functions become far more powerful when they accept parameters — values passed in by the caller. The function uses the parameter name like a variable inside its body.
func drawSquare(size: Double) { for _ in 1...4 { pen.addLine(distance: size) pen.turn(degrees: 90) } } // Draw squares of different sizes: drawSquare(size: 50) drawSquare(size: 100) drawSquare(size: 150)
You can have multiple parameters, separated by commas. Swift uses argument labels at the call site for readability:
func drawRectangle(width: Double, height: Double) { for _ in 1...2 { pen.addLine(distance: width) pen.turn(degrees: 90) pen.addLine(distance: height) pen.turn(degrees: 90) } } drawRectangle(width: 200, height: 100)
| Standard | Connection |
|---|---|
| Functions & Modelling | A parameterised function is a direct model of a mathematical function f(x). The parameter is the input, and the drawn shape is the output. Multiple parameters map to multi-variable functions f(x, y). |
Different Sizes
Write a function drawRegularPolygon(sides: Int, sideLength: Double) that draws any regular polygon. Use it to draw a triangle, square, pentagon, hexagon, and octagon, each a different size, arranged in a row.
func drawRegularPolygon(sides: Int, sideLength: Double) { let angle = 360.0 / Double(sides) for _ in 1...sides { pen.addLine(distance: sideLength) pen.turn(degrees: angle) } } drawRegularPolygon(sides: 3, sideLength: 60) pen.move(distance: 80) drawRegularPolygon(sides: 4, sideLength: 60) pen.move(distance: 80) drawRegularPolygon(sides: 5, sideLength: 60) pen.move(distance: 80) drawRegularPolygon(sides: 6, sideLength: 60) pen.move(distance: 80) drawRegularPolygon(sides: 8, sideLength: 60)
| Standard | Connection |
|---|---|
| Geometry — Regular Polygons | A single parameterised function replaces six separate loop blocks. The exterior angle formula 360°/n shows a direct inverse relationship between number of sides and turn angle. |
Different Shapes
Write a function drawRectangle(width: Double, height: Double, color: Color) that draws a filled rectangle of any size and colour. Use it to create a colourful grid of rectangles — 3 columns, 3 rows, each a different colour and proportion.
func drawRectangle(width: Double, height: Double, color: Color) { let shape = Pen() shape.fillColor = color for _ in 1...2 { shape.addLine(distance: width) shape.turn(degrees: 90) shape.addLine(distance: height) shape.turn(degrees: 90) } pen.addShape(pen: shape) }
| Standard | Connection |
|---|---|
| Geometry — Area & Perimeter | Rectangles with the same perimeter can have different areas (and vice versa). Experimenting with width and height demonstrates this inverse relationship. |
Denmark
The Danish flag (Dannebrog) is a red rectangle with a white cross. The cross divides the flag into four rectangles. Write a function to draw the flag, with parameters for overall width and height.
Traditional proportions: 28 × 21 units; cross bars are 4 units wide; vertical bar is offset left of centre.
func drawDenmark(scale: Double) { // Red background let bg = Pen() bg.fillColor = .red for _ in 1...2 { bg.addLine(distance: 28 * scale) bg.turn(degrees: 90) bg.addLine(distance: 21 * scale) bg.turn(degrees: 90) } pen.addShape(pen: bg) // White cross let hBar = Pen() hBar.fillColor = .white for _ in 1...2 { hBar.addLine(distance: 28 * scale) hBar.turn(degrees: 90) hBar.addLine(distance: 4 * scale) hBar.turn(degrees: 90) } pen.addShape(pen: hBar) } drawDenmark(scale: 5)
| Standard | Connection |
|---|---|
| Ratio & Proportion | Flag dimensions use fixed ratios (28:21 = 4:3). Scaling by a constant multiplier preserves proportions — an application of ratio and scale factor. |
Sweden
The Swedish flag is blue with a yellow Scandinavian cross (same offset proportions as Denmark but with a blue background and gold cross). Adapt your Denmark function to draw the Swedish flag.
Proportions: 16 × 10 units; vertical bar 2 units wide at position 5 from left; horizontal bar 2 units wide at position 4 from top.
func drawSweden(scale: Double) { let bg = Pen(); bg.fillColor = .blue for _ in 1...2 { bg.addLine(distance: 16*scale); bg.turn(degrees:90) bg.addLine(distance: 10*scale); bg.turn(degrees:90) } pen.addShape(pen: bg) // Yellow cross bars drawn at offsets let cross = Pen(); cross.fillColor = .yellow for _ in 1...2 { cross.addLine(distance: 16*scale); cross.turn(degrees:90) cross.addLine(distance: 2*scale); cross.turn(degrees:90) } pen.addShape(pen: cross) } drawSweden(scale: 8)
| Standard | Connection |
|---|---|
| Ratio & Proportion | Identifying how Denmark and Sweden share a cross design but with different proportions reinforces the concept of scaled geometric similarity. |
Norway
Norway's flag has a red background with a blue cross outlined in white. Build on your Scandinavian cross function to add a second, slightly wider white cross drawn underneath the blue one.
// Draw layers: red bg → white cross (wider) → blue cross (narrower) // Use pen.move() with negative distances to reposition between layers func drawCrossBar(width: Double, thickness: Double, color: Color) { let bar = Pen(); bar.fillColor = color for _ in 1...2 { bar.addLine(distance: width); bar.turn(degrees:90) bar.addLine(distance: thickness); bar.turn(degrees:90) } pen.addShape(pen: bar) }
| Standard | Connection |
|---|---|
| Geometry — Concentric Shapes | Drawing a white cross wider than the blue cross creates an outline via layering — analogous to the concept of border width as the difference between outer and inner dimensions. |
St Andrew
The flag of Scotland features a white diagonal cross (saltire) on a blue background. Draw two diagonal lines connecting opposite corners of the flag's rectangle.
Hint: use trigonometry (or Pythagoras) to calculate the diagonal length from the width and height.
import Foundation let w: Double = 200, h: Double = 120 let diag = sqrt(w*w + h*h) let angle = atan2(h, w) * 180 / .pi // Diagonal 1: bottom-left to top-right pen.addLine(distance: diag) pen.move(distance: -diag) // Diagonal 2: top-left to bottom-right pen.turn(degrees: -angle * 2) pen.addLine(distance: diag)
| Standard | Connection |
|---|---|
| Pythagoras' Theorem | The diagonal of a rectangle with width w and height h has length √(w² + h²). This is a direct application of Pythagoras' theorem. |
St Patrick
The St Patrick's Cross is a red diagonal saltire (like St Andrew's but red on white). Draw it using the same approach as St Andrew, but with a red diagonal and white background.
// Reuse the St Andrew approach: // 1. Draw white background rectangle // 2. Set pen colour to red // 3. Draw diagonals using sqrt(w²+h²)
| Standard | Connection |
|---|---|
| Geometry — Similarity | St Patrick's Cross is geometrically identical to St Andrew's — the same shape, different colours. This demonstrates that geometric properties are independent of colour. |
St George
England's flag is a white background with a red cross (like Denmark but centred). Use your Scandinavian cross function with centred proportions.
func drawStGeorge(scale: Double) { // White background 3:2 proportions let bg = Pen(); bg.fillColor = .white for _ in 1...2 { bg.addLine(distance:30*scale); bg.turn(degrees:90) bg.addLine(distance:20*scale); bg.turn(degrees:90) } pen.addShape(pen: bg) // Red centred cross — horizontal and vertical bars let hBar = Pen(); hBar.fillColor = .red for _ in 1...2 { hBar.addLine(distance:30*scale); hBar.turn(degrees:90) hBar.addLine(distance:4*scale); hBar.turn(degrees:90) } pen.addShape(pen: hBar) } drawStGeorge(scale: 5)
| Standard | Connection |
|---|---|
| Geometry — Line Symmetry | St George's Cross has two lines of symmetry (horizontal and vertical) and 4-fold rotational symmetry — a symmetry group of order 4. |
Union Jack
The Union Jack is a combination of St George's Cross, St Andrew's Cross, and St Patrick's Cross. Use your functions from sections 09–11 to layer all three on the same flag. The order is: blue background → St Andrew (white) → St Patrick (red, thinner) → St George (red, centred).
// Call your existing functions in order: // 1. drawBlueBackground() // 2. drawSaltire(color: .white, thickness: 8) // St Andrew // 3. drawSaltire(color: .red, thickness: 4) // St Patrick // 4. drawCentredCross(color: .red, width: 6) // St George
| Standard | Connection |
|---|---|
| Geometry — Composition | The Union Jack is a superposition of three geometric designs. Function composition in code mirrors geometric composition — combining simple shapes to create complex ones. |
Filled Star
Write a function drawStar(points: Int, size: Double, color: Color) that draws a filled star with any number of points. Use it to draw three stars of different sizes side by side.
func drawStar(points: Int, size: Double, color: Color) { let angle = Double(180 - 180/points) * 2 let star = Pen(); star.fillColor = color for _ in 1...points { star.addLine(distance: size) star.turn(degrees: angle) } pen.addShape(pen: star) } drawStar(points: 5, size: 80, color: .yellow)
| Standard | Connection |
|---|---|
| Geometry — Star Polygons | A {n/2} star polygon turns 2×360°/n at each vertex. The turn angle formula derives from the exterior angle theorem for star polygons. |
Australia
The Australian flag has a blue background, the Union Jack in the top-left, a large 7-pointed star below it, and the Southern Cross (5 stars) on the right. Use your Union Jack and star functions to draw a simplified version.
// Use pen.move() to position each element: // 1. Blue background rectangle // 2. Union Jack scaled to top-left quadrant // 3. drawStar(points: 7, ...) below Union Jack // 4. Southern Cross: 4 large + 1 small star
| Standard | Connection |
|---|---|
| Geometry — Scale & Position | Fitting the Union Jack into one quadrant requires halving its dimensions — a scale factor of 0.5. Positions are calculated relative to flag dimensions using fractions. |
Netherlands
The Dutch flag is three equal horizontal stripes: red (top), white (middle), blue (bottom). Write a function drawTricolour(color1: Color, color2: Color, color3: Color, width: Double, height: Double) and draw the Netherlands flag.
func drawStripe(width: Double, height: Double, color: Color) { let s = Pen(); s.fillColor = color for _ in 1...2 { s.addLine(distance: width); s.turn(degrees:90) s.addLine(distance: height); s.turn(degrees:90) } pen.addShape(pen: s) } drawStripe(width: 200, height: 40, color: .red) pen.turn(degrees: 270); pen.move(distance: 40); pen.turn(degrees: 90) drawStripe(width: 200, height: 40, color: .white) pen.turn(degrees: 270); pen.move(distance: 40); pen.turn(degrees: 90) drawStripe(width: 200, height: 40, color: .blue)
| Standard | Connection |
|---|---|
| Geometry — Area | Three equal horizontal stripes each occupy 1/3 of the total area. Total area = width × height; each stripe area = width × (height/3). |
France
The French tricolour has three vertical stripes: blue, white, red. Reuse your stripe function from the Netherlands exercise, but rotate it 90° for vertical stripes.
// Draw three side-by-side rectangles (each 1/3 the total width) // After each stripe, move right by stripe width to start the next drawStripe(width: 60, height: 120, color: .blue) pen.move(distance: 60) drawStripe(width: 60, height: 120, color: .white) pen.move(distance: 60) drawStripe(width: 60, height: 120, color: .red)
| Standard | Connection |
|---|---|
| Geometry — Transformations | Rotating the stripe from horizontal to vertical is a 90° transformation. The same function with swapped width/height parameters achieves this in code. |
Positions
Update your flag functions to accept an x and y parameter so the flag can be drawn at any position on the canvas. Draw the flags of France, Netherlands, and Denmark side by side on the same canvas using positions.
func drawFrance(x: Double, y: Double, scale: Double) { pen.move(distance: x) pen.turn(degrees: 90) pen.move(distance: y) pen.turn(degrees: -90) // ... draw flag at current position } drawFrance(x: 0, y: 0, scale: 1) drawNetherlands(x: 220, y: 0, scale: 1) drawDenmark(x: 440, y: 0, scale: 1)
| Standard | Connection |
|---|---|
| Coordinate Geometry | Specifying x and y positions is the Cartesian coordinate system applied to canvas layout. Moving to position (x, y) mirrors plotting a point on the coordinate plane. |
Switzerland
The Swiss flag is a red square with a white cross made from two equal rectangles overlapping at the centre. The cross is centred, and the rectangles have a 1:6 proportion relative to the flag size. Draw it using your rectangle function.
// Swiss flag: 1:1 square ratio // Cross: two rectangles sized 1/6 × 2/3 of flag width // Centred: offset = (flag_width - cross_arm) / 2 let size: Double = 180 let arm = size / 5 let long = size * 3 / 5 let offset = (size - arm) / 2
| Standard | Connection |
|---|---|
| Geometry — Symmetry & Area | The Swiss cross has 4-fold rotational symmetry and 4 lines of reflection symmetry. The overlapping rectangles share an area, so the cross area = 2 × (arm × long) − arm² (subtract the double-counted centre square). |
Tonga
Tonga's flag is red with a white rectangle in the top-left corner containing a red cross. Use your positioned rectangle function and cross function to draw it.
// 1. Red background (full flag) // 2. White rectangle: top-left, width/height ≈ 1/3 of flag // 3. Red cross centred within the white rectangle
| Standard | Connection |
|---|---|
| Geometry — Composite Shapes | The white canton is a fraction of the total flag area. Calculating positions of shapes within other shapes applies fractional reasoning and proportional thinking. |
Puerto Rico
Puerto Rico's flag has five alternating red and white horizontal stripes, with a blue equilateral triangle on the left containing a white star. Combine your stripe function, triangle loop, and star function to draw it.
// 5 stripes alternating red/white let colors: [Color] = [.red, .white, .red, .white, .red] // Triangle left-side isoceles pointing right // Star centred in triangle
| Standard | Connection |
|---|---|
| Geometry — Triangles | The triangle is equilateral with its apex touching the right edge of the canton. Its height equals the flag height; side length = height / sin(60°) = height × 2/√3. |
United States
The US flag has 13 alternating red and white horizontal stripes, and a blue canton in the top-left with 50 stars arranged in staggered rows. Use loops, your stripe function, and your star function to draw a simplified version.
Challenge: arrange the 50 stars in the correct 6/5 alternating row pattern (6 rows of 5, 5 rows of 4 with offset).
// Outer loop: 11 rows (6 of 5 stars + 5 of 4 stars) for row in 0..<11 { let starsInRow = row % 2 == 0 ? 6 : 5 let xOffset = row % 2 == 0 ? 0 : starSpacing / 2 for col in 0..<starsInRow { // position and draw small star } }
| Standard | Connection |
|---|---|
| Patterns & Nested Loops | The staggered star arrangement is generated by a nested loop where the inner count and x-offset depend on whether the row index is even or odd — connecting number patterns to geometric layout. |