Tracks
/
Swift
Swift
/
Exercises
/
Freelancer Rates
Freelancer Rates

Freelancer Rates

Learning Exercise

Introduction

Numbers

Swift provides two primary categories of numbers: integers and floating-point numbers.

  • Integers represent whole numbers with no fractional component, such as 0, 1, -1, 42, and -273.
  • Floating-point numbers represent numbers with a fractional component, such as 0.0, 3.14, and -1.36969e-10.

You can insert underscores into numeric literals to improve readability: 1_000_000 is identical to 1000000. Floating-point literals can be written in decimal or exponential notation.

In most cases, you use Int for integers and Double for floating-point numbers:

let speed: Int = 42                           // Explicit Int
let pi: Double = 3.14                         // Explicit Double
let giga: Double = 1_000_000_000              // Double with readability underscores
let plancksConstant: Double = 6.62607015e-34  // Double in scientific notation

Arithmetic Operators

Swift provides standard arithmetic operators for numeric calculations:

Operator Description Example
+ Addition 4 + 6 evaluates to 10
- Subtraction 15 - 10 evaluates to 5
* Multiplication 2 * 3 evaluates to 6
Caution

Swift is type-safe and does not allow mixing different numeric types in arithmetic operations. You cannot directly add or multiply an Int and a Double; you must convert one type to match the other first.

Division

The / operator performs division. When both operands are integers, integer division truncates any fractional remainder:

5.0 / 2.0 // 2.5 (Double division)
5 / 2     // 2 (integer division truncates the remainder)

Dividing a non-zero floating-point number by zero results in inf or -inf. Dividing 0.0 by 0.0 produces nan (Not a Number). In contrast, dividing an integer by zero causes a compile-time or runtime error:

print(5.0 / 0.0)  // Prints inf
print(-5.0 / 0.0) // Prints -inf
print(0.0 / 0.0)  // Prints nan

// The following line will not compile:
// print(5 / 0) // Error: Division by zero

Remainder Operator

The remainder operator (%) calculates the remainder left over after dividing two integers:

5 % 2  // 1
-5 % 2 // -1

// Dividing by zero produces an error:
// 5 % 0 // Error: Division by zero
Note

In Swift, % is a true remainder operator rather than a modulo operator. The result always takes the sign of the first operand (the dividend), regardless of the sign of the second operand:

5 % -2  // 1
-5 % 2  // -1

Rounding Floating-Point Numbers

You can round a floating-point number using the rounded() method. By default, rounded() rounds to the nearest integer. You can also supply a specific rounding rule, such as .up or .down:

let x = 3.14
let y = x.rounded()      // 3.0
let w = x.rounded(.down) // 3.0
let z = x.rounded(.up)   // 4.0

Type Inference

When you declare a numeric constant or variable without a type annotation, Swift infers its type:

  • Whole numbers default to Int.
  • Numbers with a decimal point default to Double.
let x = 42         // Inferred as Int
let y = 42.0       // Inferred as Double
let z: Double = 42 // Explicitly typed as Double

Type Conversion

To perform operations between values of different types, convert one value using type initializers like Double(_:) or Int(_:):

let integerCount = 42
let floatingCount = Double(integerCount)
print(floatingCount) // Prints 42.0

let pi = 3.14
let integerPi = Int(pi)
print(integerPi) // Prints 3 (fractional part is truncated)

Instructions

In this exercise, you'll be writing code to help a freelancer communicate with a project manager. Your task is to provide a few utilities to quickly calculate daily and monthly rates, optionally with a given discount.

We first establish a few rules between the freelancer and the project manager:

  • The daily rate is 8 times the hourly rate.
  • A month has 22 billable days.

Sometimes, the freelancer is offering to apply a discount on their daily rate (for example for their most loyal customers or not-for-profit customers).

Discounts are modeled as fractional numbers representing percentages, for example, 25.0 (25%).

1. Calculate the daily rate given an hourly rate

Implement a function called dailyRateFrom to calculate the daily rate given an hourly rate as a parameter. The contract defines that a day has 8 billable hours.

dailyRateFrom(hourlyRate: 60)
// Returns 480.0

The returned daily rate should be a Double.

2. Calculate the monthly rate, given an hourly rate and a discount

Implement a monthlyRateFrom function to calculate the discounted monthly rate. It takes two parameters, an hourly rate and the discount in percent.

monthlyRateFrom(hourlyRate: 77, withDiscount: 10.5)
// Returns 12129

The returned monthly rate should be rounded up (take the ceiling) to the nearest integer.

3. Calculate the number of complete workdays given a budget, hourly rate, and discount

Implement a function workdaysIn that takes a budget, an hourly rate, and a discount, and calculates how many complete days of work that covers.

workdaysIn(budget: 20000, hourlyRate: 80, withDiscount: 11.0)
// Returns 35.0

The returned number of days should be rounded down (take the floor) to the next integer.

Edit via GitHub The link opens in a new window or tab
Swift Exercism

Ready to start Freelancer Rates?

Sign up to Exercism to learn and master Swift with 35 concepts116 exercises, and real human mentoring, all for free.