mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-12-18 17:20:16 +00:00
Merge branch 'master' of https://github.com/MaximSmolskiy/Python
This commit is contained in:
commit
e6790b5407
|
@ -16,7 +16,7 @@ repos:
|
|||
- id: auto-walrus
|
||||
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.4.7
|
||||
rev: v0.5.7
|
||||
hooks:
|
||||
- id: ruff
|
||||
- id: ruff-format
|
||||
|
@ -29,7 +29,7 @@ repos:
|
|||
- tomli
|
||||
|
||||
- repo: https://github.com/tox-dev/pyproject-fmt
|
||||
rev: "2.1.3"
|
||||
rev: "2.2.1"
|
||||
hooks:
|
||||
- id: pyproject-fmt
|
||||
|
||||
|
@ -47,10 +47,11 @@ repos:
|
|||
- id: validate-pyproject
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.10.0
|
||||
rev: v1.11.1
|
||||
hooks:
|
||||
- id: mypy
|
||||
args:
|
||||
- --explicit-package-bases
|
||||
- --ignore-missing-imports
|
||||
- --install-types # See mirrors-mypy README.md
|
||||
- --non-interactive
|
||||
|
|
|
@ -540,8 +540,7 @@
|
|||
* [Lu Decomposition](linear_algebra/lu_decomposition.py)
|
||||
* Src
|
||||
* [Conjugate Gradient](linear_algebra/src/conjugate_gradient.py)
|
||||
* Gaussian Elimination Pivoting
|
||||
* [Gaussian Elimination Pivoting](linear_algebra/src/gaussian_elimination_pivoting/gaussian_elimination_pivoting.py)
|
||||
* [Gaussian Elimination Pivoting](linear_algebra/src/gaussian_elimination_pivoting.py)
|
||||
* [Lib](linear_algebra/src/lib.py)
|
||||
* [Polynom For Points](linear_algebra/src/polynom_for_points.py)
|
||||
* [Power Iteration](linear_algebra/src/power_iteration.py)
|
||||
|
@ -863,6 +862,7 @@
|
|||
* [Newtons Second Law Of Motion](physics/newtons_second_law_of_motion.py)
|
||||
* [Photoelectric Effect](physics/photoelectric_effect.py)
|
||||
* [Potential Energy](physics/potential_energy.py)
|
||||
* [Rainfall Intensity](physics/rainfall_intensity.py)
|
||||
* [Reynolds Number](physics/reynolds_number.py)
|
||||
* [Rms Speed Of Molecule](physics/rms_speed_of_molecule.py)
|
||||
* [Shear Stress](physics/shear_stress.py)
|
||||
|
@ -1259,6 +1259,7 @@
|
|||
* [Can String Be Rearranged As Palindrome](strings/can_string_be_rearranged_as_palindrome.py)
|
||||
* [Capitalize](strings/capitalize.py)
|
||||
* [Check Anagrams](strings/check_anagrams.py)
|
||||
* [Count Vowels](strings/count_vowels.py)
|
||||
* [Credit Card Validator](strings/credit_card_validator.py)
|
||||
* [Damerau Levenshtein Distance](strings/damerau_levenshtein_distance.py)
|
||||
* [Detecting English Programmatically](strings/detecting_english_programmatically.py)
|
||||
|
|
|
@ -24,10 +24,10 @@ def get_valid_pos(position: tuple[int, int], n: int) -> list[tuple[int, int]]:
|
|||
]
|
||||
permissible_positions = []
|
||||
|
||||
for position in positions:
|
||||
y_test, x_test = position
|
||||
for inner_position in positions:
|
||||
y_test, x_test = inner_position
|
||||
if 0 <= y_test < n and 0 <= x_test < n:
|
||||
permissible_positions.append(position)
|
||||
permissible_positions.append(inner_position)
|
||||
|
||||
return permissible_positions
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ def transform(
|
|||
|
||||
center_x, center_y = (x // 2 for x in kernel.shape)
|
||||
|
||||
# Use padded image when applying convolotion
|
||||
# Use padded image when applying convolution
|
||||
# to not go out of bounds of the original the image
|
||||
transformed = np.zeros(image.shape, dtype=np.uint8)
|
||||
padded = np.pad(image, 1, "constant", constant_values=constant)
|
||||
|
|
|
@ -297,6 +297,12 @@ def weight_conversion(from_type: str, to_type: str, value: float) -> float:
|
|||
1.660540199e-23
|
||||
>>> weight_conversion("atomic-mass-unit","atomic-mass-unit",2)
|
||||
1.999999998903455
|
||||
>>> weight_conversion("slug", "kilogram", 1)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: Invalid 'from_type' or 'to_type' value: 'slug', 'kilogram'
|
||||
Supported values are: kilogram, gram, milligram, metric-ton, long-ton, short-ton, \
|
||||
pound, stone, ounce, carrat, atomic-mass-unit
|
||||
"""
|
||||
if to_type not in KILOGRAM_CHART or from_type not in WEIGHT_TYPE_CHART:
|
||||
msg = (
|
||||
|
|
|
@ -80,9 +80,9 @@ class Node:
|
|||
"""
|
||||
if self.left and (self.data < self.left.data or not self.left.is_sorted):
|
||||
return False
|
||||
if self.right and (self.data > self.right.data or not self.right.is_sorted):
|
||||
return False
|
||||
return True
|
||||
return not (
|
||||
self.right and (self.data > self.right.data or not self.right.is_sorted)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
"""
|
||||
psf/black : true
|
||||
ruff : passed
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Iterator
|
||||
|
@ -321,9 +316,7 @@ class RedBlackTree:
|
|||
return False
|
||||
if self.left and not self.left.check_coloring():
|
||||
return False
|
||||
if self.right and not self.right.check_coloring():
|
||||
return False
|
||||
return True
|
||||
return not (self.right and not self.right.check_coloring())
|
||||
|
||||
def black_height(self) -> int | None:
|
||||
"""Returns the number of black nodes from this node to the
|
||||
|
@ -561,9 +554,7 @@ def test_rotations() -> bool:
|
|||
right_rot.right.right = RedBlackTree(10, parent=right_rot.right)
|
||||
right_rot.right.right.left = RedBlackTree(5, parent=right_rot.right.right)
|
||||
right_rot.right.right.right = RedBlackTree(20, parent=right_rot.right.right)
|
||||
if tree != right_rot:
|
||||
return False
|
||||
return True
|
||||
return tree == right_rot
|
||||
|
||||
|
||||
def test_insertion_speed() -> bool:
|
||||
|
@ -606,13 +597,11 @@ def test_insert_and_search() -> bool:
|
|||
tree.insert(12)
|
||||
tree.insert(10)
|
||||
tree.insert(11)
|
||||
if 5 in tree or -6 in tree or -10 in tree or 13 in tree:
|
||||
if any(i in tree for i in (5, -6, -10, 13)):
|
||||
# Found something not in there
|
||||
return False
|
||||
if not (11 in tree and 12 in tree and -8 in tree and 0 in tree):
|
||||
# Didn't find something in there
|
||||
return False
|
||||
return True
|
||||
# Find all these things in there
|
||||
return all(i in tree for i in (11, 12, -8, 0))
|
||||
|
||||
|
||||
def test_insert_delete() -> bool:
|
||||
|
@ -634,9 +623,7 @@ def test_insert_delete() -> bool:
|
|||
tree = tree.remove(9)
|
||||
if not tree.check_color_properties():
|
||||
return False
|
||||
if list(tree.inorder_traverse()) != [-8, 0, 4, 8, 10, 11, 12]:
|
||||
return False
|
||||
return True
|
||||
return list(tree.inorder_traverse()) == [-8, 0, 4, 8, 10, 11, 12]
|
||||
|
||||
|
||||
def test_floor_ceil() -> bool:
|
||||
|
@ -664,9 +651,7 @@ def test_min_max() -> bool:
|
|||
tree.insert(24)
|
||||
tree.insert(20)
|
||||
tree.insert(22)
|
||||
if tree.get_max() != 22 or tree.get_min() != -16:
|
||||
return False
|
||||
return True
|
||||
return not (tree.get_max() != 22 or tree.get_min() != -16)
|
||||
|
||||
|
||||
def test_tree_traversal() -> bool:
|
||||
|
@ -682,9 +667,7 @@ def test_tree_traversal() -> bool:
|
|||
return False
|
||||
if list(tree.preorder_traverse()) != [0, -16, 16, 8, 22, 20, 24]:
|
||||
return False
|
||||
if list(tree.postorder_traverse()) != [-16, 8, 20, 24, 22, 16, 0]:
|
||||
return False
|
||||
return True
|
||||
return list(tree.postorder_traverse()) == [-16, 8, 20, 24, 22, 16, 0]
|
||||
|
||||
|
||||
def test_tree_chaining() -> bool:
|
||||
|
@ -695,9 +678,7 @@ def test_tree_chaining() -> bool:
|
|||
return False
|
||||
if list(tree.preorder_traverse()) != [0, -16, 16, 8, 22, 20, 24]:
|
||||
return False
|
||||
if list(tree.postorder_traverse()) != [-16, 8, 20, 24, 22, 16, 0]:
|
||||
return False
|
||||
return True
|
||||
return list(tree.postorder_traverse()) == [-16, 8, 20, 24, 22, 16, 0]
|
||||
|
||||
|
||||
def print_results(msg: str, passes: bool) -> None:
|
||||
|
|
|
@ -156,9 +156,11 @@ class GraphAdjacencyMatrix(Generic[T]):
|
|||
self.vertex_to_index.pop(vertex)
|
||||
|
||||
# decrement indices for vertices shifted by the deleted vertex in the adj matrix
|
||||
for vertex in self.vertex_to_index:
|
||||
if self.vertex_to_index[vertex] >= start_index:
|
||||
self.vertex_to_index[vertex] = self.vertex_to_index[vertex] - 1
|
||||
for inner_vertex in self.vertex_to_index:
|
||||
if self.vertex_to_index[inner_vertex] >= start_index:
|
||||
self.vertex_to_index[inner_vertex] = (
|
||||
self.vertex_to_index[inner_vertex] - 1
|
||||
)
|
||||
|
||||
def contains_vertex(self, vertex: T) -> bool:
|
||||
"""
|
||||
|
|
|
@ -79,7 +79,7 @@ def key(start: TPos, i: int, goal: TPos, g_function: dict[TPos, float]):
|
|||
|
||||
|
||||
def do_something(back_pointer, goal, start):
|
||||
grid = np.chararray((n, n))
|
||||
grid = np.char.chararray((n, n))
|
||||
for i in range(n):
|
||||
for j in range(n):
|
||||
grid[i][j] = "*"
|
||||
|
@ -123,9 +123,7 @@ def do_something(back_pointer, goal, start):
|
|||
def valid(p: TPos):
|
||||
if p[0] < 0 or p[0] > n - 1:
|
||||
return False
|
||||
if p[1] < 0 or p[1] > n - 1:
|
||||
return False
|
||||
return True
|
||||
return not (p[1] < 0 or p[1] > n - 1)
|
||||
|
||||
|
||||
def expand_state(
|
||||
|
|
|
@ -38,7 +38,7 @@ def find_components(
|
|||
reversed_graph: dict[int, list[int]], vert: int, visited: list[bool]
|
||||
) -> list[int]:
|
||||
"""
|
||||
Use depth first search to find strongliy connected
|
||||
Use depth first search to find strongly connected
|
||||
vertices. Now graph is reversed
|
||||
>>> find_components({0: [1], 1: [2], 2: [0]}, 0, 5 * [False])
|
||||
[0, 1, 2]
|
||||
|
|
|
@ -103,4 +103,4 @@ if __name__ == "__main__":
|
|||
edges = list(zip(source, target))
|
||||
g = create_graph(n_vertices, edges)
|
||||
|
||||
assert [[5], [6], [4], [3, 2, 1, 0]] == tarjan(g)
|
||||
assert tarjan(g) == [[5], [6], [4], [3, 2, 1, 0]]
|
||||
|
|
|
@ -82,8 +82,8 @@ def reformat_hex(i: int) -> bytes:
|
|||
|
||||
hex_rep = format(i, "08x")[-8:]
|
||||
little_endian_hex = b""
|
||||
for i in [3, 2, 1, 0]:
|
||||
little_endian_hex += hex_rep[2 * i : 2 * i + 2].encode("utf-8")
|
||||
for j in [3, 2, 1, 0]:
|
||||
little_endian_hex += hex_rep[2 * j : 2 * j + 2].encode("utf-8")
|
||||
return little_endian_hex
|
||||
|
||||
|
||||
|
|
|
@ -1,15 +1,5 @@
|
|||
import numpy as np
|
||||
|
||||
matrix = np.array(
|
||||
[
|
||||
[5.0, -5.0, -3.0, 4.0, -11.0],
|
||||
[1.0, -4.0, 6.0, -4.0, -10.0],
|
||||
[-2.0, -5.0, 4.0, -5.0, -12.0],
|
||||
[-3.0, -3.0, 5.0, -5.0, 8.0],
|
||||
],
|
||||
dtype=float,
|
||||
)
|
||||
|
||||
|
||||
def solve_linear_system(matrix: np.ndarray) -> np.ndarray:
|
||||
"""
|
||||
|
@ -87,15 +77,18 @@ def solve_linear_system(matrix: np.ndarray) -> np.ndarray:
|
|||
|
||||
if __name__ == "__main__":
|
||||
from doctest import testmod
|
||||
from pathlib import Path
|
||||
|
||||
testmod()
|
||||
file_path = Path(__file__).parent / "matrix.txt"
|
||||
try:
|
||||
matrix = np.loadtxt(file_path)
|
||||
except FileNotFoundError:
|
||||
print(f"Error: {file_path} not found. Using default matrix instead.")
|
||||
|
||||
# Example usage:
|
||||
print(f"Matrix:\n{matrix}")
|
||||
print(f"{solve_linear_system(matrix) = }")
|
||||
example_matrix = np.array(
|
||||
[
|
||||
[5.0, -5.0, -3.0, 4.0, -11.0],
|
||||
[1.0, -4.0, 6.0, -4.0, -10.0],
|
||||
[-2.0, -5.0, 4.0, -5.0, -12.0],
|
||||
[-3.0, -3.0, 5.0, -5.0, 8.0],
|
||||
],
|
||||
dtype=float,
|
||||
)
|
||||
|
||||
print(f"Matrix:\n{example_matrix}")
|
||||
print(f"{solve_linear_system(example_matrix) = }")
|
|
@ -1,4 +0,0 @@
|
|||
5.0 -5.0 -3.0 4.0 -11.0
|
||||
1.0 -4.0 6.0 -4.0 -10.0
|
||||
-2.0 -5.0 4.0 -5.0 -12.0
|
||||
-3.0 -3.0 5.0 -5.0 8.0
|
|
@ -4,7 +4,7 @@ Github : faizan2700
|
|||
|
||||
Purpose : You have one function f(x) which takes float integer and returns
|
||||
float you have to integrate the function in limits a to b.
|
||||
The approximation proposed by Thomas Simpsons in 1743 is one way to calculate
|
||||
The approximation proposed by Thomas Simpson in 1743 is one way to calculate
|
||||
integration.
|
||||
|
||||
( read article : https://cp-algorithms.com/num_methods/simpson-integration.html )
|
||||
|
|
|
@ -76,9 +76,9 @@ def get_3d_vectors_cross(ab: Vector3d, ac: Vector3d) -> Vector3d:
|
|||
|
||||
def is_zero_vector(vector: Vector3d, accuracy: int) -> bool:
|
||||
"""
|
||||
Check if vector is equal to (0, 0, 0) of not.
|
||||
Check if vector is equal to (0, 0, 0) or not.
|
||||
|
||||
Sine the algorithm is very accurate, we will never get a zero vector,
|
||||
Since the algorithm is very accurate, we will never get a zero vector,
|
||||
so we need to round the vector axis,
|
||||
because we want a result that is either True or False.
|
||||
In other applications, we can return a float that represents the collinearity ratio.
|
||||
|
@ -97,9 +97,9 @@ def are_collinear(a: Point3d, b: Point3d, c: Point3d, accuracy: int = 10) -> boo
|
|||
"""
|
||||
Check if three points are collinear or not.
|
||||
|
||||
1- Create tow vectors AB and AC.
|
||||
2- Get the cross vector of the tow vectors.
|
||||
3- Calcolate the length of the cross vector.
|
||||
1- Create two vectors AB and AC.
|
||||
2- Get the cross vector of the two vectors.
|
||||
3- Calculate the length of the cross vector.
|
||||
4- If the length is zero then the points are collinear, else they are not.
|
||||
|
||||
The use of the accuracy parameter is explained in is_zero_vector docstring.
|
||||
|
|
|
@ -84,7 +84,6 @@ class FFT:
|
|||
# Corner case
|
||||
if len(dft) <= 1:
|
||||
return dft[0]
|
||||
#
|
||||
next_ncol = self.c_max_length // 2
|
||||
while next_ncol > 0:
|
||||
new_dft = [[] for i in range(next_ncol)]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
- - - - - -- - - - - - - - - - - - - - - - - - - - - - -
|
||||
Name - - CNN - Convolution Neural Network For Photo Recognizing
|
||||
Goal - - Recognize Handing Writing Word Photo
|
||||
Goal - - Recognize Handwriting Word Photo
|
||||
Detail: Total 5 layers neural network
|
||||
* Convolution layer
|
||||
* Pooling layer
|
||||
|
@ -135,7 +135,7 @@ class CNN:
|
|||
)
|
||||
data_featuremap.append(featuremap)
|
||||
|
||||
# expanding the data slice to One dimenssion
|
||||
# expanding the data slice to one dimension
|
||||
focus1_list = []
|
||||
for each_focus in data_focus:
|
||||
focus1_list.extend(self.Expand_Mat(each_focus))
|
||||
|
@ -304,7 +304,7 @@ class CNN:
|
|||
plt.grid(True, alpha=0.5)
|
||||
plt.show()
|
||||
|
||||
print("------------------Training Complished---------------------")
|
||||
print("------------------Training Complete---------------------")
|
||||
print((" - - Training epoch: ", rp, f" - - Mse: {mse:.6f}"))
|
||||
if draw_e:
|
||||
draw_error()
|
||||
|
@ -353,5 +353,5 @@ class CNN:
|
|||
|
||||
if __name__ == "__main__":
|
||||
"""
|
||||
I will put the example on other file
|
||||
I will put the example in another file
|
||||
"""
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -85,11 +85,10 @@ def validate(n: int) -> bool:
|
|||
>>> validate(3797)
|
||||
True
|
||||
"""
|
||||
if len(str(n)) > 3 and (
|
||||
not is_prime(int(str(n)[-3:])) or not is_prime(int(str(n)[:3]))
|
||||
):
|
||||
return False
|
||||
return True
|
||||
return not (
|
||||
len(str(n)) > 3
|
||||
and (not is_prime(int(str(n)[-3:])) or not is_prime(int(str(n)[:3])))
|
||||
)
|
||||
|
||||
|
||||
def compute_truncated_primes(count: int = 11) -> list[int]:
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -43,7 +43,7 @@ def solution(limit: int = 1_000_000) -> int:
|
|||
ind = np.arange(2 * i, limit + 1, i) # indexes for selection
|
||||
phi[ind] -= phi[ind] // i
|
||||
|
||||
return np.sum(phi[2 : limit + 1])
|
||||
return int(np.sum(phi[2 : limit + 1]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -74,12 +74,6 @@ lint.ignore = [
|
|||
"UP038", # Use `X | Y` in `{}` call instead of `(X, Y)` -- DO NOT FIX
|
||||
]
|
||||
|
||||
lint.per-file-ignores."arithmetic_analysis/newton_raphson.py" = [
|
||||
"PGH001",
|
||||
]
|
||||
lint.per-file-ignores."data_structures/binary_tree/binary_search_tree_recursive.py" = [
|
||||
"BLE001",
|
||||
]
|
||||
lint.per-file-ignores."data_structures/hashing/tests/test_hash_map.py" = [
|
||||
"BLE001",
|
||||
]
|
||||
|
|
|
@ -36,7 +36,7 @@ def build_tree() -> TreeNode:
|
|||
right_node = TreeNode(int(check))
|
||||
node_found.right = right_node
|
||||
q.put(right_node)
|
||||
raise
|
||||
raise ValueError("Something went wrong")
|
||||
|
||||
|
||||
def pre_order(node: TreeNode) -> None:
|
||||
|
@ -164,8 +164,8 @@ def level_order_actual(node: TreeNode) -> None:
|
|||
if node_dequeued.right:
|
||||
list_.append(node_dequeued.right)
|
||||
print()
|
||||
for node in list_:
|
||||
q.put(node)
|
||||
for inner_node in list_:
|
||||
q.put(inner_node)
|
||||
|
||||
|
||||
# iteration version
|
||||
|
|
|
@ -3,13 +3,41 @@ This is pure Python implementation of interpolation search algorithm
|
|||
"""
|
||||
|
||||
|
||||
def interpolation_search(sorted_collection, item):
|
||||
"""Pure implementation of interpolation search algorithm in Python
|
||||
Be careful collection must be ascending sorted, otherwise result will be
|
||||
unpredictable
|
||||
:param sorted_collection: some ascending sorted collection with comparable items
|
||||
:param item: item value to search
|
||||
:return: index of found item or None if item is not found
|
||||
def interpolation_search(sorted_collection: list[int], item: int) -> int | None:
|
||||
"""
|
||||
Searches for an item in a sorted collection by interpolation search algorithm.
|
||||
|
||||
Args:
|
||||
sorted_collection: sorted list of integers
|
||||
item: item value to search
|
||||
|
||||
Returns:
|
||||
int: The index of the found item, or None if the item is not found.
|
||||
Examples:
|
||||
>>> interpolation_search([1, 2, 3, 4, 5], 2)
|
||||
1
|
||||
>>> interpolation_search([1, 2, 3, 4, 5], 4)
|
||||
3
|
||||
>>> interpolation_search([1, 2, 3, 4, 5], 6) is None
|
||||
True
|
||||
>>> interpolation_search([], 1) is None
|
||||
True
|
||||
>>> interpolation_search([100], 100)
|
||||
0
|
||||
>>> interpolation_search([1, 2, 3, 4, 5], 0) is None
|
||||
True
|
||||
>>> interpolation_search([1, 2, 3, 4, 5], 7) is None
|
||||
True
|
||||
>>> interpolation_search([1, 2, 3, 4, 5], 2)
|
||||
1
|
||||
>>> interpolation_search([1, 2, 3, 4, 5], 0) is None
|
||||
True
|
||||
>>> interpolation_search([1, 2, 3, 4, 5], 7) is None
|
||||
True
|
||||
>>> interpolation_search([1, 2, 3, 4, 5], 2)
|
||||
1
|
||||
>>> interpolation_search([5, 5, 5, 5, 5], 3) is None
|
||||
True
|
||||
"""
|
||||
left = 0
|
||||
right = len(sorted_collection) - 1
|
||||
|
@ -19,7 +47,6 @@ def interpolation_search(sorted_collection, item):
|
|||
if sorted_collection[left] == sorted_collection[right]:
|
||||
if sorted_collection[left] == item:
|
||||
return left
|
||||
else:
|
||||
return None
|
||||
|
||||
point = left + ((item - sorted_collection[left]) * (right - left)) // (
|
||||
|
@ -33,7 +60,7 @@ def interpolation_search(sorted_collection, item):
|
|||
current_item = sorted_collection[point]
|
||||
if current_item == item:
|
||||
return point
|
||||
elif point < left:
|
||||
if point < left:
|
||||
right = left
|
||||
left = point
|
||||
elif point > right:
|
||||
|
@ -46,21 +73,41 @@ def interpolation_search(sorted_collection, item):
|
|||
return None
|
||||
|
||||
|
||||
def interpolation_search_by_recursion(sorted_collection, item, left, right):
|
||||
def interpolation_search_by_recursion(
|
||||
sorted_collection: list[int], item: int, left: int = 0, right: int | None = None
|
||||
) -> int | None:
|
||||
"""Pure implementation of interpolation search algorithm in Python by recursion
|
||||
Be careful collection must be ascending sorted, otherwise result will be
|
||||
unpredictable
|
||||
First recursion should be started with left=0 and right=(len(sorted_collection)-1)
|
||||
:param sorted_collection: some ascending sorted collection with comparable items
|
||||
:param item: item value to search
|
||||
:return: index of found item or None if item is not found
|
||||
"""
|
||||
|
||||
Args:
|
||||
sorted_collection: some sorted collection with comparable items
|
||||
item: item value to search
|
||||
left: left index in collection
|
||||
right: right index in collection
|
||||
|
||||
Returns:
|
||||
index of item in collection or None if item is not present
|
||||
|
||||
Examples:
|
||||
>>> interpolation_search_by_recursion([0, 5, 7, 10, 15], 0)
|
||||
0
|
||||
>>> interpolation_search_by_recursion([0, 5, 7, 10, 15], 15)
|
||||
4
|
||||
>>> interpolation_search_by_recursion([0, 5, 7, 10, 15], 5)
|
||||
1
|
||||
>>> interpolation_search_by_recursion([0, 5, 7, 10, 15], 100) is None
|
||||
True
|
||||
>>> interpolation_search_by_recursion([5, 5, 5, 5, 5], 3) is None
|
||||
True
|
||||
"""
|
||||
if right is None:
|
||||
right = len(sorted_collection) - 1
|
||||
# avoid divided by 0 during interpolation
|
||||
if sorted_collection[left] == sorted_collection[right]:
|
||||
if sorted_collection[left] == item:
|
||||
return left
|
||||
else:
|
||||
return None
|
||||
|
||||
point = left + ((item - sorted_collection[left]) * (right - left)) // (
|
||||
|
@ -73,64 +120,18 @@ def interpolation_search_by_recursion(sorted_collection, item, left, right):
|
|||
|
||||
if sorted_collection[point] == item:
|
||||
return point
|
||||
elif point < left:
|
||||
if point < left:
|
||||
return interpolation_search_by_recursion(sorted_collection, item, point, left)
|
||||
elif point > right:
|
||||
if point > right:
|
||||
return interpolation_search_by_recursion(sorted_collection, item, right, left)
|
||||
elif sorted_collection[point] > item:
|
||||
if sorted_collection[point] > item:
|
||||
return interpolation_search_by_recursion(
|
||||
sorted_collection, item, left, point - 1
|
||||
)
|
||||
else:
|
||||
return interpolation_search_by_recursion(
|
||||
sorted_collection, item, point + 1, right
|
||||
)
|
||||
|
||||
|
||||
def __assert_sorted(collection):
|
||||
"""Check if collection is ascending sorted, if not - raises :py:class:`ValueError`
|
||||
:param collection: collection
|
||||
:return: True if collection is ascending sorted
|
||||
:raise: :py:class:`ValueError` if collection is not ascending sorted
|
||||
Examples:
|
||||
>>> __assert_sorted([0, 1, 2, 4])
|
||||
True
|
||||
>>> __assert_sorted([10, -1, 5])
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: Collection must be ascending sorted
|
||||
"""
|
||||
if collection != sorted(collection):
|
||||
raise ValueError("Collection must be ascending sorted")
|
||||
return True
|
||||
return interpolation_search_by_recursion(sorted_collection, item, point + 1, right)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
import doctest
|
||||
|
||||
"""
|
||||
user_input = input('Enter numbers separated by comma:\n').strip()
|
||||
collection = [int(item) for item in user_input.split(',')]
|
||||
try:
|
||||
__assert_sorted(collection)
|
||||
except ValueError:
|
||||
sys.exit('Sequence must be ascending sorted to apply interpolation search')
|
||||
|
||||
target_input = input('Enter a single number to be found in the list:\n')
|
||||
target = int(target_input)
|
||||
"""
|
||||
|
||||
debug = 0
|
||||
if debug == 1:
|
||||
collection = [10, 30, 40, 45, 50, 66, 77, 93]
|
||||
try:
|
||||
__assert_sorted(collection)
|
||||
except ValueError:
|
||||
sys.exit("Sequence must be ascending sorted to apply interpolation search")
|
||||
target = 67
|
||||
|
||||
result = interpolation_search(collection, target)
|
||||
if result is not None:
|
||||
print(f"{target} found at positions: {result}")
|
||||
else:
|
||||
print("Not found")
|
||||
doctest.testmod()
|
||||
|
|
|
@ -77,10 +77,7 @@ class FilesArray:
|
|||
self.empty.add(i)
|
||||
self.files[i].close()
|
||||
|
||||
if len(self.empty) == self.num_buffers:
|
||||
return False
|
||||
|
||||
return True
|
||||
return len(self.empty) != self.num_buffers
|
||||
|
||||
def unshift(self, index):
|
||||
value = self.buffers[index]
|
||||
|
|
0
source/__init__.py
Normal file
0
source/__init__.py
Normal file
|
@ -72,9 +72,7 @@ def can_string_be_rearranged_as_palindrome(input_str: str = "") -> bool:
|
|||
for character_count in character_freq_dict.values():
|
||||
if character_count % 2:
|
||||
odd_char += 1
|
||||
if odd_char > 1:
|
||||
return False
|
||||
return True
|
||||
return not odd_char > 1
|
||||
|
||||
|
||||
def benchmark(input_str: str = "") -> None:
|
||||
|
|
34
strings/count_vowels.py
Normal file
34
strings/count_vowels.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
def count_vowels(s: str) -> int:
|
||||
"""
|
||||
Count the number of vowels in a given string.
|
||||
|
||||
:param s: Input string to count vowels in.
|
||||
:return: Number of vowels in the input string.
|
||||
|
||||
Examples:
|
||||
>>> count_vowels("hello world")
|
||||
3
|
||||
>>> count_vowels("HELLO WORLD")
|
||||
3
|
||||
>>> count_vowels("123 hello world")
|
||||
3
|
||||
>>> count_vowels("")
|
||||
0
|
||||
>>> count_vowels("a quick brown fox")
|
||||
5
|
||||
>>> count_vowels("the quick BROWN fox")
|
||||
5
|
||||
>>> count_vowels("PYTHON")
|
||||
1
|
||||
"""
|
||||
if not isinstance(s, str):
|
||||
raise ValueError("Input must be a string")
|
||||
|
||||
vowels = "aeiouAEIOU"
|
||||
return sum(1 for char in s if char in vowels)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from doctest import testmod
|
||||
|
||||
testmod()
|
|
@ -101,9 +101,7 @@ def is_valid_email_address(email: str) -> bool:
|
|||
return False
|
||||
|
||||
# (7.) Validate the placement of "." characters
|
||||
if domain.startswith(".") or domain.endswith(".") or ".." in domain:
|
||||
return False
|
||||
return True
|
||||
return not (domain.startswith(".") or domain.endswith(".") or ".." in domain)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -67,19 +67,19 @@ def text_justification(word: str, max_width: int) -> list:
|
|||
answer = []
|
||||
line: list[str] = []
|
||||
width = 0
|
||||
for word in words:
|
||||
if width + len(word) + len(line) <= max_width:
|
||||
for inner_word in words:
|
||||
if width + len(inner_word) + len(line) <= max_width:
|
||||
# keep adding words until we can fill out max_width
|
||||
# width = sum of length of all words (without overall_spaces_count)
|
||||
# len(word) = length of current word
|
||||
# len(inner_word) = length of current inner_word
|
||||
# len(line) = number of overall_spaces_count to insert between words
|
||||
line.append(word)
|
||||
width += len(word)
|
||||
line.append(inner_word)
|
||||
width += len(inner_word)
|
||||
else:
|
||||
# justify the line and add it to result
|
||||
answer.append(justify(line, width, max_width))
|
||||
# reset new line and new width
|
||||
line, width = [word], len(word)
|
||||
line, width = [inner_word], len(inner_word)
|
||||
remaining_spaces = max_width - width - len(line)
|
||||
answer.append(" ".join(line) + (remaining_spaces + 1) * " ")
|
||||
return answer
|
||||
|
|
|
@ -31,12 +31,7 @@ class Parser(HTMLParser):
|
|||
# Check the list of defined attributes.
|
||||
for name, value in attrs:
|
||||
# If href is defined, not empty nor # print it and not already in urls.
|
||||
if (
|
||||
name == "href"
|
||||
and value != "#"
|
||||
and value != ""
|
||||
and value not in self.urls
|
||||
):
|
||||
if name == "href" and value not in (*self.urls, "", "#"):
|
||||
url = parse.urljoin(self.domain, value)
|
||||
self.urls.append(url)
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ def get_forbes_real_time_billionaires() -> list[dict[str, int | str]]:
|
|||
"Country": person["countryOfCitizenship"],
|
||||
"Gender": person["gender"],
|
||||
"Worth ($)": f"{person['finalWorth'] / 1000:.1f} Billion",
|
||||
"Age": years_old(person["birthDate"]),
|
||||
"Age": str(years_old(person["birthDate"] / 1000)),
|
||||
}
|
||||
for person in response_json["personList"]["personsLists"]
|
||||
]
|
||||
|
@ -95,4 +95,7 @@ def display_billionaires(forbes_billionaires: list[dict[str, int | str]]) -> Non
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from doctest import testmod
|
||||
|
||||
testmod()
|
||||
display_billionaires(get_forbes_real_time_billionaires())
|
||||
|
|
Loading…
Reference in New Issue
Block a user