Skip to content

Commit b2e30e7

Browse files
committed
2 parents 4b560a4 + 4467423 commit b2e30e7

File tree

14 files changed

+469
-199
lines changed

14 files changed

+469
-199
lines changed

Diff for: .pre-commit-config.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,20 @@ repos:
1616
- id: auto-walrus
1717

1818
- repo: https://github.com/astral-sh/ruff-pre-commit
19-
rev: v0.4.3
19+
rev: v0.4.7
2020
hooks:
2121
- id: ruff
2222
- id: ruff-format
2323

2424
- repo: https://github.com/codespell-project/codespell
25-
rev: v2.2.6
25+
rev: v2.3.0
2626
hooks:
2727
- id: codespell
2828
additional_dependencies:
2929
- tomli
3030

3131
- repo: https://github.com/tox-dev/pyproject-fmt
32-
rev: "1.8.0"
32+
rev: "2.1.3"
3333
hooks:
3434
- id: pyproject-fmt
3535

@@ -42,7 +42,7 @@ repos:
4242
pass_filenames: false
4343

4444
- repo: https://github.com/abravalheri/validate-pyproject
45-
rev: v0.16
45+
rev: v0.18
4646
hooks:
4747
- id: validate-pyproject
4848

Diff for: DIRECTORY.md

-1
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,6 @@
661661
* [Manhattan Distance](maths/manhattan_distance.py)
662662
* [Matrix Exponentiation](maths/matrix_exponentiation.py)
663663
* [Max Sum Sliding Window](maths/max_sum_sliding_window.py)
664-
* [Median Of Two Arrays](maths/median_of_two_arrays.py)
665664
* [Minkowski Distance](maths/minkowski_distance.py)
666665
* [Mobius Function](maths/mobius_function.py)
667666
* [Modular Division](maths/modular_division.py)

Diff for: backtracking/all_permutations.py

+36
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,42 @@ def create_state_space_tree(
2323
Creates a state space tree to iterate through each branch using DFS.
2424
We know that each state has exactly len(sequence) - index children.
2525
It terminates when it reaches the end of the given sequence.
26+
27+
:param sequence: The input sequence for which permutations are generated.
28+
:param current_sequence: The current permutation being built.
29+
:param index: The current index in the sequence.
30+
:param index_used: list to track which elements are used in permutation.
31+
32+
Example 1:
33+
>>> sequence = [1, 2, 3]
34+
>>> current_sequence = []
35+
>>> index_used = [False, False, False]
36+
>>> create_state_space_tree(sequence, current_sequence, 0, index_used)
37+
[1, 2, 3]
38+
[1, 3, 2]
39+
[2, 1, 3]
40+
[2, 3, 1]
41+
[3, 1, 2]
42+
[3, 2, 1]
43+
44+
Example 2:
45+
>>> sequence = ["A", "B", "C"]
46+
>>> current_sequence = []
47+
>>> index_used = [False, False, False]
48+
>>> create_state_space_tree(sequence, current_sequence, 0, index_used)
49+
['A', 'B', 'C']
50+
['A', 'C', 'B']
51+
['B', 'A', 'C']
52+
['B', 'C', 'A']
53+
['C', 'A', 'B']
54+
['C', 'B', 'A']
55+
56+
Example 3:
57+
>>> sequence = [1]
58+
>>> current_sequence = []
59+
>>> index_used = [False]
60+
>>> create_state_space_tree(sequence, current_sequence, 0, index_used)
61+
[1]
2662
"""
2763

2864
if index == len(sequence):

Diff for: backtracking/all_subsequences.py

+51-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,56 @@ def create_state_space_tree(
2222
Creates a state space tree to iterate through each branch using DFS.
2323
We know that each state has exactly two children.
2424
It terminates when it reaches the end of the given sequence.
25+
26+
:param sequence: The input sequence for which subsequences are generated.
27+
:param current_subsequence: The current subsequence being built.
28+
:param index: The current index in the sequence.
29+
30+
Example:
31+
>>> sequence = [3, 2, 1]
32+
>>> current_subsequence = []
33+
>>> create_state_space_tree(sequence, current_subsequence, 0)
34+
[]
35+
[1]
36+
[2]
37+
[2, 1]
38+
[3]
39+
[3, 1]
40+
[3, 2]
41+
[3, 2, 1]
42+
43+
>>> sequence = ["A", "B"]
44+
>>> current_subsequence = []
45+
>>> create_state_space_tree(sequence, current_subsequence, 0)
46+
[]
47+
['B']
48+
['A']
49+
['A', 'B']
50+
51+
>>> sequence = []
52+
>>> current_subsequence = []
53+
>>> create_state_space_tree(sequence, current_subsequence, 0)
54+
[]
55+
56+
>>> sequence = [1, 2, 3, 4]
57+
>>> current_subsequence = []
58+
>>> create_state_space_tree(sequence, current_subsequence, 0)
59+
[]
60+
[4]
61+
[3]
62+
[3, 4]
63+
[2]
64+
[2, 4]
65+
[2, 3]
66+
[2, 3, 4]
67+
[1]
68+
[1, 4]
69+
[1, 3]
70+
[1, 3, 4]
71+
[1, 2]
72+
[1, 2, 4]
73+
[1, 2, 3]
74+
[1, 2, 3, 4]
2575
"""
2676

2777
if index == len(sequence):
@@ -35,7 +85,7 @@ def create_state_space_tree(
3585

3686

3787
if __name__ == "__main__":
38-
seq: list[Any] = [3, 1, 2, 4]
88+
seq: list[Any] = [1, 2, 3]
3989
generate_all_subsequences(seq)
4090

4191
seq.clear()

Diff for: bit_manipulation/binary_and_operator.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def binary_and(a: int, b: int) -> str:
2626
>>> binary_and(0, 1.1)
2727
Traceback (most recent call last):
2828
...
29-
TypeError: 'float' object cannot be interpreted as an integer
29+
ValueError: Unknown format code 'b' for object of type 'float'
3030
>>> binary_and("0", "1")
3131
Traceback (most recent call last):
3232
...
@@ -35,8 +35,8 @@ def binary_and(a: int, b: int) -> str:
3535
if a < 0 or b < 0:
3636
raise ValueError("the value of both inputs must be positive")
3737

38-
a_binary = str(bin(a))[2:] # remove the leading "0b"
39-
b_binary = str(bin(b))[2:] # remove the leading "0b"
38+
a_binary = format(a, "b")
39+
b_binary = format(b, "b")
4040

4141
max_len = max(len(a_binary), len(b_binary))
4242

Diff for: data_structures/binary_tree/segment_tree.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def query_recursive(self, idx, left, right, a, b):
9898

9999
def show_data(self):
100100
show_list = []
101-
for i in range(1, N + 1):
101+
for i in range(1, self.N + 1):
102102
show_list += [self.query(i, i)]
103103
print(show_list)
104104

Diff for: divide_and_conquer/power.py

+18
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@ def actual_power(a: int, b: int):
22
"""
33
Function using divide and conquer to calculate a^b.
44
It only works for integer a,b.
5+
6+
:param a: The base of the power operation, an integer.
7+
:param b: The exponent of the power operation, a non-negative integer.
8+
:return: The result of a^b.
9+
10+
Examples:
11+
>>> actual_power(3, 2)
12+
9
13+
>>> actual_power(5, 3)
14+
125
15+
>>> actual_power(2, 5)
16+
32
17+
>>> actual_power(7, 0)
18+
1
519
"""
620
if b == 0:
721
return 1
@@ -13,6 +27,10 @@ def actual_power(a: int, b: int):
1327

1428
def power(a: int, b: int) -> float:
1529
"""
30+
:param a: The base (integer).
31+
:param b: The exponent (integer).
32+
:return: The result of a^b, as a float for negative exponents.
33+
1634
>>> power(4,6)
1735
4096
1836
>>> power(2,3)

Diff for: graphs/dijkstra_algorithm.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ def decrease_key(self, tup, new_d):
215215
[(5, 'A'), (15, 'B')]
216216
"""
217217
idx = self.pos[tup[1]]
218-
# assuming the new_d is atmost old_d
218+
# assuming the new_d is at most old_d
219219
self.array[idx] = (new_d, tup[1])
220220
while idx > 0 and self.array[self.par(idx)][0] > self.array[idx][0]:
221221
self.swap(idx, self.par(idx))

Diff for: machine_learning/loss_functions.py

+34
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,40 @@ def smooth_l1_loss(y_true: np.ndarray, y_pred: np.ndarray, beta: float = 1.0) ->
629629
return np.mean(loss)
630630

631631

632+
def kullback_leibler_divergence(y_true: np.ndarray, y_pred: np.ndarray) -> float:
633+
"""
634+
Calculate the Kullback-Leibler divergence (KL divergence) loss between true labels
635+
and predicted probabilities.
636+
637+
KL divergence loss quantifies dissimilarity between true labels and predicted
638+
probabilities. It's often used in training generative models.
639+
640+
KL = Σ(y_true * ln(y_true / y_pred))
641+
642+
Reference: https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence
643+
644+
Parameters:
645+
- y_true: True class probabilities
646+
- y_pred: Predicted class probabilities
647+
648+
>>> true_labels = np.array([0.2, 0.3, 0.5])
649+
>>> predicted_probs = np.array([0.3, 0.3, 0.4])
650+
>>> kullback_leibler_divergence(true_labels, predicted_probs)
651+
0.030478754035472025
652+
>>> true_labels = np.array([0.2, 0.3, 0.5])
653+
>>> predicted_probs = np.array([0.3, 0.3, 0.4, 0.5])
654+
>>> kullback_leibler_divergence(true_labels, predicted_probs)
655+
Traceback (most recent call last):
656+
...
657+
ValueError: Input arrays must have the same length.
658+
"""
659+
if len(y_true) != len(y_pred):
660+
raise ValueError("Input arrays must have the same length.")
661+
662+
kl_loss = y_true * np.log(y_true / y_pred)
663+
return np.sum(kl_loss)
664+
665+
632666
if __name__ == "__main__":
633667
import doctest
634668

0 commit comments

Comments
 (0)