Skip to content

Commit 987cd9d

Browse files
committed
2 parents 142cb8c + cd3e8f9 commit 987cd9d

23 files changed

+392
-178
lines changed

.github/workflows/autoblack.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ jobs:
1111
steps:
1212
- uses: actions/checkout@v1 # Use v1, NOT v2
1313
- uses: actions/setup-python@v2
14-
- run: pip install black
14+
- run: pip install black isort
1515
- run: black --check .
1616
- name: If needed, commit black changes to a new pull request
1717
if: failure()
1818
run: |
1919
black .
20+
isort --profile black --recursive .
2021
git config --global user.name github-actions
2122
git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com'
2223
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY

.github/workflows/codespell.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ jobs:
1313
SKIP="./.*,./other/dictionary.txt,./other/words,./project_euler/problem_22/p022_names.txt"
1414
codespell -L ans,fo,hist,iff,secant,tim --skip=$SKIP --quiet-level=2
1515
- name: Codespell comment
16-
if: ${{ failure() }}
17-
uses: plettich/python_codespell_action@master
16+
if: ${{ failure() }}
17+
uses: plettich/python_codespell_action@master

DIRECTORY.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@
205205
* [Max Non Adjacent Sum](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/max_non_adjacent_sum.py)
206206
* [Max Sub Array](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/max_sub_array.py)
207207
* [Max Sum Contiguous Subsequence](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/max_sum_contiguous_subsequence.py)
208+
* [Minimum Cost Path](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/minimum_cost_path.py)
208209
* [Minimum Partition](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/minimum_partition.py)
209210
* [Optimal Binary Search Tree](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/optimal_binary_search_tree.py)
210211
* [Rod Cutting](https://github.com/TheAlgorithms/Python/blob/master/dynamic_programming/rod_cutting.py)
@@ -230,11 +231,11 @@
230231
* [Articulation Points](https://github.com/TheAlgorithms/Python/blob/master/graphs/articulation_points.py)
231232
* [Basic Graphs](https://github.com/TheAlgorithms/Python/blob/master/graphs/basic_graphs.py)
232233
* [Bellman Ford](https://github.com/TheAlgorithms/Python/blob/master/graphs/bellman_ford.py)
233-
* [Bfs](https://github.com/TheAlgorithms/Python/blob/master/graphs/bfs.py)
234234
* [Bfs Shortest Path](https://github.com/TheAlgorithms/Python/blob/master/graphs/bfs_shortest_path.py)
235235
* [Bidirectional A Star](https://github.com/TheAlgorithms/Python/blob/master/graphs/bidirectional_a_star.py)
236236
* [Bidirectional Breadth First Search](https://github.com/TheAlgorithms/Python/blob/master/graphs/bidirectional_breadth_first_search.py)
237237
* [Breadth First Search](https://github.com/TheAlgorithms/Python/blob/master/graphs/breadth_first_search.py)
238+
* [Breadth First Search 2](https://github.com/TheAlgorithms/Python/blob/master/graphs/breadth_first_search_2.py)
238239
* [Breadth First Search Shortest Path](https://github.com/TheAlgorithms/Python/blob/master/graphs/breadth_first_search_shortest_path.py)
239240
* [Check Bipartite Graph Bfs](https://github.com/TheAlgorithms/Python/blob/master/graphs/check_bipartite_graph_bfs.py)
240241
* [Check Bipartite Graph Dfs](https://github.com/TheAlgorithms/Python/blob/master/graphs/check_bipartite_graph_dfs.py)
@@ -309,6 +310,7 @@
309310
* [Scoring Functions](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/scoring_functions.py)
310311
* [Sequential Minimum Optimization](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/sequential_minimum_optimization.py)
311312
* [Support Vector Machines](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/support_vector_machines.py)
313+
* [Word Frequency Functions](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/word_frequency_functions.py)
312314

313315
## Maths
314316
* [3N Plus 1](https://github.com/TheAlgorithms/Python/blob/master/maths/3n_plus_1.py)
@@ -442,7 +444,9 @@
442444
* [Integeration By Simpson Approx](https://github.com/TheAlgorithms/Python/blob/master/other/integeration_by_simpson_approx.py)
443445
* [Largest Subarray Sum](https://github.com/TheAlgorithms/Python/blob/master/other/largest_subarray_sum.py)
444446
* [Least Recently Used](https://github.com/TheAlgorithms/Python/blob/master/other/least_recently_used.py)
447+
* [Lfu Cache](https://github.com/TheAlgorithms/Python/blob/master/other/lfu_cache.py)
445448
* [Linear Congruential Generator](https://github.com/TheAlgorithms/Python/blob/master/other/linear_congruential_generator.py)
449+
* [Lru Cache](https://github.com/TheAlgorithms/Python/blob/master/other/lru_cache.py)
446450
* [Magicdiamondpattern](https://github.com/TheAlgorithms/Python/blob/master/other/magicdiamondpattern.py)
447451
* [Markov Chain](https://github.com/TheAlgorithms/Python/blob/master/other/markov_chain.py)
448452
* [Nested Brackets](https://github.com/TheAlgorithms/Python/blob/master/other/nested_brackets.py)
@@ -566,6 +570,8 @@
566570
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_40/sol1.py)
567571
* Problem 42
568572
* [Solution42](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_42/solution42.py)
573+
* Problem 47
574+
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_47/sol1.py)
569575
* Problem 48
570576
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_48/sol1.py)
571577
* Problem 52
@@ -585,7 +591,8 @@
585591

586592
## Scheduling
587593
* [First Come First Served](https://github.com/TheAlgorithms/Python/blob/master/scheduling/first_come_first_served.py)
588-
* [Shortest Job First Algorithm](https://github.com/TheAlgorithms/Python/blob/master/scheduling/shortest_job_first_algorithm.py)
594+
* [Round Robin](https://github.com/TheAlgorithms/Python/blob/master/scheduling/round_robin.py)
595+
* [Shortest Job First](https://github.com/TheAlgorithms/Python/blob/master/scheduling/shortest_job_first.py)
589596

590597
## Searches
591598
* [Binary Search](https://github.com/TheAlgorithms/Python/blob/master/searches/binary_search.py)

ciphers/affine_cipher.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,4 @@ def get_random_key():
102102
import doctest
103103

104104
doctest.testmod()
105-
main()
105+
# main()

data_structures/binary_tree/avl_tree.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,16 @@ def del_node(root, data):
204204
if root is None:
205205
return root
206206
if get_height(root.get_right()) - get_height(root.get_left()) == 2:
207-
if get_height(root.get_right().get_right()) > \
208-
get_height(root.get_right().get_left()):
207+
if get_height(root.get_right().get_right()) > get_height(
208+
root.get_right().get_left()
209+
):
209210
root = left_rotation(root)
210211
else:
211212
root = rl_rotation(root)
212213
elif get_height(root.get_right()) - get_height(root.get_left()) == -2:
213-
if get_height(root.get_left().get_left()) > \
214-
get_height(root.get_left().get_right()):
214+
if get_height(root.get_left().get_left()) > get_height(
215+
root.get_left().get_right()
216+
):
215217
root = right_rotation(root)
216218
else:
217219
root = lr_rotation(root)
@@ -253,6 +255,7 @@ class AVLtree:
253255
2 *
254256
*************************************
255257
"""
258+
256259
def __init__(self):
257260
self.root = None
258261

@@ -307,6 +310,7 @@ def __str__(self): # a level traversale, gives a more intuitive look on the tre
307310

308311
def _test():
309312
import doctest
313+
310314
doctest.testmod()
311315

312316

dynamic_programming/max_non_adjacent_sum.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Video Explaination: https://www.youtube.com/watch?v=6w60Zi1NtL8&feature=emb_logo
1+
# Video Explanation: https://www.youtube.com/watch?v=6w60Zi1NtL8&feature=emb_logo
22

33
from typing import List
44

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Youtube Explanation: https://www.youtube.com/watch?v=lBRtnuxg-gU
2+
3+
from typing import List
4+
5+
6+
def minimum_cost_path(matrix: List[List[int]]) -> int:
7+
"""
8+
Find the minimum cost traced by all possible paths from top left to bottom right in
9+
a given matrix
10+
11+
>>> minimum_cost_path([[2, 1], [3, 1], [4, 2]])
12+
6
13+
14+
>>> minimum_cost_path([[2, 1, 4], [2, 1, 3], [3, 2, 1]])
15+
7
16+
"""
17+
18+
# preprocessing the first row
19+
for i in range(1, len(matrix[0])):
20+
matrix[0][i] += matrix[0][i - 1]
21+
22+
# preprocessing the first column
23+
for i in range(1, len(matrix)):
24+
matrix[i][0] += matrix[i - 1][0]
25+
26+
# updating the path cost for current position
27+
for i in range(1, len(matrix)):
28+
for j in range(1, len(matrix[0])):
29+
matrix[i][j] += min(matrix[i - 1][j], matrix[i][j - 1])
30+
31+
return matrix[-1][-1]
32+
33+
34+
if __name__ == "__main__":
35+
import doctest
36+
37+
doctest.testmod()
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
"""
2-
BFS.
3-
2+
https://en.wikipedia.org/wiki/Breadth-first_search
43
pseudo-code:
5-
6-
BFS(graph G, start vertex s):
4+
breadth_first_search(graph G, start vertex s):
75
// all nodes initially unexplored
86
mark s as explored
97
let Q = queue data structure, initialized with s
@@ -13,9 +11,10 @@
1311
if w unexplored:
1412
mark w as explored
1513
add w to Q (at the end)
16-
1714
"""
1815

16+
from typing import Set, Dict
17+
1918
G = {
2019
"A": ["B", "C"],
2120
"B": ["A", "D", "E"],
@@ -26,13 +25,13 @@
2625
}
2726

2827

29-
def bfs(graph, start):
28+
def breadth_first_search(graph: Dict, start: str) -> Set[str]:
3029
"""
31-
>>> ''.join(sorted(bfs(G, 'A')))
30+
>>> ''.join(sorted(breadth_first_search(G, 'A')))
3231
'ABCDEF'
3332
"""
34-
explored, queue = set(), [start] # collections.deque([start])
35-
explored.add(start)
33+
explored = {start}
34+
queue = [start]
3635
while queue:
3736
v = queue.pop(0) # queue.popleft()
3837
for w in graph[v]:
@@ -43,4 +42,4 @@ def bfs(graph, start):
4342

4443

4544
if __name__ == "__main__":
46-
print(bfs(G, "A"))
45+
print(breadth_first_search(G, "A"))

graphs/connected_components.py

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,14 @@
55
66
"""
77

8-
test_graph_1 = {
9-
0: [1, 2],
10-
1: [0, 3],
11-
2: [0],
12-
3: [1],
13-
4: [5, 6],
14-
5: [4, 6],
15-
6: [4, 5],
16-
}
17-
18-
test_graph_2 = {
19-
0: [1, 2, 3],
20-
1: [0, 3],
21-
2: [0],
22-
3: [0, 1],
23-
4: [],
24-
5: [],
25-
}
8+
test_graph_1 = {0: [1, 2], 1: [0, 3], 2: [0], 3: [1], 4: [5, 6], 5: [4, 6], 6: [4, 5]}
9+
10+
test_graph_2 = {0: [1, 2, 3], 1: [0, 3], 2: [0], 3: [0, 1], 4: [], 5: []}
2611

2712

2813
def dfs(graph: dict, vert: int, visited: list) -> list:
2914
"""
30-
Use depth first search to find all vertexes
15+
Use depth first search to find all vertices
3116
being in the same component as initial vertex
3217
>>> dfs(test_graph_1, 0, 5 * [False])
3318
[0, 1, 3, 2]

graphs/gale_shapley_bigraph.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from typing import List
2+
3+
4+
def stable_matching(donor_pref: List[int], recipient_pref: List[int]) -> List[int]:
5+
"""
6+
Finds the stable match in any bipartite graph, i.e a pairing where no 2 objects
7+
prefer each other over their partner. The function accepts the preferences of
8+
oegan donors and recipients (where both are assigned numbers from 0 to n-1) and
9+
returns a list where the index position corresponds to the donor and value at the
10+
index is the organ recipient.
11+
12+
To better understand the algorithm, see also:
13+
https://github.com/akashvshroff/Gale_Shapley_Stable_Matching (README).
14+
https://www.youtube.com/watch?v=Qcv1IqHWAzg&t=13s (Numberphile YouTube).
15+
16+
>>> donor_pref = [[0, 1, 3, 2], [0, 2, 3, 1], [1, 0, 2, 3], [0, 3, 1, 2]]
17+
>>> recipient_pref = [[3, 1, 2, 0], [3, 1, 0, 2], [0, 3, 1, 2], [1, 0, 3, 2]]
18+
>>> print(stable_matching(donor_pref, recipient_pref))
19+
[1, 2, 3, 0]
20+
"""
21+
assert len(donor_pref) == len(recipient_pref)
22+
n = len(donor_pref)
23+
unmatched_donors = list(range(n))
24+
donor_record = [-1] * n # who the donor has donated to
25+
rec_record = [-1] * n # who the recipient has received from
26+
num_donations = [0] * n
27+
while unmatched_donors:
28+
donor = unmatched_donors[0]
29+
donor_preference = donor_pref[donor]
30+
recipient = donor_preference[num_donations[donor]]
31+
num_donations[donor] += 1
32+
rec_preference = recipient_pref[recipient]
33+
prev_donor = rec_record[recipient]
34+
if prev_donor != -1:
35+
if rec_preference.index(prev_donor) > rec_preference.index(donor):
36+
rec_record[recipient] = donor
37+
donor_record[donor] = recipient
38+
unmatched_donors.append(prev_donor)
39+
unmatched_donors.remove(donor)
40+
else:
41+
rec_record[recipient] = donor
42+
donor_record[donor] = recipient
43+
unmatched_donors.remove(donor)
44+
return donor_record

graphs/strongly_connected_components.py

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,9 @@
55
66
"""
77

8-
test_graph_1 = {
9-
0: [2, 3],
10-
1: [0],
11-
2: [1],
12-
3: [4],
13-
4: [],
14-
}
15-
16-
test_graph_2 = {
17-
0: [1, 2, 3],
18-
1: [2],
19-
2: [0],
20-
3: [4],
21-
4: [5],
22-
5: [3],
23-
}
8+
test_graph_1 = {0: [2, 3], 1: [0], 2: [1], 3: [4], 4: []}
9+
10+
test_graph_2 = {0: [1, 2, 3], 1: [2], 2: [0], 3: [4], 4: [5], 5: [3]}
2411

2512

2613
def topology_sort(graph: dict, vert: int, visited: list) -> list:

greedy_method/test_knapsack.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ def test_negative_profit_value(self):
3535
# profit = [10, -20, 30, 40, 50, 60]
3636
# weight = [2, 4, 6, 8, 10, 12]
3737
# max_weight = 15
38-
self.assertRaisesRegex(
39-
ValueError, "Weight can not be negative.",
40-
)
38+
self.assertRaisesRegex(ValueError, "Weight can not be negative.")
4139

4240
def test_negative_weight_value(self):
4341
"""

machine_learning/k_means_clust.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ def ReportGenerator(
250250
df["dummy"] = 1
251251
numeric_cols = df.select_dtypes(np.number).columns
252252
report = (
253-
df.groupby(["Cluster"])[ # constract report dataframe
253+
df.groupby(["Cluster"])[ # construct report dataframe
254254
numeric_cols
255255
] # group by cluster number
256256
.agg(
@@ -289,14 +289,14 @@ def ReportGenerator(
289289

290290
clustersize = report[
291291
(report["Features"] == "dummy") & (report["Type"] == "count")
292-
] # caclulating size of cluster(count of clientID's)
292+
] # calculate the size of cluster(count of clientID's)
293293
clustersize.Type = (
294294
"ClusterSize" # rename created cluster df to match report column names
295295
)
296296
clustersize.Features = "# of Customers"
297297
clusterproportion = pd.DataFrame(
298298
clustersize.iloc[:, 2:].values
299-
/ clustersize.iloc[:, 2:].values.sum() # caclulating proportion of cluster
299+
/ clustersize.iloc[:, 2:].values.sum() # calculating the proportion of cluster
300300
)
301301
clusterproportion[
302302
"Type"

0 commit comments

Comments
 (0)