1. Conditional Flow (if and switch statements).
(a) Number in Range.
Write a function named
is_in_range that determines whether a number falls within a specified range (inclusive).
| Inputs: | value (1x1) double β the number to check
|
lower_bound (1x1) double β minimum value of the range
|
|
upper_bound (1x1) double β maximum value of the range
|
|
| Outputs: | result (1x1) logical β true if value is in range [lower_bound, upper_bound], false otherwise
|
Test cases:
% Test 1: Value in range
r1 = is_in_range(5, 1, 10)
% Expected: r1 = 1 (true)
% Test 2: Value at lower boundary
r2 = is_in_range(1, 1, 10)
% Expected: r2 = 1 (true)
% Test 3: Value at upper boundary
r3 = is_in_range(10, 1, 10)
% Expected: r3 = 1 (true)
% Test 4: Value below range
r4 = is_in_range(0, 1, 10)
% Expected: r4 = 0 (false)
% Test 5: Value above range
r5 = is_in_range(11, 1, 10)
% Expected: r5 = 0 (false)
(b) Tax Bracket Rate Finder.
Write a function named
find_tax_rate that determines the marginal tax rate for a given income based on progressive tax brackets.
Tax bracket rates:
-
Income up to $10,000: 0% tax rate
-
Income from $10,001 to $40,000: 10% tax rate
-
Income from $40,001 to $85,000: 15% tax rate
-
Income above $85,000: 20% tax rate
| Inputs: | income (1x1) double β annual income in dollars
|
| Outputs: | tax_rate (1x1) double β the marginal tax rate (as a decimal, e.g., 0.10 for 10%)
|
Test cases:
% Test 1: No tax bracket
t1 = find_tax_rate(8000)
% Expected: t1 = 0
% Test 2: 10% bracket
t2 = find_tax_rate(25000)
% Expected: t2 = 0.10
% Test 3: 15% bracket
t3 = find_tax_rate(60000)
% Expected: t3 = 0.15
% Test 4: 20% bracket
t4 = find_tax_rate(100000)
% Expected: t4 = 0.20
% Test 5: Boundary case
t5 = find_tax_rate(40000)
% Expected: t5 = 0.10
(c) Water Phase Identifier.
Write a function named
water_phase that determines the physical state of water (ice, liquid, or steam) based on temperature in Celsius at standard atmospheric pressure.
Phase rules:
-
Below 0Β°C: ice
-
From 0Β°C to 100Β°C (inclusive): liquid
-
Above 100Β°C: steam
| Inputs: | temp_celsius (1x1) double β temperature in Celsius
|
| Outputs: | phase (1x1) string β "ice", "liquid", or "steam"
|
Test cases:
% Test 1: Below freezing
p1 = water_phase(-10)
% Expected: p1 = "ice"
% Test 2: Freezing point
p2 = water_phase(0)
% Expected: p2 = "liquid"
% Test 3: Room temperature
p3 = water_phase(25)
% Expected: p3 = "liquid"
% Test 4: Boiling point
p4 = water_phase(100)
% Expected: p4 = "liquid"
% Test 5: Above boiling
p5 = water_phase(120)
% Expected: p5 = "steam"
(d) BMI Category Classifier.
Write a function named
bmi_category that calculates Body Mass Index (BMI) and classifies it into standard health categories.
BMI is calculated as: \(\text{BMI} = \frac{\text{weight (kg)}}{\text{height (m)}^2}\)
Categories:
-
BMI < 18.5: "Underweight"
-
BMI 18.5 to 24.9: "Normal weight"
-
BMI 25 to 29.9: "Overweight"
-
BMI β₯ 30: "Obese"
| Inputs: | weight_kg (1x1) double β weight in kilograms
|
height_m (1x1) double β height in meters
|
|
| Outputs: | category (1x1) string β the BMI category
|
Test cases:
% Test 1: Underweight
c1 = bmi_category(50, 1.75)
% Expected: c1 = "Underweight"
% Test 2: Normal weight
c2 = bmi_category(70, 1.75)
% Expected: c2 = "Normal weight"
% Test 3: Overweight
c3 = bmi_category(85, 1.75)
% Expected: c3 = "Overweight"
% Test 4: Obese
c4 = bmi_category(100, 1.75)
% Expected: c4 = "Obese"
% Test 5: Boundary case
c5 = bmi_category(75.5, 1.75)
% Expected: c5 = "Normal weight"
(e) Even and Positive.
Write a function named
is_even_and_positive that determines whether a number is both even and positive.
A number is even if dividing it by 2 produces no remainder. You can use the
mod function to find remainders.
| Inputs: | num (1x1) double β the number to check
|
| Outputs: | result (1x1) logical β true if num is both even and positive, false otherwise
|
Test cases:
% Test 1: Even and positive
r1 = is_even_and_positive(4)
% Expected: r1 = 1 (true)
% Test 2: Odd and positive
r2 = is_even_and_positive(7)
% Expected: r2 = 0 (false)
% Test 3: Even and negative
r3 = is_even_and_positive(-6)
% Expected: r3 = 0 (false)
% Test 4: Zero (even but not positive)
r4 = is_even_and_positive(0)
% Expected: r4 = 0 (false)
% Test 5: Large even positive
r5 = is_even_and_positive(100)
% Expected: r5 = 1 (true)
(f) Exclusive OR (XOR).
Write a function named
my_xor that implements the exclusive OR operation without using MATLABβs built-in xor function.
XOR returns true when exactly one (but not both) of the inputs is true. Think about how you can combine AND, OR, and NOT operators to achieve this behavior.
| Inputs: | a (1x1) logical β first logical value
|
b (1x1) logical β second logical value
|
|
| Outputs: | result (1x1) logical β true if exactly one input is true, false otherwise
|
Test cases:
% Test 1: Both false
r1 = my_xor(false, false)
% Expected: r1 = 0 (false)
% Test 2: First true, second false
r2 = my_xor(true, false)
% Expected: r2 = 1 (true)
% Test 3: First false, second true
r3 = my_xor(false, true)
% Expected: r3 = 1 (true)
% Test 4: Both true
r4 = my_xor(true, true)
% Expected: r4 = 0 (false)
(g) Parking Fee Calculator.
Write a function named
parking_fee that calculates the parking fee based on the number of hours parked.
Fee structure:
-
First hour: $3
-
Hours 2-4: $2 per hour
-
Hours 5+: $1.50 per hour
-
Maximum daily fee: $15
| Inputs: | hours (1x1) double β number of hours parked (may include fractions)
|
| Outputs: | fee (1x1) double β total parking fee in dollars
|
Test cases:
% Test 1: First hour
f1 = parking_fee(0.5)
% Expected: f1 = 3
% Test 2: Two hours
f2 = parking_fee(2)
% Expected: f2 = 5 (3 + 2)
% Test 3: Four hours
f3 = parking_fee(4)
% Expected: f3 = 9 (3 + 2 + 2 + 2)
% Test 4: Six hours
f4 = parking_fee(6)
% Expected: f4 = 12 (3 + 2 + 2 + 2 + 1.5 + 1.5)
% Test 5: Exceeds maximum
f5 = parking_fee(12)
% Expected: f5 = 15
(h) Rock-Paper-Scissors Judge.
Write a function named
rps_winner that determines the winner of a rock-paper-scissors game. Use a switch statement to handle the different move combinations.
Rules:
-
Rock beats Scissors
-
Scissors beats Paper
-
Paper beats Rock
-
Same moves result in a tie
Moves are represented as: βRβ for rock, βPβ for paper, βSβ for scissors.
| Inputs: | player1 (1x1) char β player 1βs move (βRβ, βPβ, or βSβ)
|
player2 (1x1) char β player 2βs move (βRβ, βPβ, or βSβ)
|
|
| Outputs: | result (1x1) string β "Player 1", "Player 2", or "Tie"
|
Test cases:
% Test 1: Rock beats Scissors
r1 = rps_winner('R', 'S')
% Expected: r1 = "Player 1"
% Test 2: Paper beats Rock
r2 = rps_winner('R', 'P')
% Expected: r2 = "Player 2"
% Test 3: Scissors beats Paper
r3 = rps_winner('S', 'P')
% Expected: r3 = "Player 1"
% Test 4: Tie
r4 = rps_winner('R', 'R')
% Expected: r4 = "Tie"
% Test 5: Another scenario
r5 = rps_winner('P', 'S')
% Expected: r5 = "Player 2"
(i) Hurricane Category Classifier.
Write a function named
hurricane_category that classifies a hurricane based on its wind speed using the Saffir-Simpson scale.
Categories (based on sustained wind speed in mph):
-
< 74: "Tropical Storm"
-
74-95: "Category 1"
-
96-110: "Category 2"
-
111-129: "Category 3"
-
130-156: "Category 4"
-
β₯ 157: "Category 5"
| Inputs: | wind_speed (1x1) double β sustained wind speed in mph
|
| Outputs: | category (1x1) string β the hurricane category
|
Test cases:
% Test 1: Tropical Storm
c1 = hurricane_category(60)
% Expected: c1 = "Tropical Storm"
% Test 2: Category 1
c2 = hurricane_category(85)
% Expected: c2 = "Category 1"
% Test 3: Category 3
c3 = hurricane_category(120)
% Expected: c3 = "Category 3"
% Test 4: Category 5
c4 = hurricane_category(160)
% Expected: c4 = "Category 5"
% Test 5: Boundary case
c5 = hurricane_category(74)
% Expected: c5 = "Category 1"
(j) Zodiac Sign Finder.
Write a function named
zodiac_sign that determines a personβs Western zodiac sign based on their birth month and day. Use a switch statement for the month, then if statements for the day ranges.
Zodiac date ranges (using format: month number, day range):
-
Capricorn: 12/22-1/19
-
Aquarius: 1/20-2/18
-
Pisces: 2/19-3/20
-
Aries: 3/21-4/19
-
Taurus: 4/20-5/20
-
Gemini: 5/21-6/20
-
Cancer: 6/21-7/22
-
Leo: 7/23-8/22
-
Virgo: 8/23-9/22
-
Libra: 9/23-10/22
-
Scorpio: 10/23-11/21
-
Sagittarius: 11/22-12/21
| Inputs: | month (1x1) double β birth month (1-12)
|
day (1x1) double β birth day (1-31)
|
|
| Outputs: | sign (1x1) string β zodiac sign name
|
Test cases:
% Test 1: Early January (Capricorn)
z1 = zodiac_sign(1, 10)
% Expected: z1 = "Capricorn"
% Test 2: Late January (Aquarius)
z2 = zodiac_sign(1, 25)
% Expected: z2 = "Aquarius"
% Test 3: Mid-year (Leo)
z3 = zodiac_sign(8, 5)
% Expected: z3 = "Leo"
% Test 4: Boundary case (Taurus/Gemini)
z4 = zodiac_sign(5, 20)
% Expected: z4 = "Taurus"
% Test 5: Late December (Capricorn - year boundary)
z5 = zodiac_sign(12, 25)
% Expected: z5 = "Capricorn"
(k) Leap Year Checker.
Write a function named
is_leap_year that determines whether a given year is a leap year.
The rules for leap years are:
-
A year is a leap year if it is divisible by 4
-
EXCEPT years divisible by 100 are NOT leap years
-
EXCEPT years divisible by 400 ARE leap years
For example: 2000 is a leap year (divisible by 400), 1900 is not (divisible by 100 but not 400), 2004 is a leap year (divisible by 4 but not 100).
| Inputs: | year (1x1) double β the year to check
|
| Outputs: | is_leap (1x1) logical β true if the year is a leap year, false otherwise
|
Test cases:
% Test 1: Divisible by 400 (leap year)
r1 = is_leap_year(2000)
% Expected: r1 = 1 (true)
% Test 2: Divisible by 100 but not 400 (not a leap year)
r2 = is_leap_year(1900)
% Expected: r2 = 0 (false)
% Test 3: Divisible by 4 but not 100 (leap year)
r3 = is_leap_year(2024)
% Expected: r3 = 1 (true)
% Test 4: Not divisible by 4 (not a leap year)
r4 = is_leap_year(2023)
% Expected: r4 = 0 (false)
% Test 5: Another divisible by 100 case
r5 = is_leap_year(2100)
% Expected: r5 = 0 (false)
(l) Quadratic Equation Solver.
Write a function named
quadratic_solver that takes the coefficients a, b, and c as inputs and returns the two solutions, x1 and x2 (if they exist), for a quadratic equation of the form
\begin{equation*}
ax^2 + bx + c = 0\text{.}
\end{equation*}
The function should handle different combinations of
a, b, and c being zero. Based on this there could be:-
Two solutions (repeated, distinct, or complex),
-
One solution (set
x2 = NaN),
Put on your math hat and think through the different cases to determine how to compute the solutions and what to return when there are no solutions or infinitely many solutions.
| Inputs: |
c (1x1) double β constant term
|
| Outputs: |
x1 (1x1) double β first solution of the quadratic equation
x2 (1x1) double β second solution of the quadratic equation
|
Test cases:
% Test 1: Two Real Solutions
[x1, x2] = quadratic_solver(1, -3, 2)
% Expected: x1 = 2, x2 = 1
% Test 2: Repeated Solutions
[x1, x2] = quadratic_solver(1, 2, 1)
% Expected: x1 = -1, x2 = -1
% Test 3: Complex Solutions
[x1, x2] = quadratic_solver(1, 0, 4)
% Expected: x1 = 2i, x2 = -2i
(m) Coordinate Quadrant Checker.
Write a function named
find_quadrant that determines which quadrant or axis a point (x, y) is located in on a 2D coordinate system.
Rules:
-
Quadrant I: x > 0 and y > 0
-
Quadrant II: x < 0 and y > 0
-
Quadrant III: x < 0 and y < 0
-
Quadrant IV: x > 0 and y < 0
-
Origin: x = 0 and y = 0
-
X-axis: y = 0 (but x β 0)
-
Y-axis: x = 0 (but y β 0)
| Inputs: | x (1x1) double β x-coordinate
|
y (1x1) double β y-coordinate
|
|
| Outputs: | location (1x1) string β "Quadrant I", "Quadrant II", "Quadrant III", "Quadrant IV", "Origin", "X-axis", or "Y-axis"
|
Test cases:
% Test 1: Quadrant I
loc1 = find_quadrant(3, 4)
% Expected: loc1 = "Quadrant I"
% Test 2: Quadrant II
loc2 = find_quadrant(-2, 5)
% Expected: loc2 = "Quadrant II"
% Test 3: Origin
loc3 = find_quadrant(0, 0)
% Expected: loc3 = "Origin"
% Test 4: X-axis
loc4 = find_quadrant(7, 0)
% Expected: loc4 = "X-axis"
% Test 5: Quadrant III
loc5 = find_quadrant(-3, -8)
% Expected: loc5 = "Quadrant III"
(n) Valid Triangle Detector.
Write a function named
is_valid_triangle that determines whether three side lengths form a valid triangle.
A triangle is valid if the sum of the two shortest sides is greater than the longest side and all sides are positive.
| Inputs: | a, b, c (1x1) double β side lengths of the triangle
|
| Outputs: | is_valid (1x1) logical β true if sides form a valid triangle, false otherwise
|
Test cases:
% Test 1: Equilateral triangle
v1 = is_valid_triangle(5, 5, 5)
% Expected: v1 = 1 (true)
% Test 2: Isosceles triangle
v2 = is_valid_triangle(5, 5, 8)
% Expected: v2 = 1 (true)
% Test 3: Scalene triangle
v3 = is_valid_triangle(3, 4, 5)
% Expected: v3 = 1 (true)
% Test 4: Invalid triangle
v4 = is_valid_triangle(1, 2, 10)
% Expected: v4 = 0 (false)
% Test 5: Another isosceles case
v5 = is_valid_triangle(7, 10, 7)
% Expected: v5 = 1 (true)
(o) Triangle Type Classifier.
Write a function named
classify_triangle that classifies a triangle as equilateral, isosceles, scalene, or invalid based on the lengths of its sides.
Rules:
-
Equilateral: all three sides are equal
-
Isosceles: exactly two sides are equal
-
Scalene: all three sides are different
-
Invalid: does not form a valid triangle
You must use the
is_valid_triangle function you wrote in the previous exercise as a βhelperβ function. This means that your classify_triangle function should (i) contain a call to is_valid_triangle and (ii) have a copy of the is_valid_triangle function code below it in the same file.
| Inputs: | a, b, c (1x1) double β side lengths of the triangle
|
| Outputs: | type (1x1) string β "Equilateral", "Isosceles", "Scalene", or "Invalid"
|
Test cases:
% Test 1: Equilateral triangle
t1 = classify_triangle(5, 5, 5)
% Expected: t1 = "Equilateral"
% Test 2: Isosceles triangle
t2 = classify_triangle(5, 5, 8)
% Expected: t2 = "Isosceles"
% Test 3: Scalene triangle
t3 = classify_triangle(3, 4, 5)
% Expected: t3 = "Scalene"
% Test 4: Invalid triangle
t4 = classify_triangle(1, 2, 10)
% Expected: t4 = "Invalid"
% Test 5: Another isosceles case
t5 = classify_triangle(7, 10, 7)
% Expected: t5 = "Isosceles"
