Repository: exercism/python
Pull request #2514 (2021-09-01 09:14:35)

Stub and Exemplar file Corrections and Docstrings
Spell checked, edited per PyLInt, and added docstrings to the stub and exemplar files for these concept exercises:
- `Meltdown Mitigation` (conditionals)
- `Making the Grade` (loops)
- `Tisbury Treasure Hunt` (tuples)
- `Restaurant Rosalynn` (None)


Patch:
diff --git a/exercises/concept/making-the-grade/.meta/exemplar.py b/exercises/concept/making-the-grade/.meta/exemplar.py
index 2b335a26..2aa9283a 100644
--- a/exercises/concept/making-the-grade/.meta/exemplar.py
+++ b/exercises/concept/making-the-grade/.meta/exemplar.py
@@ -1,4 +1,9 @@
 def round_scores(student_scores):
+    '''
+    :param student_scores: list of student exam scores as float or int.
+    :return: list of student scores *rounded* to nearest integer value.
+    '''
+
     rounded = []
     while student_scores:
         rounded.append(round(student_scores.pop()))
@@ -6,6 +11,11 @@ def round_scores(student_scores):
 
 
 def count_failed_students(student_scores):
+    '''
+    :param student_scores: list of integer student scores.
+    :return: integer count of student scores at or below 40.
+    '''
+
     non_passing = 0
     for score in student_scores:
         if score <= 40:
@@ -14,14 +24,26 @@ def count_failed_students(student_scores):
 
 
 def above_threshold(student_scores, threshold):
-    above_threshold = []
+    '''
+    :param student_scores: list of integer scores
+    :param threshold :  integer
+    :return: list of integer scores that are at or above the "best" threshold.
+    '''
+
+    above = []
+
     for score in student_scores:
         if score >= threshold:
-            above_threshold.append(score)
-    return above_threshold
+            above.append(score)
+    return above
 
 
 def letter_grades(highest):
+    '''
+   :param highest: integer of highest exam score.
+   :return: list of integer score thresholds for each F-A letter grades.
+   '''
+
     increment = round((highest - 40)/4)
     scores = []
     for score in range(41, highest, increment):
@@ -30,20 +52,31 @@ def letter_grades(highest):
 
 
 def student_ranking(student_scores, student_names):
+    '''
+     :param student_scores: list of scores in descending order.
+     :param student_names: list of names in descending order by exam score.
+     :return: list of strings in format ["<rank>. <student name>: <score>"].
+     '''
+
     results = []
     for index, name in enumerate(student_names):
         rank_string = str(index + 1) + ". " + name + ": " + str(student_scores[index])
         results.append(rank_string)
-        #results.append(f"{index + 1}. {name}: {student_scores[index]}")
+
     return results
 
 
 def perfect_score(student_info):
+    '''
+    :param student_info: list of [<student name>, <score>] lists
+    :return: First [<student name>, 100] found OR "No perfect score."
+    '''
+
     result = "No perfect score."
+
     for item in student_info:
         if item[1] == 100:
             result = item
             break
-        else:
-            continue
+
     return result
diff --git a/exercises/concept/making-the-grade/loops.py b/exercises/concept/making-the-grade/loops.py
index 7e08125a..8c60c22c 100644
--- a/exercises/concept/making-the-grade/loops.py
+++ b/exercises/concept/making-the-grade/loops.py
@@ -3,6 +3,7 @@ def round_scores(student_scores):
     :param student_scores: list of student exam scores as float or int.
     :return: list of student scores *rounded* to nearest integer value.
     '''
+
     pass
 
 def count_failed_students(student_scores):
@@ -10,6 +11,7 @@ def count_failed_students(student_scores):
     :param student_scores: list of integer student scores.
     :return: integer count of student scores at or below 40.
     '''
+
     pass
 
 def above_threshold(student_scores, threshold):
@@ -18,6 +20,7 @@ def above_threshold(student_scores, threshold):
     :param threshold :  integer
     :return: list of integer scores that are at or above the "best" threshold.
     '''
+
     pass
 
 def letter_grades(highest):
@@ -25,14 +28,18 @@ def letter_grades(highest):
     :param highest: integer of highest exam score.
     :return: list of integer score thresholds for each F-A letter grades.
     '''
+
     pass
+
 def student_ranking(student_scores, student_names):
     '''
      :param student_scores: list of scores in descending order.
      :param student_names: list of names in descending order by exam score.
      :return: list of strings in format ["<rank>. <student name>: <score>"].
      '''
+
     pass
+
 def perfect_score(student_info):
     '''
     :param student_info: list of [<student name>, <score>] lists
diff --git a/exercises/concept/meltdown-mitigation/.meta/exemplar.py b/exercises/concept/meltdown-mitigation/.meta/exemplar.py
index 96c2833f..6791002a 100644
--- a/exercises/concept/meltdown-mitigation/.meta/exemplar.py
+++ b/exercises/concept/meltdown-mitigation/.meta/exemplar.py
@@ -18,7 +18,7 @@ def is_criticality_balanced(temperature, neutrons_emitted):
         return False
 
 
-def reactor_efficency(voltage, current, theoretical_max_power):
+def reactor_efficiency(voltage, current, theoretical_max_power):
     '''
 
     :param voltage: int
@@ -26,12 +26,12 @@ def reactor_efficency(voltage, current, theoretical_max_power):
     :param theoretical_max_power: int
     :return: str one of 'green', 'orange', 'red', or 'black'
 
-    Efficency can be grouped into 4 bands:
+    Efficiency can be grouped into 4 bands:
 
-    1. green  ->   80-100% efficency
-    2. orange ->   60-79% efficency
-    3. red    ->   30-59% efficency
-    4. black  ->   <30% efficent
+    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
diff --git a/exercises/concept/meltdown-mitigation/conditionals.py b/exercises/concept/meltdown-mitigation/conditionals.py
index 3ee8f789..ef0f3b85 100644
--- a/exercises/concept/meltdown-mitigation/conditionals.py
+++ b/exercises/concept/meltdown-mitigation/conditionals.py
@@ -10,10 +10,11 @@ def is_criticality_balanced(temperature, neutrons_emitted):
     - The number of neutrons emitted per second is greater than 500.
     - The product of temperature and neutrons emitted per second is less than 500000.
     '''
+
     pass
 
 
-def reactor_efficency(voltage, current, theoretical_max_power):
+def reactor_efficiency(voltage, current, theoretical_max_power):
     '''
 
     :param voltage: int
@@ -21,17 +22,18 @@ def reactor_efficency(voltage, current, theoretical_max_power):
     :param theoretical_max_power: int
     :return: str one of 'green', 'orange', 'red', or 'black'
 
-    Efficency can be grouped into 4 bands:
+    Efficiency can be grouped into 4 bands:
 
-    1. green  ->   80-100% efficency
-    2. orange ->   60-79% efficency
-    3. red    ->   30-59% efficency
-    4. black  ->   <30% efficent
+    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
     '''
+
     pass
 
 
@@ -47,4 +49,5 @@ def fail_safe(temperature, neutrons_produced_per_second, threshold):
     - `temperature * neutrons per second` +/- 10% of `threshold` == 'NORMAL'
     - `temperature * neutron per second` is not in the above-stated ranges ==  'DANGER'
     '''
+
     pass
diff --git a/exercises/concept/restaurant-rozalynn/.meta/exemplar.py b/exercises/concept/restaurant-rozalynn/.meta/exemplar.py
index 7fd3ca68..6bb76639 100644
--- a/exercises/concept/restaurant-rozalynn/.meta/exemplar.py
+++ b/exercises/concept/restaurant-rozalynn/.meta/exemplar.py
@@ -1,43 +1,87 @@
+
 def new_seating_chart(size=22):
-    seats = dict()
-    for number in range(1, size+1):
-        seats[number] = None
-    return seats
+    '''
+
+    :param size: int - number if seats in the seating chart.
+    :return: dict - with number of seats specified, and placeholder values.
+    '''
+
+    return {number: None for number in range(1, size+1) }
+
 
 def arrange_reservations(guests=None):
-    if guests is None:
-        return new_seating_chart()
-    else:
-        seats = new_seating_chart()
+    '''
+
+    :param guest_list: list - list of guest names for reservations.
+    :return: dict - Default sized dictionary with guests assigned seats,
+             and placeholders for empty seats.
+    '''
+
+    seats = new_seating_chart()
+
+    if guests:
         for seat_number in range(1, len(guests)):
             seats[seat_number] = guests[seat_number]
     return seats
 
+
 def find_all_available_seats(seats):
+    '''
+
+    :param seats: dict - seating chart.
+    :return: list - list of seat numbers available for reserving..
+    '''
+
     available = []
     for seat_num, value in seats.items():
         if value is None:
             available.append(seat_num)
     return available
 
+
 def curr_empty_seat_capacity(seats):
+    '''
+
+    :param seats: dict - dictionary of reserved seats.
+    :return: int - number of seats empty.
+    '''
+
     count = 0
     for value in seats.values():
         if value is None:
             count += 1
     return count
 
+
 def accommodate_waiting_guests(seats, guests):
+    '''
+
+    :param seats: dict - seating chart dictionary.
+    :param guests: list - walk-in guests
+    :return: dict - updated seating chart with available spaces filled.
+    '''
+
     curr_empty_seats = curr_empty_seat_capacity(seats)
     empty_seat_list = find_all_available_seats(seats)
+
     if len(guests) > curr_empty_seats:
         return False
     else:
-        for index in range(len(guests)):
+        for index, item in enumerate(guests):
             seats[empty_seat_list[index]] = guests[index]
+
     return seats
 
+
 def empty_seats(seats, seat_numbers):
-   for seat in seat_numbers:
-      seats[seat] = None
-   return seats
\ No newline at end of file
+    '''
+
+    :param seats: dict - seating chart dictionary.
+    :param seat_numbers: list - list of seat numbers to free up or empty.
+    :return: updated seating chart dictionary.
+    '''
+
+    for seat in seat_numbers:
+        seats[seat] = None
+
+    return seats
\ No newline at end of file
diff --git a/exercises/concept/restaurant-rozalynn/none.py b/exercises/concept/restaurant-rozalynn/none.py
index 8f873ce2..140f2175 100644
--- a/exercises/concept/restaurant-rozalynn/none.py
+++ b/exercises/concept/restaurant-rozalynn/none.py
@@ -1,16 +1,57 @@
-def new_seating_chart():
+def new_seating_chart(size=22):
+    '''
+
+    :param size: int - number if seats in the seating chart. Default is 22.
+    :return: dict - with number of seats specified, and placeholder values.
+    '''
+
+    pass
+
+def arrange_reservations(guest_list):
+    '''
+
+    :param guest_list: list - list of guest names for reservations.
+    :return: dict - Default sized dictionary with guests assigned seats,
+             and placeholders for empty seats.
+    '''
+
+    pass
+
+def find_all_available_seats(seats):
+    '''
+
+    :param seats: dict - seating chart.
+    :return: list - list of seat numbers available for reserving..
+    '''
+
     pass
 
-def arrange_reservations():
+def current_seating_capacity(seats):
+    '''
+
+    :param seats: dict - dictionary of reserved seats.
+    :return: int - number of seats empty.
+    '''
+
     pass
 
-def find_all_available_seats():
-   pass
+def accommodate_waiting_guests(seats, guests):
+    '''
 
-def current_seating_capacity():
-   pass
+    :param seats: dict - seating chart dictionary.
+    :param guests: list - walk-in guests
+    :return: dict - updated seating chart with available spaces filled.
+    '''
 
-def accommodate_waiting_guests():
-   pass
-def empty_seats():
     pass
+
+
+def empty_seats(seats, seat_numbers):
+    '''
+
+    :param seats: dict - seating chart dictionary.
+    :param seat_numbers: list - list of seat numbers to free up or empty.
+    :return: updated seating chart dictionary.
+    '''
+
+    pass
\ No newline at end of file
diff --git a/exercises/concept/tisbury-treasure-hunt/.meta/exemplar.py b/exercises/concept/tisbury-treasure-hunt/.meta/exemplar.py
index 729e72a4..33538bbf 100644
--- a/exercises/concept/tisbury-treasure-hunt/.meta/exemplar.py
+++ b/exercises/concept/tisbury-treasure-hunt/.meta/exemplar.py
@@ -1,21 +1,58 @@
 def get_coordinate(record):
+    '''
+
+    :param record: tuple - a (treasure, coordinate) pair.
+    :return: str - the extracted map coordinate.
+    '''
+
     return record[1]
 
+
 def convert_coordinate(coordinate):
+    '''
+
+    :param coordinate: str - a string map coordinate
+    :return:  tuple - the string coordinate seperated into its individual components.
+    '''
+
     return tuple(coordinate)
 
+
 def compare_records(azara_record, rui_record):
+    '''
+
+    :param azara_record: tuple - a (treasure, coordinate) pair.
+    :param rui_record: tuple - a (location, coordinate, quadrant) trio.
+    :return: bool - True if coordinates match, False otherwise.
+    '''
+
     return convert_coordinate(azara_record[1]) in rui_record
 
+
 def create_record(azara_record, rui_record):
+    '''
+
+    :param azara_record: tuple - a (treasure, coordinate) pair.
+    :param rui_record: tuple - a (location, coordinate, quadrant) trio.
+    :return:  tuple - combined record, or "not a match" if the records are incompatible.
+    '''
+
     if compare_records(azara_record, rui_record):
         return azara_record + rui_record
     else:
         return "not a match"
 
+
 def clean_up(combined_record_group):
+    '''
+
+    :param combined_record_group: tuple of tuples - everything from both participants.
+    :return: tuple of tuples - everything "cleaned", with excess coordinates and information removed.
+    '''
 
     report = ""
+
     for item in combined_record_group:
-       report += f"{(item[0], item[2], item[3], item[4])}\n"
+        report += f"{(item[0], item[2], item[3], item[4])}\n"
+
     return report
diff --git a/exercises/concept/tisbury-treasure-hunt/tuples.py b/exercises/concept/tisbury-treasure-hunt/tuples.py
index 9212aa06..bce55568 100644
--- a/exercises/concept/tisbury-treasure-hunt/tuples.py
+++ b/exercises/concept/tisbury-treasure-hunt/tuples.py
@@ -1,14 +1,46 @@
 def get_coordinate(record):
+    '''
+
+    :param record: tuple - a (treasure, coordinate) pair.
+    :return: str - the extracted map coordinate.
+    '''
+
     pass
 
 def convert_coordinate(coordinate):
+    '''
+
+    :param coordinate: str - a string map coordinate
+    :return:  tuple - the string coordinate seperated into its individual components.
+    '''
+
     pass
 
 def compare_records(azara_record, rui_record):
+    '''
+
+    :param azara_record: tuple - a (treasure, coordinate) pair.
+    :param rui_record: tuple - a (location, coordinate, quadrant) trio.
+    :return: bool - True if coordinates match, False otherwise.
+    '''
+
     pass
 
 def create_record(azara_record, rui_record):
+    '''
+
+    :param azara_record: tuple - a (treasure, coordinate) pair.
+    :param rui_record: tuple - a (location, coordinate, quadrant) trio.
+    :return:  tuple - combined record, or "not a match" if the records are incompatible.
+    '''
+
     pass
 
 def clean_up(combined_record_group):
+    '''
+
+    :param combined_record_group: tuple of tuples - everything from both participants.
+    :return: tuple of tuples - everything "cleaned", with excess coordinates and information removed.
+    '''
+
     pass


Test patch:
diff --git a/exercises/concept/meltdown-mitigation/conditionals_test.py b/exercises/concept/meltdown-mitigation/conditionals_test.py
index cc5bc567..abf94bc7 100644
--- a/exercises/concept/meltdown-mitigation/conditionals_test.py
+++ b/exercises/concept/meltdown-mitigation/conditionals_test.py
@@ -2,7 +2,7 @@
 import unittest
 import pytest
 from conditionals import (is_criticality_balanced,
-                          reactor_efficency,
+                          reactor_efficiency,
                           fail_safe
                           )
 
@@ -40,7 +40,7 @@ class TestConditionals(unittest.TestCase):
 
 # End of first functions testing
 
-# Test case for reactor_efficency()
+# 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
@@ -48,33 +48,33 @@ class TestConditionals(unittest.TestCase):
     # Need to verify if f-string based errors allowed
 
     @pytest.mark.task(taskno=2)
-    def test_reactor_efficency_set1(self):
+    def test_reactor_efficiency_set1(self):
 
-        test_return = reactor_efficency(
+        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}"
         )
 
     @pytest.mark.task(taskno=2)
-    def test_reactor_efficency_set2(self):
-        test_return = reactor_efficency(
+    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}"
         )
 
     @pytest.mark.task(taskno=2)
-    def test_reactor_efficency_set3(self):
-        test_return = reactor_efficency(
+    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}"
         )
 
     @pytest.mark.task(taskno=2)
-    def test_reactor_efficency_set4(self):
-        test_return = reactor_efficency(
+    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}"