diff --git a/.github/workflows/pydocstyle_kyu4.yml b/.github/workflows/pydocstyle_kyu4.yml new file mode 100644 index 00000000000..fb5fab4f43d --- /dev/null +++ b/.github/workflows/pydocstyle_kyu4.yml @@ -0,0 +1,46 @@ +--- +name: pydocstyle for kyu4 + +on: # yamllint disable-line rule:truthy + push: + branches: + - 'kyu4' + +permissions: + contents: read + pull-requests: read + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.x"] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + # This is the version of the action for setting up Python, + # not the Python version. + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + # You can test your matrix by printing the current Python version + - name: Display Python version + run: python -c "import sys; print(sys.version)" + - name: Install dependencies + run: | + python -m pip install --upgrade pip setuptools wheel + pip install -r requirements.txt + pip install pydocstyle + pip install types-requests + - name: Check to make sure that the module is in your Python path + run: | + echo $PYTHONPATH + - name: Check pydocstyle version + run: | + pydocstyle --version + - name: Doc style checking with pydocstyle + # Pydocstyle testing (Guide) + # https://www.pydocstyle.org/en/stable/usage.html#cli-usage + run: | + pydocstyle --verbose --explain --count kyu_4 diff --git a/kyu_4/__init__.py b/kyu_4/__init__.py index e69de29bb2d..f4a82f04020 100644 --- a/kyu_4/__init__.py +++ b/kyu_4/__init__.py @@ -0,0 +1 @@ +"""Codewars kyu_4 package.""" diff --git a/kyu_4/human_readable_duration_format/__init__.py b/kyu_4/human_readable_duration_format/__init__.py index e69de29bb2d..056c0879651 100644 --- a/kyu_4/human_readable_duration_format/__init__.py +++ b/kyu_4/human_readable_duration_format/__init__.py @@ -0,0 +1 @@ +"""Human readable duration format package.""" diff --git a/kyu_4/human_readable_duration_format/format_duration.py b/kyu_4/human_readable_duration_format/format_duration.py index 3bf8955a6a3..c1c41e583de 100644 --- a/kyu_4/human_readable_duration_format/format_duration.py +++ b/kyu_4/human_readable_duration_format/format_duration.py @@ -1,4 +1,6 @@ """ +Format duration. + A function which formats a duration, given as a number of seconds, in a human-friendly way. Created by Egor Kostan. @@ -8,37 +10,13 @@ def format_duration(seconds: int) -> str: """ + format_duration function. + A function which formats a duration, given as a number of seconds, in a human-friendly way. - - The resulting expression is made of components like 4 seconds, - 1 year, etc. In general, a positive integer and one of the - valid units of time, separated by a space. The unit of time - is used in plural if the integer is greater than 1. - - The components are separated by a comma and a space (", "). - Except the last component, which is separated by " and ", just - like it would be written in English. - - A more significant units of time will occur before than a least - significant one. Therefore, 1 second and 1 year is not correct, - but 1 year and 1 second is. - - Different components have different unit of times. So there is - not repeated units like in 5 seconds and 1 second. - - A component will not appear at all if its value happens to be zero. - Hence, 1 minute and 0 seconds is not valid, but it should be just 1 minute. - - A unit of time must be used "as much as possible". It means that the - function should not return 61 seconds, but 1 minute and 1 second instead. - Formally, the duration specified by of a component must not be greater than - any valid more significant unit of time. - :param seconds: int :return: str """ - if seconds == 0: return 'now' @@ -67,34 +45,36 @@ def format_duration(seconds: int) -> str: return result -def format_days(days: int, day: str, result: str) -> str: +def format_days(days: int, + day: str, + result: str) -> str: """ - Format days for the final string - :param days: - :param day: - :param result: - :return: + Format days for the final string. + + :param days: int + :param day: str + :param result: str + :return: str """ - if days > 0 and result != '': - result += f', {day}' - elif days > 0: - result += f'{day}' + if days > 0: + result += f', {day}' if result else f'{day}' return result -def format_hours(hours: int, hour: str, result: str) -> str: +def format_hours(hours: int, + hour: str, + result: str) -> str: """ - Format hours for the final string - :param hours: - :param hour: - :param result: - :return: + Format hours for the final string. + + :param hours: int + :param hour: str + :param result: str + :return: str """ - if hours > 0 and result != '': - result += f', {hour}' - elif hours > 0: - result += f'{hour}' + if hours > 0: + result += f', {hour}' if result else f'{hour}' return result @@ -104,12 +84,13 @@ def format_minutes(minutes: int, minute: str, result: str) -> str: """ - Format minutes for the final string - :param minutes: - :param seconds: - :param minute: - :param result: - :return: + Format minutes for the final string. + + :param minutes: int + :param seconds: int + :param minute: str + :param result: str + :return: str """ if minutes > 0 and result != '' and seconds == 0: result += f' and {minute}' @@ -123,26 +104,27 @@ def format_minutes(minutes: int, def format_seconds(seconds: int, second: str, result: str) -> str: """ - Format seconds for the final string - :param seconds: - :param second: - :param result: - :return: + Format seconds for the final string. + + :param seconds: int + :param second: str + :param result: str + :return: str """ - if seconds > 0 and result != '': - result += f' and {second}' - elif seconds > 0: - result += f'{second}' + if seconds > 0: + result += f' and {second}' if result else f'{second}' return result -def get_string(number: int, string: str) -> str: +def get_string(number: int, + string: str) -> str: """ - Concatenate string result - :param number: - :param string: - :return: + Concatenate string result. + + :param number: int + :param string: str + :return: str """ result: str = '' if number == 1: @@ -155,59 +137,52 @@ def get_string(number: int, string: str) -> str: def calc_seconds(seconds: int) -> int: """ - Calculate seconds - :param seconds: - :return: - """ - if seconds < 60: - return seconds + Calculate seconds. - return seconds % 60 + :param seconds: int + :return: int + """ + return seconds if seconds < 60 else seconds % 60 def calc_minutes(seconds: int) -> int: """ - calculate minutes - :param seconds: - :return: + Calculate minutes. + + :param seconds: int + :return: int """ minutes = seconds // 60 - if minutes < 60: - return minutes - - return minutes % 60 + return minutes if minutes < 60 else minutes % 60 def calc_hours(seconds: int) -> int: """ - Calculate hours - :param seconds: - :return: + Calculate hours. + + :param seconds: int + :return: int """ hours = seconds // (60 * 60) - if hours < 24: - return hours - - return hours % 24 + return hours if hours < 24 else hours % 24 def calc_days(seconds: int) -> int: """ - Calculate days - :param seconds: - :return: + Calculate days. + + :param seconds: int + :return: int """ days = seconds // (60 * 60 * 24) - if days < 365: - return days - - return days % 365 + return days if days < 365 else days % 365 def calc_years(seconds: int) -> int: """ - Calculate years - :param seconds: - :return: + Calculate years. + + :param seconds: int + :return: int """ return seconds // (60 * 60 * 24 * 365) diff --git a/kyu_4/human_readable_duration_format/test_format_duration.py b/kyu_4/human_readable_duration_format/test_format_duration.py index 0f498dc6ba2..6580a672242 100644 --- a/kyu_4/human_readable_duration_format/test_format_duration.py +++ b/kyu_4/human_readable_duration_format/test_format_duration.py @@ -1,5 +1,6 @@ """ -Test for 'Human readable duration format' +Test for 'Human readable duration format'. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -29,12 +30,12 @@ name='Source/Kata') # pylint: enable-msg=R0801 class FormatDurationTestCase(unittest.TestCase): - """ - Testing format_duration - """ + """Testing format_duration.""" def test_format_duration(self): """ + Test format_duration function. + Test a function which formats a duration, given as a number of seconds, in a human-friendly way. diff --git a/kyu_4/most_frequently_used_words/__init__.py b/kyu_4/most_frequently_used_words/__init__.py index e69de29bb2d..c288a6188db 100644 --- a/kyu_4/most_frequently_used_words/__init__.py +++ b/kyu_4/most_frequently_used_words/__init__.py @@ -0,0 +1 @@ +"""Most frequently used words in a text package.""" diff --git a/kyu_4/most_frequently_used_words/solution.py b/kyu_4/most_frequently_used_words/solution.py index 89813390c35..3557d1b8bd8 100644 --- a/kyu_4/most_frequently_used_words/solution.py +++ b/kyu_4/most_frequently_used_words/solution.py @@ -1,5 +1,6 @@ """ -Most frequently used words in a text +Most frequently used words in a text. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -7,6 +8,8 @@ def top_3_words(text: str) -> list: """ + Top 3 words function. + Given a string of text (possibly with punctuation and line-breaks), returns an array of the top-3 most occurring words, in descending order of the number of occurrences. diff --git a/kyu_4/most_frequently_used_words/test_top_3_words.py b/kyu_4/most_frequently_used_words/test_top_3_words.py index 3e4c70af713..54e0dd1133a 100644 --- a/kyu_4/most_frequently_used_words/test_top_3_words.py +++ b/kyu_4/most_frequently_used_words/test_top_3_words.py @@ -1,5 +1,6 @@ """ -Test for 'Most frequently used words in a text' +Test for 'Most frequently used words in a text'. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -28,13 +29,13 @@ url='https://www.codewars.com/kata/51e056fe544cf36c410000fb', name='Source/Kata') class Top3WordsTestCase(unittest.TestCase): - """ - Testing top_3_words - """ + """Testing top_3_words.""" def test_top_3_words(self): """ - Test top_3_words function + Test top_3_words function with various test data. + + :return: """ # pylint: disable-msg=R0801 allure.dynamic.title("Testing top_3_words function") diff --git a/kyu_4/next_bigger_number_with_the_same_digits/__init__.py b/kyu_4/next_bigger_number_with_the_same_digits/__init__.py index e69de29bb2d..30dc3d22713 100644 --- a/kyu_4/next_bigger_number_with_the_same_digits/__init__.py +++ b/kyu_4/next_bigger_number_with_the_same_digits/__init__.py @@ -0,0 +1 @@ +"""Next bigger number with the same digits package.""" diff --git a/kyu_4/next_bigger_number_with_the_same_digits/next_bigger.py b/kyu_4/next_bigger_number_with_the_same_digits/next_bigger.py index 889ff900f9b..1dda31b556f 100644 --- a/kyu_4/next_bigger_number_with_the_same_digits/next_bigger.py +++ b/kyu_4/next_bigger_number_with_the_same_digits/next_bigger.py @@ -1,5 +1,6 @@ """ -Solution for -> Next bigger number with the same digits +Solution for -> Next bigger number with the same digits. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -7,10 +8,14 @@ def next_bigger(n: int) -> int: """ + Next bigger function. + A function that takes a positive integer number and returns the next bigger number formed by the same digits. - If no bigger number can be composed using those digits, return -1 + If no bigger number can be composed using those digits, return -1. + :param n: + :return: """ # 1. Starting from last digit of given number, find the first digit # which breaks the sorted ordering. Let the index of this found @@ -32,6 +37,8 @@ def next_bigger(n: int) -> int: def digit_that_breaks_ordering_index(digits: list) -> int: """ + Find a digit that breaks ordering index. + Starting from last digit of given number, find the first digit which breaks the sorted ordering. Let the index of this found digit be 'i' and the digit be number[i]. @@ -48,6 +55,8 @@ def digit_that_breaks_ordering_index(digits: list) -> int: def next_greater_digit_index(digits: list, i: int) -> int: """ + Find next greater digit index. + Find the next greater digit in the right portion of number[i] - that is from digit at index i+1 to last digit. Let that digit be number[j] at index 'j'. @@ -62,11 +71,8 @@ def next_greater_digit_index(digits: list, i: int) -> int: return i for index, digit in enumerate(digits[i:]): - if digits[i - 1] < digit: - if current == '': - current = digit - j = i + index - elif current > digit: - current = digit - j = i + index + if digits[i - 1] < digit and (current == '' or current > digit): + current = digit + j = i + index + return j diff --git a/kyu_4/next_bigger_number_with_the_same_digits/test_next_bigger.py b/kyu_4/next_bigger_number_with_the_same_digits/test_next_bigger.py index 924c6be31c5..8f5e497334c 100644 --- a/kyu_4/next_bigger_number_with_the_same_digits/test_next_bigger.py +++ b/kyu_4/next_bigger_number_with_the_same_digits/test_next_bigger.py @@ -1,5 +1,6 @@ """ -Test for -> Next bigger number with the same digits +Test for -> Next bigger number with the same digits. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -29,12 +30,11 @@ name='Source/Kata') # pylint: enable-msg=R0801 class NextBiggerTestCase(unittest.TestCase): - """ - Testing next_bigger function - """ + """Testing next_bigger function.""" + def test_next_bigger(self): """ - Testing next_bigger function + Testing next_bigger function. You have to test a function that takes a positive integer number and returns the next bigger number formed by the same digits: @@ -43,7 +43,8 @@ def test_next_bigger(self): 513 ==> 531 2017 ==> 2071 - If no bigger number can be composed using those digits, return -1 + If no bigger number can be composed using those digits, return -1. + :return: """ # pylint: disable-msg=R0801 allure.dynamic.title("Testing next_bigger function") diff --git a/kyu_4/next_smaller_number_with_the_same_digits/__init__.py b/kyu_4/next_smaller_number_with_the_same_digits/__init__.py index e69de29bb2d..da3bbbb87c5 100644 --- a/kyu_4/next_smaller_number_with_the_same_digits/__init__.py +++ b/kyu_4/next_smaller_number_with_the_same_digits/__init__.py @@ -0,0 +1 @@ +"""Next smaller number with the same digits package.""" diff --git a/kyu_4/next_smaller_number_with_the_same_digits/next_smaller.py b/kyu_4/next_smaller_number_with_the_same_digits/next_smaller.py index a0dfe8eb090..493628defdc 100644 --- a/kyu_4/next_smaller_number_with_the_same_digits/next_smaller.py +++ b/kyu_4/next_smaller_number_with_the_same_digits/next_smaller.py @@ -1,5 +1,6 @@ """ -Solution for -> Next smaller number with the same digits +Solution for -> Next smaller number with the same digits. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -7,10 +8,13 @@ def next_smaller(n: int) -> int: """ + next_smaller function. + A function that takes a positive integer and returns the next smaller positive integer containing the same digits. - If no smaller number can be composed using those digits, return -1 + :param n: int + :return: int """ # 1 # Starting from the right, find the index of the first digit that @@ -41,7 +45,8 @@ def next_smaller(n: int) -> int: def find_x(n: int) -> int: """ - Find x + Find x. + :param n: int :return: int """ @@ -54,7 +59,8 @@ def find_x(n: int) -> int: def find_y(n: int, x_i: int) -> int: """ - Find y + Find y. + :param n: int :param x_i: int :return: int @@ -75,4 +81,4 @@ def find_y(n: int, x_i: int) -> int: if comparable_x['y'] < y: comparable_x['y'] = y comparable_x['index'] = index + x_i + 1 - return comparable_x['index'] if comparable_x['index'] else -1 + return comparable_x['index'] or -1 diff --git a/kyu_4/next_smaller_number_with_the_same_digits/test_next_smaller.py b/kyu_4/next_smaller_number_with_the_same_digits/test_next_smaller.py index 0e1ad4b4264..2bb5262c59e 100644 --- a/kyu_4/next_smaller_number_with_the_same_digits/test_next_smaller.py +++ b/kyu_4/next_smaller_number_with_the_same_digits/test_next_smaller.py @@ -1,5 +1,6 @@ """ -Test for -> Next smaller number with the same digits +Test for -> Next smaller number with the same digits. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -29,13 +30,11 @@ name='Source/Kata') # pylint: enable-msg=R0801 class NextSmallerTestCase(unittest.TestCase): - """ - Testing next_smaller function - """ + """Testing next_smaller function.""" def test_next_smaller(self): """ - Testing next_smaller function + Testing next_smaller function. You have to test a function that takes a positive integer number and returns the next smaller number formed by the same digits: @@ -45,6 +44,7 @@ def test_next_smaller(self): 2071 ==> 2017 If no smaller number can be composed using those digits, return -1 + :return: """ # pylint: disable-msg=R0801 allure.dynamic.title("Testing next_smaller function") diff --git a/kyu_4/permutations/__init__.py b/kyu_4/permutations/__init__.py index e69de29bb2d..942250b3c8e 100644 --- a/kyu_4/permutations/__init__.py +++ b/kyu_4/permutations/__init__.py @@ -0,0 +1 @@ +"""Permutations package.""" diff --git a/kyu_4/permutations/permutations.py b/kyu_4/permutations/permutations.py index 68cbdcf0c72..aab6185389c 100644 --- a/kyu_4/permutations/permutations.py +++ b/kyu_4/permutations/permutations.py @@ -1,5 +1,6 @@ """ -Solution for -. Permutations +Solution for -. Permutations. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -7,10 +8,14 @@ def permutations(string: str) -> list: """ + Permutation function. + creates all permutations of an input string and remove duplicates, if present. This means, you have to shuffle all letters from the input in all possible orders. + :param string: str + :return: list """ for strg in string: print(strg) diff --git a/kyu_4/permutations/test_permutations.py b/kyu_4/permutations/test_permutations.py index 04a4ffaecd6..b1ca433f5d4 100644 --- a/kyu_4/permutations/test_permutations.py +++ b/kyu_4/permutations/test_permutations.py @@ -1,5 +1,6 @@ """ -Solution for -. Permutations +Solution for -. Permutations. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -28,19 +29,18 @@ @pytest.mark.skip(reason="The solution is not ready") # pylint: enable-msg=R0801 class PermutationsTestCase(unittest.TestCase): - """ - Testing permutations function - """ + """Testing permutations function.""" def test_permutations(self): """ - Testing permutations function + Testing permutations function. Test that permutations function creates all permutations of an input string and remove duplicates, if present. This means, you have to shuffle all letters from the input in all possible orders. + :return: """ # pylint: disable-msg=R0801 allure.dynamic.title("Testing permutations function") diff --git a/kyu_4/range_extraction/__init__.py b/kyu_4/range_extraction/__init__.py index e69de29bb2d..732db55fa77 100644 --- a/kyu_4/range_extraction/__init__.py +++ b/kyu_4/range_extraction/__init__.py @@ -0,0 +1 @@ +"""Range Extraction package.""" diff --git a/kyu_4/range_extraction/solution.py b/kyu_4/range_extraction/solution.py index 6fc40883d8e..b39d66d20b0 100644 --- a/kyu_4/range_extraction/solution.py +++ b/kyu_4/range_extraction/solution.py @@ -1,5 +1,6 @@ """ -Solution for -> Range Extraction +Solution for -> Range Extraction. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -7,10 +8,12 @@ def solution(args: list) -> str: """ + Solution for Range Extraction problem. + Tt takes a list of integers in increasing order and returns a correctly formatted string in the range format. - :param args: - :return: + :param args: list + :return: str """ current: list = [args[0], args[0], False] result: str = '' @@ -35,30 +38,34 @@ def solution(args: list) -> str: return result -def case_3(a: int, current: list, result: str) -> str: +def case_3(a: int, + current: list, + result: str) -> str: """ - Case #3 - :param a: - :param current: - :param result: - :return: + Case #3. + + :param a: int + :param current: list + :param result: str + :return: str """ if current[1] + 1 == a: current[1] = a result += str(current[0]) if abs(current[1] - current[0]) >= 2: - result += '-' + str(current[1]) + result += f'-{str(current[1])}' elif current[0] != current[1]: - result += ',' + str(current[1]) + result += f',{str(current[1])}' return result def case_2(**kwargs) -> str: """ - Case #2 - :return: + Case #2. + + :return: str """ a: int = kwargs['a'] i: int = kwargs['i'] @@ -72,11 +79,11 @@ def case_2(**kwargs) -> str: current[2] = True if abs(current[1] - current[0]) >= 2 and i != 1: - result += str(current[0]) + '-' + str(current[1]) + ',' + result += f'{str(current[0])}-{str(current[1])},' else: - result += str(current[0]) + ',' + result += f'{str(current[0])},' if current[0] != current[1]: - result += str(current[1]) + ',' + result += f'{str(current[1])},' current[0] = a current[1] = a diff --git a/kyu_4/range_extraction/test_solution.py b/kyu_4/range_extraction/test_solution.py index e7ee7fc8465..1827b11888c 100644 --- a/kyu_4/range_extraction/test_solution.py +++ b/kyu_4/range_extraction/test_solution.py @@ -1,5 +1,6 @@ """ -Test for -> Range Extraction +Test for -> Range Extraction. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -27,13 +28,13 @@ @allure.link(url='https://www.codewars.com/kata/51ba717bb08c1cd60f00002f', name='Source/Kata') class SolutionTestCase(unittest.TestCase): - """ - Testing solution for Range Extraction problem - """ + """Testing solution for Range Extraction problem.""" def test_solution(self): """ - Testing solution function + Testing solution function. + + :return: """ allure.dynamic.title("Testing solution function") allure.dynamic.severity(allure.severity_level.NORMAL) diff --git a/kyu_4/snail/__init__.py b/kyu_4/snail/__init__.py index e69de29bb2d..6ececdca848 100644 --- a/kyu_4/snail/__init__.py +++ b/kyu_4/snail/__init__.py @@ -0,0 +1 @@ +"""Snail Sort package.""" diff --git a/kyu_4/snail/snail_sort.py b/kyu_4/snail/snail_sort.py index 34f614c1144..9c8c0f73125 100644 --- a/kyu_4/snail/snail_sort.py +++ b/kyu_4/snail/snail_sort.py @@ -1,5 +1,5 @@ """ -Solution for -> Snail +Solution for -> Snail. Returns the array elements arranged from outermost elements to the middle element, traveling clockwise. @@ -11,6 +11,8 @@ def snail(snail_map: list) -> list: """ + Snail function. + Returns the array elements arranged from outermost elements to the middle element, traveling clockwise. diff --git a/kyu_4/snail/test_snail.py b/kyu_4/snail/test_snail.py index 4e92c26f8b3..ef6002302f3 100644 --- a/kyu_4/snail/test_snail.py +++ b/kyu_4/snail/test_snail.py @@ -1,5 +1,5 @@ """ -Test for -> Snail +Test for -> Snail. Returns the array elements arranged from outermost elements to the middle element, traveling clockwise. @@ -28,17 +28,16 @@ @allure.link(url='https://www.codewars.com/kata/521c2db8ddc89b9b7a0000c1', name='Source/Kata') class SnailTestCase(unittest.TestCase): - """ - Testing snail function - """ + """Testing snail function.""" def test_snail(self): """ - Testing 'snail' function + Testing 'snail' function. Given an n x n array, 'snail' function should return the array elements arranged from outermost elements to the middle element, traveling clockwise. + :return: """ # pylint: disable-msg=R0801 allure.dynamic.title("Testing 'snail' function") diff --git a/kyu_4/strings_mix/README.md b/kyu_4/strings_mix/README.md index c09c168468d..0904770cf61 100644 --- a/kyu_4/strings_mix/README.md +++ b/kyu_4/strings_mix/README.md @@ -1,8 +1,8 @@ # Strings Mix -Given two strings `s1` and `s2`, we want to visualize how different the +****Given two strings `s1` and `s2`, we want to visualize how different the two strings are. We will only take into account the lowercase letters -(a to z). First let us count the frequency of each lowercase letters in +(a to z). Fir****st let us count the frequency of each lowercase letters in `s1` and `s2`. ```text diff --git a/kyu_4/strings_mix/__init__.py b/kyu_4/strings_mix/__init__.py index e69de29bb2d..19cbec43a11 100644 --- a/kyu_4/strings_mix/__init__.py +++ b/kyu_4/strings_mix/__init__.py @@ -0,0 +1 @@ +"""Strings Mix package.""" diff --git a/kyu_4/strings_mix/solution.py b/kyu_4/strings_mix/solution.py index a73966a0bfa..589f0eb6432 100644 --- a/kyu_4/strings_mix/solution.py +++ b/kyu_4/strings_mix/solution.py @@ -1,5 +1,6 @@ """ -Solution for -> Strings Mix +Solution for -> Strings Mix. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -11,6 +12,8 @@ def mix(s1: str, s2: str) -> str: """ + Mix function. + Given two strings s1 and s2, we want to visualize how different the two strings are. We will only take into account the lowercase letters (a to z). @@ -48,6 +51,8 @@ def mix(s1: str, s2: str) -> str: def sort_results(results: list) -> list: """ + Sorting results function. + The results will be in decreasing order of their length and when they have the same length sorted in ascending lexicographic order (letters and digits - more precisely @@ -76,7 +81,8 @@ def sort_results(results: list) -> list: def get_counters(s: str) -> dict: """ - Get counters + Get counters. + :param s: str :return: dict """ diff --git a/kyu_4/strings_mix/test_mix.py b/kyu_4/strings_mix/test_mix.py index dec95adf8cd..5a441503863 100644 --- a/kyu_4/strings_mix/test_mix.py +++ b/kyu_4/strings_mix/test_mix.py @@ -1,5 +1,6 @@ """ -Test for -> Strings Mix +Test for -> Strings Mix. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -24,12 +25,11 @@ url='https://www.codewars.com/kata/5629db57620258aa9d000014', name='Source/Kata') class MixTestCase(unittest.TestCase): - """ - Testing solution for Strings Mix problem - """ + """Testing solution for Strings Mix problem.""" + def test_smix(self): """ - Testing 'mix' function + Testing 'mix' function. Given two strings s1 and s2, the 'mix' function should visualize how different the two strings are. diff --git a/kyu_4/strip_comments/__init__.py b/kyu_4/strip_comments/__init__.py index e69de29bb2d..62779246461 100644 --- a/kyu_4/strip_comments/__init__.py +++ b/kyu_4/strip_comments/__init__.py @@ -0,0 +1 @@ +"""Strip Comments package.""" diff --git a/kyu_4/strip_comments/solution.py b/kyu_4/strip_comments/solution.py index 6a3b065b3f5..7d7fac4512a 100644 --- a/kyu_4/strip_comments/solution.py +++ b/kyu_4/strip_comments/solution.py @@ -1,5 +1,6 @@ """ -Solution for -> Strip Comments +Solution for -> Strip Comments. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -7,6 +8,8 @@ def solution(string: str, markers: list) -> str: """ + Strip comments solution. + The solution strips all text that follows any of a set of comment markers passed in. Any whitespace at the end of the line will be stripped out as well. diff --git a/kyu_4/strip_comments/test_solution.py b/kyu_4/strip_comments/test_solution.py index 68e78a365c7..20f5ab69343 100644 --- a/kyu_4/strip_comments/test_solution.py +++ b/kyu_4/strip_comments/test_solution.py @@ -1,5 +1,6 @@ """ -Test for -> Strip Comments +Test for -> Strip Comments. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -23,17 +24,16 @@ @allure.link(url='https://www.codewars.com/kata/51c8e37cee245da6b40000bd', name='Source/Kata') class SolutionTestCase(unittest.TestCase): - """ - Testing solution for Strip Comments problem - """ + """Testing solution for Strip Comments problem.""" def test_solution(self): """ - Testing 'solution' function + Testing 'solution' function. The solution should strips all text that follows any of a set of comment markers passed in. Any whitespace at the end of the line should also be stripped out. + :return: """ # pylint: disable-msg=R0801 allure.dynamic.title("Testing 'solution' function") diff --git a/kyu_4/sudoku_solution_validator/__init__.py b/kyu_4/sudoku_solution_validator/__init__.py index e69de29bb2d..c5bdd87d16e 100644 --- a/kyu_4/sudoku_solution_validator/__init__.py +++ b/kyu_4/sudoku_solution_validator/__init__.py @@ -0,0 +1 @@ +"""Sudoku Solution Validator package.""" diff --git a/kyu_4/sudoku_solution_validator/test_valid_solution.py b/kyu_4/sudoku_solution_validator/test_valid_solution.py index a0c08843d60..65e27d6b58b 100644 --- a/kyu_4/sudoku_solution_validator/test_valid_solution.py +++ b/kyu_4/sudoku_solution_validator/test_valid_solution.py @@ -1,5 +1,6 @@ """ -Test for -> Sudoku Solution Validator +Test for -> Sudoku Solution Validator. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -24,12 +25,12 @@ @allure.link(url='https://www.codewars.com/kata/529bf0e9bdf7657179000008', name='Source/Kata') class ValidSolutionTestCase(unittest.TestCase): - """ - Testing validSolution function - """ + """Testing validSolution function.""" def test_valid_solution(self): """ + Test valid_solution function. + Test a function validSolution/ValidateSolution/valid_solution() that accepts a 2D array representing a Sudoku board, and returns true if it is a valid solution, or false otherwise. The cells of @@ -42,7 +43,7 @@ def test_valid_solution(self): :return: """ # pylint: disable-msg=R0801 - allure.dynamic.title("Testing validSolution") + allure.dynamic.title("Testing valid_solution") allure.dynamic.severity(allure.severity_level.NORMAL) allure.dynamic.description_html( '

Codewars badge:

' diff --git a/kyu_4/sudoku_solution_validator/valid_solution.py b/kyu_4/sudoku_solution_validator/valid_solution.py index 64530a3a2cc..e4c27c50b56 100644 --- a/kyu_4/sudoku_solution_validator/valid_solution.py +++ b/kyu_4/sudoku_solution_validator/valid_solution.py @@ -1,5 +1,6 @@ """ -Solution for -> Sudoku Solution Validator +Solution for -> Sudoku Solution Validator. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -7,11 +8,12 @@ def valid_solution(board: list) -> bool: """ - A function validSolution/ValidateSolution/valid_solution() - that accepts a 2D array representing a Sudoku board, - and returns true if it is a valid solution, or false otherwise - :param board: - :return: + Sudoku solution validator. + + A function that accepts a 2D array representing a Sudoku board, + and returns true if it is a valid solution, or false otherwise. + :param board: list + :return: bool """ return all([check_horizontally(board), check_vertically(board), @@ -20,9 +22,10 @@ def valid_solution(board: list) -> bool: def check_horizontally(board: list) -> bool: """ - test horizontally - :param board: - :return: + Test horizontally. + + :param board: list + :return: bool """ for row in board: if sorted(row) != [1, 2, 3, 4, 5, 6, 7, 8, 9]: @@ -32,14 +35,14 @@ def check_horizontally(board: list) -> bool: def check_vertically(board: list) -> bool: """ - test vertically + Test vertically. + :param board: :return: """ i: int = 0 - while i < 9: - col = [] + col: list = [] for row in board: col.append(row[i]) if sorted(col) != [1, 2, 3, 4, 5, 6, 7, 8, 9]: @@ -50,21 +53,22 @@ def check_vertically(board: list) -> bool: def check_sub_grids(board: list) -> bool: """ - test each of the nine 3x3 sub-grids + Test each of the nine 3x3 sub-grids. + (also known as blocks) - :param board: - :return: + :param board: list + :return: bool """ sub_grids: list = [ - board[0][0:3] + board[1][0:3] + board[2][0:3], + board[0][:3] + board[1][:3] + board[2][:3], board[0][3:6] + board[1][3:6] + board[2][3:6], board[0][6:] + board[1][6:] + board[2][6:], - board[3][0:3] + board[4][0:3] + board[5][0:3], + board[3][:3] + board[4][:3] + board[5][:3], board[3][3:6] + board[4][3:6] + board[5][3:6], board[3][6:] + board[4][6:] + board[5][6:], - board[6][0:3] + board[7][0:3] + board[8][0:3], + board[6][:3] + board[7][:3] + board[8][:3], board[6][3:6] + board[7][3:6] + board[8][3:6], board[6][6:] + board[7][6:] + board[8][6:], ] diff --git a/kyu_4/sum_by_factors/__init__.py b/kyu_4/sum_by_factors/__init__.py index e69de29bb2d..e426b1ef6d1 100644 --- a/kyu_4/sum_by_factors/__init__.py +++ b/kyu_4/sum_by_factors/__init__.py @@ -0,0 +1 @@ +"""Sum by Factors package.""" diff --git a/kyu_4/sum_by_factors/sum_for_list.py b/kyu_4/sum_by_factors/sum_for_list.py index c5669a25289..523d0b93569 100644 --- a/kyu_4/sum_by_factors/sum_for_list.py +++ b/kyu_4/sum_by_factors/sum_for_list.py @@ -1,5 +1,6 @@ """ -Solution for -> sum_for_list function +Solution for -> sum_for_list function. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -9,7 +10,9 @@ def sum_for_list(lst: list) -> list: """ - Given an array of positive or negative integers I= [i1,..,in] + Sorting an array by increasing order. + + Given an array of positive or negative integers I= [i1,...,in] the function have to produce a sorted array P of the form: [ [p, sum of all ij of I for which p is a prime factor (p positive) of ij] ...] @@ -39,12 +42,12 @@ def sum_for_list(lst: list) -> list: m = -1 if digit % (prime * m) == 0: - if len(temp) == 0: + if not temp: temp.append(prime) sum_digits += digit # add result in case prime in temp list - if len(temp) > 0: + if temp: temp.append(sum_digits) results.append(temp) diff --git a/kyu_4/sum_by_factors/test_sum_for_list.py b/kyu_4/sum_by_factors/test_sum_for_list.py index ca05d5c0615..bd31fdc46dd 100644 --- a/kyu_4/sum_by_factors/test_sum_for_list.py +++ b/kyu_4/sum_by_factors/test_sum_for_list.py @@ -1,5 +1,6 @@ """ -Testing sum_for_list function +Testing sum_for_list function. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -25,13 +26,12 @@ url='https://www.codewars.com/kata/54d496788776e49e6b00052f', name='Source/Kata') class SumForListTestCase(unittest.TestCase): - """ - Testing sum_for_list function - """ + """Testing sum_for_list function.""" def test_sum_for_list(self): """ - Testing sum_for_list function + Testing sum_for_list function. + :return: """ # pylint: disable-msg=R0801 diff --git a/kyu_4/sum_of_intervals/__init__.py b/kyu_4/sum_of_intervals/__init__.py index e69de29bb2d..bf777c72502 100644 --- a/kyu_4/sum_of_intervals/__init__.py +++ b/kyu_4/sum_of_intervals/__init__.py @@ -0,0 +1 @@ +"""Sum of Intervals package.""" diff --git a/kyu_4/sum_of_intervals/sum_of_intervals.py b/kyu_4/sum_of_intervals/sum_of_intervals.py index 0130532696e..25693462476 100644 --- a/kyu_4/sum_of_intervals/sum_of_intervals.py +++ b/kyu_4/sum_of_intervals/sum_of_intervals.py @@ -1,5 +1,6 @@ """ -Solution for -> Sum of Intervals +Solution for -> Sum of Intervals. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -7,34 +8,30 @@ def sum_of_intervals(intervals: list) -> int: """ - Accepts an array of intervals, and returns - the sum of all the interval lengths. + Sum of intervals. + Accept an array of intervals, and returns + the sum of all the interval lengths. Overlapping intervals should only be counted once. - :param intervals: - :return: + :param intervals: list + :return: int """ - intervals = remove_overlaps(intervals) - results: list = [] - - for i in intervals: - results.append(i[1] - i[0]) - + results: list = [(i[1] - i[0]) for i in intervals] return sum(results) def remove_overlaps(intervals: list) -> list: """ - Remove overlaps and duplicates - :param intervals: - :return: + Remove overlaps and duplicates. + + :param intervals: list + :return: int """ is_clean: bool = False while not is_clean: is_clean = True - for index_i, i in enumerate(intervals): for index_b, b in enumerate(intervals): if index_b != index_i: @@ -45,13 +42,16 @@ def remove_overlaps(intervals: list) -> list: return intervals -def clean_interval(intervals, i, b) -> bool: +def clean_interval(intervals: list, + i: tuple, + b: tuple) -> bool: """ - Remove intervals - :param intervals: - :param i: - :param b: - :return: + Remove intervals. + + :param intervals: list + :param i: tuple + :param b: tuple + :return: bool """ result: bool = True diff --git a/kyu_4/sum_of_intervals/test_sum_of_intervals.py b/kyu_4/sum_of_intervals/test_sum_of_intervals.py index 29d7c9e6923..fe9253cf5c1 100644 --- a/kyu_4/sum_of_intervals/test_sum_of_intervals.py +++ b/kyu_4/sum_of_intervals/test_sum_of_intervals.py @@ -1,5 +1,6 @@ """ -Test for -> Sum of Intervals +Test for -> Sum of Intervals. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -27,13 +28,11 @@ @allure.link(url='https://www.codewars.com/kata/52b7ed099cdc285c300001cd', name='Source/Kata') class SumOfIntervalsTestCase(unittest.TestCase): - """ - Testing sum_of_intervals function - """ + """Testing sum_of_intervals function.""" def test_sum_of_intervals(self): """ - Testing sum_of_intervals function + Testing sum_of_intervals function. The function should accept an array of intervals, and return the sum of all the interval lengths. diff --git a/kyu_4/the_greatest_warrior/__init__.py b/kyu_4/the_greatest_warrior/__init__.py index e69de29bb2d..68f8ffb6c20 100644 --- a/kyu_4/the_greatest_warrior/__init__.py +++ b/kyu_4/the_greatest_warrior/__init__.py @@ -0,0 +1 @@ +"""The Greatest Warrior package.""" diff --git a/kyu_4/the_greatest_warrior/test_battle.py b/kyu_4/the_greatest_warrior/test_battle.py index 811d30edc09..79ed0ac0e66 100644 --- a/kyu_4/the_greatest_warrior/test_battle.py +++ b/kyu_4/the_greatest_warrior/test_battle.py @@ -1,5 +1,6 @@ """ -Test for -> The Greatest Warrior -> test battle +Test for -> The Greatest Warrior -> test battle. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -30,13 +31,13 @@ name='Source/Kata') # pylint: enable-msg=R0801 class BattleTestCase(unittest.TestCase): - """ - Testing Battle method - """ + """Testing Battle method.""" def test_battle(self): """ - Testing Battle method + Testing Battle method with various test data. + + :return: """ # pylint: disable-msg=R0801 allure.dynamic.title("Testing Battle method") diff --git a/kyu_4/the_greatest_warrior/test_warrior.py b/kyu_4/the_greatest_warrior/test_warrior.py index c4256f1c0b0..73d0eb446ca 100644 --- a/kyu_4/the_greatest_warrior/test_warrior.py +++ b/kyu_4/the_greatest_warrior/test_warrior.py @@ -1,5 +1,6 @@ """ -Test for -> The Greatest Warrior -> test warrior +Test for -> The Greatest Warrior -> test warrior. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -31,13 +32,13 @@ name='Source/Kata') # pylint: enable-msg=R0801 class WarriorTestCase(unittest.TestCase): - """ - Testing Warrior class - """ + """Testing Warrior class.""" def test_warrior_tom(self): """ - Testing Warrior class >>> tom + Testing Warrior class >>> tom. + + :return: """ # pylint: disable=R0801 allure.dynamic.title("Testing Warrior class >>> tom") @@ -66,7 +67,9 @@ def test_warrior_tom(self): def test_warrior_bruce_lee(self): """ - Testing Warrior class >>> bruce_lee + Testing Warrior class >>> bruce_lee. + + :return: """ # pylint: disable=R0801 allure.dynamic.title("Testing Warrior class >>> bruce_lee") diff --git a/kyu_4/the_greatest_warrior/warrior.py b/kyu_4/the_greatest_warrior/warrior.py index f225b1c8666..8189a410d56 100644 --- a/kyu_4/the_greatest_warrior/warrior.py +++ b/kyu_4/the_greatest_warrior/warrior.py @@ -1,5 +1,6 @@ """ -Solution for -> The Greatest Warrior +Solution for -> The Greatest Warrior. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -31,11 +32,14 @@ class Warrior: """ + Warrior class. + A class called Warrior which calculates and keeps track of level and skills, and ranks. """ def __init__(self): + """Create a new warrior instance.""" # A warrior's experience starts from 100 self.__experience = BASIC_EXPERIENCE # A warrior starts at level 1 @@ -47,12 +51,16 @@ def __init__(self): def __set_rank(self) -> str: """ + Set rank. + :return: warrior's experience """ return RANKS[(self.level // 10)] def __set_level(self) -> int: """ + Set level. + A warrior starts at level 1 and can progress all the way to 100. @@ -62,23 +70,23 @@ def __set_level(self) -> int: by another 100, the warrior's level rises to the next level. - :return: + :return: int """ new_level = self.experience // BASIC_EXPERIENCE return new_level if new_level <= 100 else 100 - def __update_experience(self, experience: int): + def __update_experience(self, experience: int) -> None: """ + Update experience. + A warrior's experience is cumulative, and does not reset with each rise of level. The only exception is when the warrior reaches level 100, with which the experience stops at 10000. :return: """ - - if self.level == 100: - self.__experience = MAX_EXPERIENCE - elif self.experience + experience > MAX_EXPERIENCE: + if (self.level == 100 + or self.experience + experience > MAX_EXPERIENCE): self.__experience = MAX_EXPERIENCE else: self.__experience += experience @@ -89,7 +97,8 @@ def __update_experience(self, experience: int): @property def level(self) -> int: """ - A warrior's level + A warrior's level. + :return: A warrior's level """ return self.__level @@ -97,8 +106,11 @@ def level(self) -> int: @property def rank(self) -> str: """ + Rank. + A warrior starts at rank "Pushover" and - can progress all the way to "Greatest" + can progress all the way to "Greatest". + :return: warrior's rank """ return self.__rank @@ -106,24 +118,27 @@ def rank(self) -> str: @property def experience(self) -> int: """ - Return experience value - :return: + Return experience value. + + :return: int """ return self.__experience @property def achievements(self) -> list: """ - Return achievements as a list - :return: + Return achievements as a list. + + :return: list """ return self.__achievements def battle(self, enemy_level: int) -> str: """ - Return message based on the result of the battle - :param enemy_level: - :return: + Return message based on the result of the battle. + + :param enemy_level: int + :return: str """ msg: str = '' # If an enemy level does not fall in the range of 1 to 100, @@ -161,13 +176,15 @@ def battle(self, enemy_level: int) -> str: def training(self, params: list) -> str: """ + Training method. + Training will accept an array of three elements: - the description, - the experience points your warrior earns, - and the minimum level requirement. + 1. the description. + 2. the experience points your warrior earns. + 3. the minimum level requirement. - :param params: - :return: + :param params: list + :return: str """ # If the warrior's level meets the minimum level requirement, # the warrior will receive the experience points from it and diff --git a/kyu_4/validate_sudoku_with_size/__init__.py b/kyu_4/validate_sudoku_with_size/__init__.py index e69de29bb2d..e73604e7e84 100644 --- a/kyu_4/validate_sudoku_with_size/__init__.py +++ b/kyu_4/validate_sudoku_with_size/__init__.py @@ -0,0 +1 @@ +"""Validate Sudoku with size `NxN` package.""" diff --git a/kyu_4/validate_sudoku_with_size/sudoku.py b/kyu_4/validate_sudoku_with_size/sudoku.py index 690964f1d95..c93abcb06f9 100644 --- a/kyu_4/validate_sudoku_with_size/sudoku.py +++ b/kyu_4/validate_sudoku_with_size/sudoku.py @@ -1,5 +1,6 @@ """ -Solution for -> Validate Sudoku with size `NxN` +Solution for -> Validate Sudoku with size `NxN`. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -15,16 +16,25 @@ class Sudoku: """ + Sudoku class. + Given a Sudoku data structure with size `NxN, N > 0 and √N == integer`, write a method to validate if it has been filled out correctly. """ def __init__(self, data: list): + """ + Create a new Sudoku instance. + + :param data: + """ self.__data: list = data def is_valid(self) -> bool: """ + Sudoku validator. + A method to validate if given a Sudoku has been filled out correctly. Sudoku -> data structure with size NxN, N > 0 and √N == integer. :return: bool @@ -34,22 +44,22 @@ def is_valid(self) -> bool: or not assert_sudoku_by_column(self.__data): return False - if len(self.__data) > 1: - if not assert_sudoku_by_region(self.__data): - return False + if len(self.__data) > 1 and not assert_sudoku_by_region(self.__data): + return False return True def is_data_valid(self) -> bool: """ - Verify data validity + Verify data validity. + :return: bool """ if not self.__data: return False - if len(self.__data) == 1: - if self.__data[0][0] != 1 or isinstance(self.__data[0][0], bool): - return False + if (len(self.__data) == 1 and + (self.__data[0][0] != 1 or isinstance(self.__data[0][0], bool))): + return False return isinstance(self.__data, list) diff --git a/kyu_4/validate_sudoku_with_size/test_sudoku.py b/kyu_4/validate_sudoku_with_size/test_sudoku.py index 7f4ad1a461d..e1967c1b7dc 100644 --- a/kyu_4/validate_sudoku_with_size/test_sudoku.py +++ b/kyu_4/validate_sudoku_with_size/test_sudoku.py @@ -1,5 +1,6 @@ """ -Test for -> Validate Sudoku with size `NxN` +Test for -> Validate Sudoku with size `NxN`. + Created by Egor Kostan. GitHub: https://github.com/ikostan """ @@ -27,13 +28,11 @@ url='https://www.codewars.com/kata/540afbe2dc9f615d5e000425', name='Source/Kata') class SudokuTestCase(unittest.TestCase): - """ - Testing Sudoku class - """ + """Testing Sudoku class.""" def test_sudoku_class(self): """ - Testing Sudoku class + Testing Sudoku class. Given a Sudoku data structure with size NxN, N > 0 and √N == integer, assert a method that validates if it has been filled out correctly. @@ -160,7 +159,8 @@ def test_sudoku_class(self): [7, 8, 9, 1, 2, 3, 4, 5, 6], [8, 9, 7, 2, 3, 1, 5, 6, 4], [9, 7, 8, 3, 1, 2, 6, 4, 5]], - False, 'Sudoku with invalid boxes (little squares), but valid rows and columns')) + False, 'Sudoku with invalid boxes (little squares),' + 'but valid rows and columns')) for data, expected, message in test_data: with allure.step("Enter a Sudoku solution and verify if it a valid one."):