Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meltdown exercise change according to issue #2565 #2568

Merged
merged 7 commits into from
Sep 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions exercises/concept/meltdown-mitigation/.docs/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ True
Once the reactor has started producing power its efficiency needs to be determined.
Efficiency can be grouped into 4 bands:

1. green -> 80-100% efficiency
2. orange -> 60-79% efficiency
3. red -> 30-59% efficiency
4. black -> <30% efficient

These percentage ranges are calculated as `(generated_power/theoretical_max_power)*100`
where `generated_power = voltage * current`
1. green -> efficiency of 80% or more,
2. orange -> efficiency of less than 80% but at least 60%,
3. red -> efficiency below 60%, but still 30% or more,
4. black -> less than 30% efficient.

The percentage value can be calculated as `(generated_power/theoretical_max_power)*100`
where `generated_power = voltage * current`.
Note that the percentage value is usually not an integer number, so make sure to consider the
proper use of the `<` and `<=` comparisons.

Implement the function `reactor_efficiency()`, with three parameters: `voltage`,
`current`, and `theoretical_max_power`.
Expand Down
1 change: 1 addition & 0 deletions exercises/concept/meltdown-mitigation/.meta/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"blurb": "Learn about conditionals and avoid a meltdown by developing a simple control system for a Nuclear Reactor.",
"icon": "circular-buffer",
"authors": ["sachsom95", "BethanyG"],
"contributors": ["kbuc"],
"files": {
"solution": ["conditionals.py"],
"test": ["conditionals_test.py"],
Expand Down
38 changes: 19 additions & 19 deletions exercises/concept/meltdown-mitigation/.meta/exemplar.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
def is_criticality_balanced(temperature, neutrons_emitted):
"""Verify criticality is balanced.

:param temperature: int
:param neutrons_emitted: int
:param temperature: temperature value (integer or float)
:param neutrons_emitted: number of neutrons emitted per second (integer or float)
:return: boolean True if conditions met, False if not

A reactor is said to be critical if it satisfies the following conditions:
- The temperature less than 800.
- The number of neutrons emitted per second greater than 500.
- The product of temperature and neutrons emitted per second less than 500000.
- The temperature is less than 800.
- The number of neutrons emitted per second is greater than 500.
- The product of temperature and neutrons emitted per second is less than 500000.
"""
output = temperature * neutrons_emitted
balanced = False
Expand All @@ -22,19 +22,19 @@ def is_criticality_balanced(temperature, neutrons_emitted):
def reactor_efficiency(voltage, current, theoretical_max_power):
"""Assess reactor efficiency zone.

:param voltage: int
:param current: int
:param theoretical_max_power: int
:param voltage: voltage value (integer or float)
:param current: current value (integer or float)
:param theoretical_max_power: power that corresponds to a 100% efficiency (integer or float)
:return: str one of 'green', 'orange', 'red', or 'black'

Efficiency can be grouped into 4 bands:

1. green -> 80-100% efficiency
2. orange -> 60-79% efficiency
3. red -> 30-59% efficiency
4. black -> <30% efficient
1. green -> efficiency of 80% or more,
2. orange -> efficiency of less than 80% but at least 60%,
3. red -> efficiency below 60%, but still 30% or more,
4. black -> less than 30% efficient.

These percentage ranges are calculated as
The percentage value is calculated as
(generated power/ theoretical max power)*100
where generated power = voltage * current
"""
Expand All @@ -44,9 +44,9 @@ def reactor_efficiency(voltage, current, theoretical_max_power):

if 80 <= percentage_range <= 100:
efficiency_level = 'green'
elif 60 <= percentage_range <= 79:
elif 60 <= percentage_range < 80:
efficiency_level = 'orange'
elif 30 <= percentage_range <= 59:
elif 30 <= percentage_range < 60:
efficiency_level = 'red'
else:
efficiency_level = 'black'
Expand All @@ -57,17 +57,17 @@ def reactor_efficiency(voltage, current, theoretical_max_power):
def fail_safe(temperature, neutrons_produced_per_second, threshold):
"""Assess and return safety range.

:param temperature:
:param neutrons_produced_per_second:
:param threshold:
:param temperature: value of the temperature (integer or float)
:param neutrons_produced_per_second: neutron flux (integer or float)
:param threshold: threshold (integer or float)
:return: str one of: 'LOW', 'NORMAL', 'DANGER'

- `temperature * neutrons per second` < 40% of `threshold` == 'LOW'
- `temperature * neutrons per second` +/- 10% of `threshold` == 'NORMAL'
- `temperature * neutron per second` is not in the above-stated ranges == 'DANGER'
"""
output = temperature * neutrons_produced_per_second
operational_percentage = int((output / threshold) * 100)
operational_percentage = (output / threshold) * 100
safety_range = 'UNKNOWN'

if operational_percentage < 40:
Expand Down
31 changes: 17 additions & 14 deletions exercises/concept/meltdown-mitigation/conditionals.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
""" Meltdown Mitigation exercise """


def is_criticality_balanced(temperature, neutrons_emitted):
"""Verify criticality is balanced.

:param temperature: int
:param neutrons_emitted: int
:param temperature: temperature value (integer or float)
:param neutrons_emitted: number of neutrons emitted per second (integer or float)
:return: boolean True if conditions met, False if not

A reactor is said to be critical if it satisfies the following conditions:
Expand All @@ -17,19 +20,19 @@ def is_criticality_balanced(temperature, neutrons_emitted):
def reactor_efficiency(voltage, current, theoretical_max_power):
"""Assess reactor efficiency zone.

:param voltage: int
:param current: int
:param theoretical_max_power: int
:param voltage: voltage value (integer or float)
:param current: current value (integer or float)
:param theoretical_max_power: power that corresponds to a 100% efficiency (integer or float)
:return: str one of 'green', 'orange', 'red', or 'black'

Efficiency can be grouped into 4 bands:

1. green -> 80-100% efficiency
2. orange -> 60-79% efficiency
3. red -> 30-59% efficiency
4. black -> <30% efficient
1. green -> efficiency of 80% or more,
2. orange -> efficiency of less than 80% but at least 60%,
3. red -> efficiency below 60%, but still 30% or more,
4. black -> less than 30% efficient.

These percentage ranges are calculated as
The percentage value is calculated as
(generated power/ theoretical max power)*100
where generated power = voltage * current
"""
Expand All @@ -40,12 +43,12 @@ def reactor_efficiency(voltage, current, theoretical_max_power):
def fail_safe(temperature, neutrons_produced_per_second, threshold):
"""Assess and return safety range.

:param temperature:
:param neutrons_produced_per_second:
:param threshold:
:param temperature: value of the temperature (integer or float)
:param neutrons_produced_per_second: neutron flux (integer or float)
:param threshold: threshold (integer or float)
:return: str one of: 'LOW', 'NORMAL', 'DANGER'

- `temperature * neutrons per second` < 40% of threshold == 'LOW'
- `temperature * neutrons per second` < 40% of `threshold` == 'LOW'
- `temperature * neutrons per second` +/- 10% of `threshold` == 'NORMAL'
- `temperature * neutron per second` is not in the above-stated ranges == 'DANGER'
"""
Expand Down
200 changes: 53 additions & 147 deletions exercises/concept/meltdown-mitigation/conditionals_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# unit test here
import unittest
import pytest
from conditionals import (is_criticality_balanced,
Expand All @@ -7,164 +6,71 @@


class TestConditionals(unittest.TestCase):
# Checking the first condition using assertTrue and assertFalse
# The values for arguments is not final and should be considered as placeholders
# More test-cases required for full testing
"""Test cases for Meltdown mitigation exercise.
"""

@pytest.mark.task(taskno=1)
def test_is_criticality_balanced_set1(self):
self.assertTrue(is_criticality_balanced(
temperature=750, neutrons_emitted=650), msg="Expected True but returned False")
def test_is_criticality_balanced(self):
"""Testing border cases around typical points.

T, n == (800, 500), (625, 800), (500, 1000), etc.

@pytest.mark.task(taskno=1)
def test_is_criticality_balanced_set2(self):
self.assertTrue(is_criticality_balanced(
temperature=799, neutrons_emitted=501), msg="Expected True but returned False")


@pytest.mark.task(taskno=1)
def test_is_criticality_balanced_set3(self):
self.assertTrue(
is_criticality_balanced(temperature=500, neutrons_emitted=600), msg="Expected True but returned False"
)


@pytest.mark.task(taskno=1)
def test_is_criticality_balanced_set4(self):
self.assertFalse(
is_criticality_balanced(temperature=800, neutrons_emitted=500), msg="Expected False but returned True"
)

# End of first functions testing

# Test case for reactor_ efficiency()
# Checking the second condition using assertEqual
# The values for arguments is not final and should be considered as placeholders
# More test-cases required for full testing
# need to add more info to messages
# Need to verify if f-string based errors allowed

@pytest.mark.task(taskno=2)
def test_reactor_efficiency_set1(self):
test_return = reactor_efficiency(
voltage=100, current=50, theoretical_max_power=5000)
self.assertEqual(
test_return, 'green', msg=f"Expected green but returned {test_return}"
)
"""

test_data = ((750, 650, True), (799, 501, True), (500, 600, True),
(1000, 800, False), (800, 500, False), (800, 500.01, False),
(799.99, 500, False), (500.01, 999.99, False), (625, 800, False),
(625.99, 800, False), (625.01, 799.99, False), (799.99, 500.01, True),
(624.99, 799.99, True), (500, 1000, False), (500.01, 1000, False),
(499.99, 1000, True))

@pytest.mark.task(taskno=2)
def test_reactor_efficiency_set2(self):
test_return = reactor_efficiency(
voltage=100, current=30, theoretical_max_power=5000)
self.assertEqual(
test_return, 'orange', msg=f"Expected orange but returned {test_return}"
)
for variant, data in enumerate(test_data, start=1):
temperature, neutrons_emitted, expected = data
with self.subTest(f"variation #{variant}", temperature=temperature, neutrons_emitted=neutrons_emitted, expected=expected):
got = is_criticality_balanced(temperature, neutrons_emitted)
msg=f"Expected {expected} but returned {got} with T={temperature} and neutrinos={neutrons_emitted}"
self.assertEqual(got, expected, msg)


@pytest.mark.task(taskno=2)
def test_reactor_efficiency_set3(self):
test_return = reactor_efficiency(
voltage=100, current=28, theoretical_max_power=5000)
self.assertEqual(
test_return, 'red', msg=f"Expected red but returned {test_return}"
)
def test_reactor_efficiency(self):
voltage = 10
theoretical_max_power = 10000

# The numbers are chosen so that current == 10 x percentage
test_data = ((1000, 'green'), (999, 'green'), (800, 'green'),
(799, 'orange'), (700, 'orange'), (600, 'orange'),
(599, 'red'), (560, 'red'), (400, 'red'), (300, 'red'),
(299, 'black'), (200, 'black'), (0, 'black'))

@pytest.mark.task(taskno=2)
def test_reactor_efficiency_set4(self):
test_return = reactor_efficiency(
voltage=100, current=10, theoretical_max_power=5000)
self.assertEqual(
test_return, 'black', msg=f"Expected black but returned {test_return}"
)

# End of second function testing

# Test case for fail_safe()
# Checking the third condition using assertEqual
# The values for arguments is not final and should be considered as placeholders
# More test-cases required for full testing
# need to add more info to messages
# Need to verify if f-string based errors allowed

@pytest.mark.task(taskno=3)
def test_fail_safe_set1(self):
test_return = fail_safe(
temperature=100, neutrons_produced_per_second=18, threshold=5000)
self.assertEqual(
test_return, 'LOW', msg=f"Expected LOW but returned {test_return}"
)


@pytest.mark.task(taskno=3)
def test_fail_safe_set2(self):
test_return = fail_safe(
temperature=100, neutrons_produced_per_second=12, threshold=4000)
self.assertEqual(
test_return, 'LOW', msg=f"Expected LOW but returned {test_return}"
)
for variant, data in enumerate(test_data, start=1):
current, expected = data
with self.subTest(f"variation #{variant}", voltage=voltage, current=current,
theoretical_max_power=theoretical_max_power, expected=expected):
got = reactor_efficiency(voltage, current, theoretical_max_power)
msg=f"Expected {expected} but returned {got} with voltage={voltage}, current={current}, " \
f"max_pow={theoretical_max_power}"
self.assertEqual(got, expected, msg)


@pytest.mark.task(taskno=3)
def test_fail_safe_set3(self):
test_return = fail_safe(
temperature=100, neutrons_produced_per_second=10, threshold=3000)
self.assertEqual(
test_return, 'LOW', msg=f"Expected LOW but returned {test_return}"
)


@pytest.mark.task(taskno=3)
def test_fail_safe_set4(self):
test_return = fail_safe(
temperature=100, neutrons_produced_per_second=55, threshold=5000)
self.assertEqual(
test_return, 'NORMAL', msg=f"Expected NORMAL but returned {test_return}"
)


@pytest.mark.task(taskno=3)
def test_fail_safe_set5(self):
test_return = fail_safe(
temperature=100, neutrons_produced_per_second=45, threshold=5000)
self.assertEqual(
test_return, 'NORMAL', msg=f"Expected NORMAL but returned {test_return}"
)


@pytest.mark.task(taskno=3)
def test_fail_safe_set6(self):
test_return = fail_safe(
temperature=100, neutrons_produced_per_second=50, threshold=5000)
self.assertEqual(
test_return, 'NORMAL', msg=f"Expected NORMAL but returned {test_return}"
)


@pytest.mark.task(taskno=3)
def test_fail_safe_set7(self):
test_return = fail_safe(
temperature=1000, neutrons_produced_per_second=35, threshold=5000)
self.assertEqual(
test_return, 'DANGER', msg=f"Expected DANGER but returned {test_return}"
)


@pytest.mark.task(taskno=3)
def test_fail_safe_set8(self):
test_return = fail_safe(
temperature=1000, neutrons_produced_per_second=30, threshold=5000)
self.assertEqual(
test_return, 'DANGER', msg=f"Expected DANGER but returned {test_return}"
)


@pytest.mark.task(taskno=3)
def test_fail_safe_set9(self):
test_return = fail_safe(
temperature=1000, neutrons_produced_per_second=25, threshold=5000)
self.assertEqual(
test_return, 'DANGER', msg=f"Expected DANGER but returned {test_return}"
)
def test_fail_safe(self):
temperature = 10
threshold = 10000
test_data = ((399, 'LOW'), (300, 'LOW'),(1, 'LOW'),
(0, 'LOW'), (901, 'NORMAL'), (1000, 'NORMAL'),
(1099, 'NORMAL'), (899, 'DANGER'), (700, 'DANGER'),
(400, 'DANGER'), (1101, 'DANGER'), (1200, 'DANGER'))

for variant, data in enumerate(test_data, start=1):
neutrons_produced_per_second, expected = data

with self.subTest(f"variation #{variant}", temperature=temperature,
neutrons_produced_per_second=neutrons_produced_per_second,
threshold=threshold, expected=expected):

got = fail_safe(temperature, neutrons_produced_per_second, threshold)
msg = f"Expected {expected} but returned {got} with T={temperature}, " \
f"neutrons={neutrons_produced_per_second}, threshold={threshold}"
self.assertEqual(got, expected, msg)