Skip to content
This repository was archived by the owner on Jul 2, 2024. It is now read-only.

Commit 78e4d6f

Browse files
authored
[Release] 2024.01.1 (#129)
2 parents 4e056d7 + 7badc13 commit 78e4d6f

File tree

14 files changed

+387
-282
lines changed

14 files changed

+387
-282
lines changed

.github/workflows/linter.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,7 @@ jobs:
2323
run: |
2424
python -m pip install --upgrade pip
2525
pip install tox tox-gh-actions
26-
- name: Run tox
26+
- name: Run pylint
2727
run: tox -e pylint
28+
- name: Run flake8
29+
run: tox -e flake8

README.rst

+3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ To do this use commands:
5454
pip install -r requirements.txt
5555
pip install -e .
5656
57+
Sometimes, you may get an error while installing the source code. Upgrading
58+
``pip`` to the latest version helps for the most of the times.
59+
5760
.. _pip: https://pip.pypa.io/
5861

5962
Code health check

poetry.lock

+274-239
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+10-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
44

55
[tool.poetry]
66
name = "problem-sets"
7-
version = "2023.10.2"
7+
version = "2024.01.1"
88
description = "Challenges and solutions for the Python training course"
99
license = "MIT"
1010
authors = [
@@ -58,6 +58,7 @@ pytest-cov = "^4.0.0"
5858
mypy = "^1.2.0"
5959
pylint = "^2.17.2"
6060
tox = "^4.4.12"
61+
flake8 = "^7.0.0"
6162

6263
[tool.poetry.scripts]
6364
wtk = "wtk.__main__:run"
@@ -100,14 +101,14 @@ max-nested-blocks = 3
100101
legacy_tox_ini = """
101102
[tox]
102103
minversion = 4.0
103-
envlist = py39, py310, py311, mypy, pylint
104+
envlist = py39, py310, py311, mypy, pylint, flake8
104105
isolated_build = true
105106
skip_missing_interpreters = true
106107
107108
[gh-actions]
108109
python =
109110
3.9: py39
110-
3.10: py310, mypy, pylint
111+
3.10: py310, mypy, pylint, flake8
111112
3.11: py311
112113
113114
[testenv]
@@ -128,4 +129,10 @@ deps =
128129
pylint
129130
commands =
130131
pylint src
132+
133+
[testenv:flake8]
134+
deps =
135+
flake8
136+
commands =
137+
flake8 src
131138
"""

requirements.txt

+1-28
Original file line numberDiff line numberDiff line change
@@ -1,28 +1 @@
1-
astroid==2.15.8
2-
cachetools==5.3.1
3-
chardet==5.2.0
4-
colorama==0.4.6
5-
coverage==7.3.2
6-
dill==0.3.7
7-
distlib==0.3.7
8-
exceptiongroup==1.1.3
9-
filelock==3.12.4
10-
iniconfig==2.0.0
11-
isort==5.12.0
12-
lazy-object-proxy==1.9.0
13-
mccabe==0.7.0
14-
mypy==1.6.0
15-
mypy-extensions==1.0.0
16-
packaging==23.2
17-
platformdirs==3.11.0
18-
pluggy==1.3.0
19-
pylint==2.17.7
20-
pyproject-api==1.6.1
21-
pytest==7.4.2
22-
pytest-cov==4.1.0
23-
tomli==2.0.1
24-
tomlkit==0.12.1
25-
tox==4.11.3
26-
typing_extensions==4.8.0
27-
virtualenv==20.24.5
28-
wrapt==1.15.0
1+

src/atm/func.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def withdraw_rev(target: int,
8686
8787
"""
8888

89-
raise NotImplementedError # TODO:
89+
raise NotImplementedError
9090

9191

9292
def get_total(values: Iterable[Tuple[int, int]]) -> int:

src/calc/__init__.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""
66

77
__all__ = [
8+
"get_digits_multiplies",
89
"get_factorial",
910
"get_fibonacci_number",
1011
"get_fibonacci_number_nr",
@@ -13,6 +14,6 @@
1314
"get_squares",
1415
]
1516

16-
from calc.func import (get_factorial, get_fibonacci_number,
17-
get_fibonacci_number_nr, get_square, get_squares,
18-
get_sum_of_strings)
17+
from calc.func import (get_digits_multiplies, get_factorial,
18+
get_fibonacci_number, get_fibonacci_number_nr,
19+
get_square, get_squares, get_sum_of_strings)

src/calc/func.py

+15
Original file line numberDiff line numberDiff line change
@@ -184,3 +184,18 @@ def get_sum_of_strings(number_1: str, number_2: str, /) -> str:
184184
result += str(carry)
185185

186186
return result[::-1]
187+
188+
189+
def get_digits_multiplies(origin: int) -> List[int]:
190+
"""
191+
Return the digits multiplies for a given number
192+
193+
:param origin: a number to find multiplies
194+
:type origin: int
195+
196+
:return: a list of digits multiplies starting from position 10 ** 1
197+
:rtype: list
198+
199+
"""
200+
201+
return [int(digit) for digit in str(origin)[::-1]]

src/quiz/func.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def load_questions_from_file(source: Union[str, pathlib.Path]) -> Questions:
4343

4444
fieldnames = ["question", "options", "answer"]
4545
questions = []
46-
with open(source) as io_buff:
46+
with open(source) as io_buff: # pylint: disable=W1514
4747
reader = csv.DictReader(io_buff, fieldnames=fieldnames)
4848
for question in reader:
4949
questions.append({
@@ -64,9 +64,9 @@ def display_question(question: Question) -> None:
6464
6565
"""
6666

67-
print("%s\n" % question["question"])
67+
print("%s\n" % question["question"]) # pylint: disable=C0209
6868
for opt_idx, option in enumerate(question["options"], 1):
69-
print("%d: %s" % (opt_idx, option))
69+
print("%d: %s" % (opt_idx, option)) # pylint: disable=C0209
7070

7171

7272
def gather_answer(question: Question) -> int:

src/sequences/func.py

+27
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ def add_spaces(origin: str) -> str:
247247
return "".join(f" {c}" if c.isupper() else c for c in origin).lstrip()
248248

249249

250+
# pylint: disable=C0103
250251
def get_consecutive_slices(origin: str, n: int) -> List[str]:
251252
"""
252253
Return possible slices of string as a collection consecutive lists
@@ -301,3 +302,29 @@ def is_vowel(char: str) -> bool:
301302
vowels = "aeiouAEIOU"
302303

303304
return char in vowels
305+
306+
307+
def remove_duplicate_lists(input_list):
308+
"""
309+
Remove duplicate lists from a list of lists.
310+
311+
:param input_list: collection of nested lists
312+
:type input_list: list
313+
314+
:return: List with duplicate lists removed
315+
:rtype: list
316+
317+
"""
318+
319+
seen = set()
320+
result = []
321+
322+
for sublist in input_list:
323+
# Convert each sublist to a tuple to make it hashable
324+
sublist_tuple = tuple(sublist)
325+
326+
if sublist_tuple not in seen:
327+
seen.add(sublist_tuple)
328+
result.append(sublist)
329+
330+
return result

src/sorting/__init__.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,13 @@
6161
"heap_sort",
6262
"insertion_sort",
6363
"merge_sort",
64+
"merge_lists",
6465
"quick_sort",
6566
"radix_sort",
6667
"selection_sort",
6768
"shell_sort"
6869
]
6970

70-
from sorting.func import *
71+
from sorting.func import (bubble_sort, bucket_sort, counting_sort, heap_sort,
72+
insertion_sort, merge_lists, merge_sort, quick_sort,
73+
radix_sort, selection_sort, shell_sort)

src/wtk/enums.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def get_fight_result(attack: FightChoice, defence: FightChoice) -> FightResult:
5959

6060
# perform type validation
6161
if not isinstance(attack, FightChoice) or \
62-
not isinstance(defence, FightChoice):
62+
not isinstance(defence, FightChoice):
6363
attack_cls = attack.__class__.__name__
6464
defence_cls = defence.__class__.__name__
6565
raise TypeError(

tests/calc/func_test.py

+7
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,10 @@ def test_sum_of_strings_empty():
6666
assert calc.get_sum_of_strings("123", "") == "123"
6767
assert calc.get_sum_of_strings("", "456") == "456"
6868
assert calc.get_sum_of_strings("", "") == "0"
69+
70+
71+
def test_find_digits_multiplies():
72+
assert calc.get_digits_multiplies(123) == [3, 2, 1]
73+
assert calc.get_digits_multiplies(456) == [6, 5, 4]
74+
assert calc.get_digits_multiplies(0) == [0]
75+
assert calc.get_digits_multiplies(2048) == [8, 4, 0, 2]

tests/sequences/func_test.py

+34-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import pytest
2-
1+
import pytest
2+
from sequences.func import remove_duplicate_lists
33
import sequences
44

55

@@ -101,3 +101,35 @@ def test_is_vowel():
101101
assert sequences.is_vowel('A') is True
102102
assert sequences.is_vowel('1') is False
103103
assert sequences.is_vowel('@') is False
104+
105+
106+
def test_remove_duplicate_lists():
107+
# Test cases with duplicate lists
108+
input_list1 = [[1, 2, 3], [4, 5], [1, 2, 3], [6, 7]]
109+
expected_output1 = [[1, 2, 3], [4, 5], [6, 7]]
110+
111+
input_list2 = [['a', 'b'], [1, 2], ['a', 'b'], ['c', 'd']]
112+
expected_output2 = [['a', 'b'], [1, 2], ['c', 'd']]
113+
114+
# Test cases without duplicate lists
115+
input_list3 = [[1, 2], [3, 4], [5, 6]]
116+
expected_output3 = [[1, 2], [3, 4], [5, 6]]
117+
118+
input_list4 = [['x', 'y'], ['z'], ['p', 'q'], ['r', 's']]
119+
expected_output4 = [['x', 'y'], ['z'], ['p', 'q'], ['r', 's']]
120+
121+
# Test the function with the test cases
122+
assert remove_duplicate_lists(input_list1) == expected_output1
123+
assert remove_duplicate_lists(input_list2) == expected_output2
124+
assert remove_duplicate_lists(input_list3) == expected_output3
125+
assert remove_duplicate_lists(input_list4) == expected_output4
126+
127+
# Test with an empty list
128+
assert remove_duplicate_lists([]) == []
129+
130+
# Test with a list containing a single empty sublist
131+
input_list5 = [[]]
132+
expected_output5 = [[]]
133+
assert remove_duplicate_lists(input_list5) == expected_output5
134+
135+
# You can add more test cases as needed

0 commit comments

Comments
 (0)