Skip to content

Commit 93be74c

Browse files
Add Black formatting and pre-commit hooks to repository
Introduce Black code formatter for consistent styling across the codebase. Add GitHub Actions workflow for format validation and a pre-commit configuration for local enforcement. Update all Python files to adhere to Black formatting standards.
1 parent a02255f commit 93be74c

34 files changed

+203
-96
lines changed

.github/workflows/format-check.yml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: Format Check
2+
on: [push, pull_request]
3+
jobs:
4+
format-check:
5+
runs-on: ubuntu-latest
6+
steps:
7+
- uses: actions/checkout@v3
8+
- name: Set up Python
9+
uses: actions/setup-python@v3
10+
with:
11+
python-version: 3.9
12+
- name: Install Black
13+
run: pip install black
14+
- name: Run Black
15+
run: black --check .

.pre-commit-config.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
repos:
2+
- repo: https://github.com/psf/black
3+
rev: 23.9.1 # Use the latest stable version
4+
hooks:
5+
- id: black

Arrays & Hashing/contains_duplicate.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@
33
import unittest
44
from typing import List
55

6+
67
def has_duplicate(nums: List[int]) -> bool:
7-
seen = set()
8+
seen = set()
9+
10+
for num in nums:
11+
if num in seen:
12+
return True
813

9-
for num in nums:
10-
if num in seen:
11-
return True
14+
seen.add(num)
1215

13-
seen.add(num)
16+
return False
1417

15-
return False
1618

1719
class Test(unittest.TestCase):
1820
def test_has_duplicate(self):

Arrays & Hashing/encode_and_decode_strings.py

+12-8
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
import unittest
44
from typing import List
55

6+
67
def encode(words: List[str]) -> str:
78
encoded_words = []
89

910
for word in words:
1011
encoded_word = str(len(word)) + "#" + word
1112
encoded_words.append(encoded_word)
1213

13-
return ' '.join(encoded_words)
14+
return " ".join(encoded_words)
15+
1416

1517
def decode(encoded_words: str) -> List[str]:
1618
n = len(encoded_words)
@@ -20,7 +22,7 @@ def decode(encoded_words: str) -> List[str]:
2022
while i < n:
2123
j = i
2224
# Find the position of the next '#'
23-
while j < n and encoded_words[j] != '#':
25+
while j < n and encoded_words[j] != "#":
2426
j += 1
2527

2628
# If no '#' is found, break the loop to avoid infinite loop
@@ -39,7 +41,9 @@ def decode(encoded_words: str) -> List[str]:
3941

4042
# Check if the end of the word is within bounds
4143
if j > n:
42-
raise ValueError(f"Word length {length} is out of bounds for the string: {encoded_words[i:]}")
44+
raise ValueError(
45+
f"Word length {length} is out of bounds for the string: {encoded_words[i:]}"
46+
)
4347

4448
decoded_word = encoded_words[i:j]
4549
decoded_words.append(decoded_word)
@@ -49,16 +53,16 @@ def decode(encoded_words: str) -> List[str]:
4953

5054
return decoded_words
5155

56+
5257
class Test(unittest.TestCase):
5358
def setUp(self):
54-
self.example1 = ["neet","code","love","you"]
55-
self.example2 = ["we","say",":","yes"]
59+
self.example1 = ["neet", "code", "love", "you"]
60+
self.example2 = ["we", "say", ":", "yes"]
5661

57-
self.expected_encoding1 = '4#neet 4#code 4#love 3#you'
58-
self.expected_encoding2 = '2#we 3#say 1#: 3#yes'
62+
self.expected_encoding1 = "4#neet 4#code 4#love 3#you"
63+
self.expected_encoding2 = "2#we 3#say 1#: 3#yes"
5964

6065
def test_encode(self):
61-
6266
self.assertEqual(encode(self.example1), self.expected_encoding1)
6367
self.assertEqual(encode(self.example2), self.expected_encoding2)
6468

Arrays & Hashing/group_anagrams.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
from typing import List
55
from collections import defaultdict
66

7+
78
def group_anagrams(words: List[str]) -> List[List[str]]:
89
anagram_groups = defaultdict(list)
910

1011
for word in words:
11-
sorted_word = ''.join(sorted(word))
12+
sorted_word = "".join(sorted(word))
1213

1314
if sorted_word in anagram_groups:
1415
anagram_groups[sorted_word].append(word)
@@ -18,6 +19,7 @@ def group_anagrams(words: List[str]) -> List[List[str]]:
1819

1920
return [group for group in anagram_groups.values()]
2021

22+
2123
class Test(unittest.TestCase):
2224
def assertEqualAnagramGroups(self, result, expected):
2325
# Sort each group and the outer list
@@ -30,7 +32,7 @@ def assertEqualAnagramGroups(self, result, expected):
3032
def test_group_anagrams(self):
3133
self.assertEqualAnagramGroups(
3234
group_anagrams(["act", "pots", "tops", "cat", "stop", "hat"]),
33-
[["hat"], ["act", "cat"], ["stop", "pots", "tops"]]
35+
[["hat"], ["act", "cat"], ["stop", "pots", "tops"]],
3436
)
3537
self.assertEqualAnagramGroups(group_anagrams(["x"]), [["x"]])
3638
self.assertEqualAnagramGroups(group_anagrams([""]), [[""]])

Arrays & Hashing/longest_consecutive_sequence.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
import unittest
44
from typing import List
55

6+
67
def longest_consecutive(nums: List[int]) -> int:
78
nums_set = set(nums)
89
longest = 0
910

1011
for num in nums_set:
11-
if (num - 1) not in nums_set: # Are we are the start of a sequence?
12+
if (num - 1) not in nums_set: # Are we are the start of a sequence?
1213
length = 1
1314

1415
while (num + length) in nums_set:
@@ -18,6 +19,7 @@ def longest_consecutive(nums: List[int]) -> int:
1819

1920
return longest
2021

22+
2123
class Test(unittest.TestCase):
2224
def test_longest_consecutive(self):
2325
self.assertEqual(longest_consecutive([2, 20, 4, 10, 3, 4, 5]), 4)

Arrays & Hashing/product_of_array_except_self.py

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import unittest
44
from typing import List
55

6+
67
def product_except_self(nums: List[int]) -> List[int]:
78
n = len(nums)
89

@@ -20,6 +21,7 @@ def product_except_self(nums: List[int]) -> List[int]:
2021

2122
return result
2223

24+
2325
class Test(unittest.TestCase):
2426
def test_product_except_self(self):
2527
self.assertEqual(product_except_self([1, 2, 4, 6]), [48, 24, 12, 8])

Arrays & Hashing/top_k_frequent_elements.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# # Use heapq.nlargest to get the k elements with the highest counts
1515
# return heapq.nlargest(k, counts.keys(), key=counts.get)
1616

17+
1718
def top_k_frequent(nums: List[int], k: int) -> List[int]:
1819
n = len(nums)
1920

@@ -25,7 +26,9 @@ def top_k_frequent(nums: List[int], k: int) -> List[int]:
2526
min_heap = []
2627

2728
for num, count in counts.items():
28-
heapq.heappush(min_heap, (-count, num)) # negate the count to convert min heap to max heap
29+
heapq.heappush(
30+
min_heap, (-count, num)
31+
) # negate the count to convert min heap to max heap
2932

3033
result = []
3134

@@ -35,6 +38,7 @@ def top_k_frequent(nums: List[int], k: int) -> List[int]:
3538

3639
return result
3740

41+
3842
class Test(unittest.TestCase):
3943
def test_top_k_frequent(self):
4044
self.assertEqual(top_k_frequent([1, 2, 2, 3, 3, 3], 2), [3, 2])

Arrays & Hashing/two_sum.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,21 @@
44
from typing import List
55
from collections import defaultdict
66

7+
78
def two_sum(nums: List[int], target) -> List[int]:
89
complements = defaultdict(int)
910

1011
for i, num in enumerate(nums):
1112
complement = target - num
1213

1314
if complement in complements:
14-
return [
15-
complements[complement], i
16-
]
15+
return [complements[complement], i]
1716

1817
complements[num] = i
1918

2019
return []
2120

21+
2222
class Test(unittest.TestCase):
2323
def test_two_sum(self):
2424
self.assertEqual(two_sum([3, 4, 5, 6], 7), [0, 1])

Arrays & Hashing/vaild_anagram.py

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import unittest
44

5+
56
def is_anagram(word_one: str, word_two: str) -> bool:
67
n = len(word_one)
78
m = len(word_two)
@@ -29,6 +30,7 @@ def is_anagram(word_one: str, word_two: str) -> bool:
2930

3031
return True
3132

33+
3234
class Test(unittest.TestCase):
3335
def test_is_anagram(self):
3436
self.assertTrue(is_anagram("racecar", "carrace"))

Arrays & Hashing/valid_sudoku.py

+36-22
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import List
55
from collections import defaultdict
66

7+
78
def is_valid_sudoku(board: List[List[str]]) -> bool:
89
rows = defaultdict(set)
910
cols = defaultdict(set)
@@ -13,13 +14,13 @@ def is_valid_sudoku(board: List[List[str]]) -> bool:
1314
for col in range(9):
1415
cell = board[row][col]
1516

16-
if cell == '.': # Skip empty cells
17+
if cell == ".": # Skip empty cells
1718
continue
1819

1920
if (
20-
cell in rows[row] or
21-
cell in cols[col] or
22-
cell in squares[(row // 3, col // 3)]
21+
cell in rows[row]
22+
or cell in cols[col]
23+
or cell in squares[(row // 3, col // 3)]
2324
):
2425
return False
2526

@@ -29,23 +30,36 @@ def is_valid_sudoku(board: List[List[str]]) -> bool:
2930

3031
return True
3132

33+
3234
class Test(unittest.TestCase):
3335
def test_is_valid_sudoku(self):
34-
self.assertTrue(is_valid_sudoku([["1","2",".",".","3",".",".",".","."],
35-
["4",".",".","5",".",".",".",".","."],
36-
[".","9","8",".",".",".",".",".","3"],
37-
["5",".",".",".","6",".",".",".","4"],
38-
[".",".",".","8",".","3",".",".","5"],
39-
["7",".",".",".","2",".",".",".","6"],
40-
[".",".",".",".",".",".","2",".","."],
41-
[".",".",".","4","1","9",".",".","8"],
42-
[".",".",".",".","8",".",".","7","9"]]))
43-
self.assertFalse(is_valid_sudoku([["1","2",".",".","3",".",".",".","."],
44-
["4",".",".","5",".",".",".",".","."],
45-
[".","9","1",".",".",".",".",".","3"],
46-
["5",".",".",".","6",".",".",".","4"],
47-
[".",".",".","8",".","3",".",".","5"],
48-
["7",".",".",".","2",".",".",".","6"],
49-
[".",".",".",".",".",".","2",".","."],
50-
[".",".",".","4","1","9",".",".","8"],
51-
[".",".",".",".","8",".",".","7","9"]]))
36+
self.assertTrue(
37+
is_valid_sudoku(
38+
[
39+
["1", "2", ".", ".", "3", ".", ".", ".", "."],
40+
["4", ".", ".", "5", ".", ".", ".", ".", "."],
41+
[".", "9", "8", ".", ".", ".", ".", ".", "3"],
42+
["5", ".", ".", ".", "6", ".", ".", ".", "4"],
43+
[".", ".", ".", "8", ".", "3", ".", ".", "5"],
44+
["7", ".", ".", ".", "2", ".", ".", ".", "6"],
45+
[".", ".", ".", ".", ".", ".", "2", ".", "."],
46+
[".", ".", ".", "4", "1", "9", ".", ".", "8"],
47+
[".", ".", ".", ".", "8", ".", ".", "7", "9"],
48+
]
49+
)
50+
)
51+
self.assertFalse(
52+
is_valid_sudoku(
53+
[
54+
["1", "2", ".", ".", "3", ".", ".", ".", "."],
55+
["4", ".", ".", "5", ".", ".", ".", ".", "."],
56+
[".", "9", "1", ".", ".", ".", ".", ".", "3"],
57+
["5", ".", ".", ".", "6", ".", ".", ".", "4"],
58+
[".", ".", ".", "8", ".", "3", ".", ".", "5"],
59+
["7", ".", ".", ".", "2", ".", ".", ".", "6"],
60+
[".", ".", ".", ".", ".", ".", "2", ".", "."],
61+
[".", ".", ".", "4", "1", "9", ".", ".", "8"],
62+
[".", ".", ".", ".", "8", ".", ".", "7", "9"],
63+
]
64+
)
65+
)

Binary Search/binary_search.py

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
# # If target is not present, return -1
2121
# return -1
2222

23+
2324
def binary_search(nums: List[int], target: int) -> int:
2425
n = len(nums)
2526

@@ -39,6 +40,7 @@ def binary_search(nums: List[int], target: int) -> int:
3940

4041
return -1
4142

43+
4244
class Test(unittest.TestCase):
4345
def test_binary_search(self):
4446
self.assertEqual(binary_search([-1, 0, 2, 4, 6, 8], 4), 3)

Binary Search/koko_eating_bananas.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
import unittest
55
from typing import List
66

7+
78
def min_eating_speed(piles: List[int], hours: int) -> int:
89
piles.sort()
910

10-
left = 1
11+
left = 1
1112
right = max(piles)
1213

1314
result = right
@@ -27,6 +28,7 @@ def min_eating_speed(piles: List[int], hours: int) -> int:
2728

2829
return result
2930

31+
3032
class Test(unittest.TestCase):
3133
def test_min_eating_speed(self):
3234
self.assertEqual(min_eating_speed([1, 4, 3, 2], 9), 2)

Binary Search/search_a_2d_matrix.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
# # Check if the target is actually at the found index
2020
# return index < len(flat_list) and flat_list[index] == target
2121

22+
2223
def search_matrix(matrix: List[List[int]], target: int) -> bool:
2324
n = len(matrix)
2425
m = len(matrix[0])
@@ -45,7 +46,12 @@ def search_matrix(matrix: List[List[int]], target: int) -> bool:
4546

4647
return False
4748

49+
4850
class Test(unittest.TestCase):
4951
def test_search_matrix(self):
50-
self.assertTrue(search_matrix([[1, 2, 4, 8],[10, 11, 12, 13],[14, 20, 30, 40]], 10))
51-
self.assertFalse(search_matrix([[1, 2, 4, 8],[10, 11, 12, 13],[14, 20, 30, 40]], 15))
52+
self.assertTrue(
53+
search_matrix([[1, 2, 4, 8], [10, 11, 12, 13], [14, 20, 30, 40]], 10)
54+
)
55+
self.assertFalse(
56+
search_matrix([[1, 2, 4, 8], [10, 11, 12, 13], [14, 20, 30, 40]], 15)
57+
)

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ The repository is organized based on the categories from NeetCode's Road Map.
1313
## Prerequisites
1414

1515
- Python 3.9 or above should be installed.
16+
- Some problems may require [LeetCode Premium](https://leetcode.com/subscribe).
17+
- [Black](https://black.readthedocs.io/en/stable/) formatter should be installed to ensure consistent code formatting.
1618

1719
## Test
1820

0 commit comments

Comments
 (0)