MediumExceptionsNot started

Dose checker with exceptions

A pharmacy script works out the dose per kilogram of body weight. Write a function dosePerKilo(float $weightKg, float $doseMg): float that throws an InvalidArgumentException with the message weight must be positive when the weight is zero or negative, throws one with the message dose must not be negative when the dose is below zero, and otherwise returns dose divided by weight. Check the weight first. Read a list of weight and dose pairs and, for each, print the result with two decimals or Error: followed by the exception message. A bad line must not stop the lines after it.

Input

The first line is N (1 to 200). Each of the next N lines has two numbers separated by a space: the weight in kilograms and the dose in milligrams. Either may be negative or have decimals; the weight may be 0.

Output

N lines: either the dose per kilogram with two decimals, or Error: <message>.

Example 1

Input

3
70 350
0 100
50 -5

Output

5.00
Error: weight must be positive
Error: dose must not be negative

350 / 70 = 5. A zero weight and a negative dose each raise a different message, and processing continues.

Example 2

Input

2
2.5 10
-10 -10

Output

4.00
Error: weight must be positive

Decimals work as floats. When both values are bad, the weight check comes first so only its message is shown.

Constraints

  • 1 <= N <= 200
  • -1000 <= weight, dose <= 1000
  • Results are printed with exactly two decimals

Hints

Hint 1 of 3

throw new InvalidArgumentException('message') leaves the function immediately.

Hint 2 of 3

Wrap only the call and the echo in try { ... } catch (InvalidArgumentException $e) { ... } inside the loop, so one failure does not end the loop.

Hint 3 of 3

$e->getMessage() returns the text you passed to the constructor.

Solution

Show a reference solution and explanation
 PHP · reference solution
<?php
function dosePerKilo(float $weightKg, float $doseMg): float
{
    if ($weightKg <= 0) {
        throw new InvalidArgumentException('weight must be positive');
    }
    if ($doseMg < 0) {
        throw new InvalidArgumentException('dose must not be negative');
    }
    return $doseMg / $weightKg;
}

$n = (int) trim(fgets(STDIN));
for ($i = 0; $i < $n; $i++) {
    [$weight, $dose] = explode(' ', trim(fgets(STDIN)));
    try {
        $perKilo = dosePerKilo((float) $weight, (float) $dose);
        echo sprintf('%.2f', $perKilo), "\n";
    } catch (InvalidArgumentException $e) {
        echo 'Error: ', $e->getMessage(), "\n";
    }
}

Why it works

Exceptions let the function refuse bad input without returning a magic value like -1 that the caller might forget to check. Because the try block sits inside the loop, a thrown exception unwinds only the current iteration: control jumps to the matching catch, the error line is printed, and the loop continues with the next line of input. InvalidArgumentException is one of PHP's standard SPL exception classes and is the conventional choice for arguments that violate a function's contract. Checking the weight before the dose is not just a style point: the order of the checks decides which message wins when both values are wrong, and the tests rely on it. Note that PHP 8 already throws DivisionByZeroError for division by zero, but that is an Error, not an Exception, and its message would not be the one the pharmacy wants.

Lesson for this exercise: Exceptions and Error Handling in PHP

Your program
<?php
function dosePerKilo(float $weightKg, float $doseMg): float
{
    // throw InvalidArgumentException for bad input, otherwise return dose / weight
    return 0.0;
}

$n = (int) trim(fgets(STDIN));
for ($i = 0; $i < $n; $i++) {
    [$weight, $dose] = explode(' ', trim(fgets(STDIN)));
    // call dosePerKilo inside try/catch and print the result or the error line
}
Run is not available for PHP in the browser yet. Write your program here, then download it and run it locally with PHP 8.4 against the examples above. The reference solution below was verified the same way.

Tests: 5 cases including the examples. Passing every test marks the exercise solved in this browser.

How this page was checked. Every program on it was run with PHP 8.4 at build time by the publishing checks, and the output shown is what it printed. Running PHP inside the browser is not available yet, so the Run button is absent rather than pretending; copy the code and run it with PHP 8.4 locally.