Merge branch 'TheAlgorithms:master' into OctalToBinary

This commit is contained in:
Bama Charan Chhandogi 2023-08-13 14:51:32 +05:30 committed by GitHub
commit b03c5a3ba0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 231 additions and 112 deletions

View File

@ -16,7 +16,7 @@ repos:
- id: auto-walrus - id: auto-walrus
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.281 rev: v0.0.282
hooks: hooks:
- id: ruff - id: ruff

View File

@ -585,6 +585,7 @@
* [Hardy Ramanujanalgo](maths/hardy_ramanujanalgo.py) * [Hardy Ramanujanalgo](maths/hardy_ramanujanalgo.py)
* [Hexagonal Number](maths/hexagonal_number.py) * [Hexagonal Number](maths/hexagonal_number.py)
* [Integration By Simpson Approx](maths/integration_by_simpson_approx.py) * [Integration By Simpson Approx](maths/integration_by_simpson_approx.py)
* [Interquartile Range](maths/interquartile_range.py)
* [Is Int Palindrome](maths/is_int_palindrome.py) * [Is Int Palindrome](maths/is_int_palindrome.py)
* [Is Ip V4 Address Valid](maths/is_ip_v4_address_valid.py) * [Is Ip V4 Address Valid](maths/is_ip_v4_address_valid.py)
* [Is Square Free](maths/is_square_free.py) * [Is Square Free](maths/is_square_free.py)
@ -709,7 +710,6 @@
* [Exponential Linear Unit](neural_network/activation_functions/exponential_linear_unit.py) * [Exponential Linear Unit](neural_network/activation_functions/exponential_linear_unit.py)
* [Back Propagation Neural Network](neural_network/back_propagation_neural_network.py) * [Back Propagation Neural Network](neural_network/back_propagation_neural_network.py)
* [Convolution Neural Network](neural_network/convolution_neural_network.py) * [Convolution Neural Network](neural_network/convolution_neural_network.py)
* [Input Data](neural_network/input_data.py)
* [Perceptron](neural_network/perceptron.py) * [Perceptron](neural_network/perceptron.py)
* [Simple Neural Network](neural_network/simple_neural_network.py) * [Simple Neural Network](neural_network/simple_neural_network.py)

View File

@ -22,9 +22,13 @@ REFERENCES :
-> Wikipedia reference: https://en.wikipedia.org/wiki/Millimeter -> Wikipedia reference: https://en.wikipedia.org/wiki/Millimeter
""" """
from collections import namedtuple from typing import NamedTuple
class FromTo(NamedTuple):
from_factor: float
to_factor: float
from_to = namedtuple("from_to", "from_ to")
TYPE_CONVERSION = { TYPE_CONVERSION = {
"millimeter": "mm", "millimeter": "mm",
@ -40,14 +44,14 @@ TYPE_CONVERSION = {
} }
METRIC_CONVERSION = { METRIC_CONVERSION = {
"mm": from_to(0.001, 1000), "mm": FromTo(0.001, 1000),
"cm": from_to(0.01, 100), "cm": FromTo(0.01, 100),
"m": from_to(1, 1), "m": FromTo(1, 1),
"km": from_to(1000, 0.001), "km": FromTo(1000, 0.001),
"in": from_to(0.0254, 39.3701), "in": FromTo(0.0254, 39.3701),
"ft": from_to(0.3048, 3.28084), "ft": FromTo(0.3048, 3.28084),
"yd": from_to(0.9144, 1.09361), "yd": FromTo(0.9144, 1.09361),
"mi": from_to(1609.34, 0.000621371), "mi": FromTo(1609.34, 0.000621371),
} }
@ -115,7 +119,11 @@ def length_conversion(value: float, from_type: str, to_type: str) -> float:
f"Conversion abbreviations are: {', '.join(METRIC_CONVERSION)}" f"Conversion abbreviations are: {', '.join(METRIC_CONVERSION)}"
) )
raise ValueError(msg) raise ValueError(msg)
return value * METRIC_CONVERSION[new_from].from_ * METRIC_CONVERSION[new_to].to return (
value
* METRIC_CONVERSION[new_from].from_factor
* METRIC_CONVERSION[new_to].to_factor
)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -19,19 +19,23 @@ REFERENCES :
-> https://www.unitconverters.net/pressure-converter.html -> https://www.unitconverters.net/pressure-converter.html
""" """
from collections import namedtuple from typing import NamedTuple
class FromTo(NamedTuple):
from_factor: float
to_factor: float
from_to = namedtuple("from_to", "from_ to")
PRESSURE_CONVERSION = { PRESSURE_CONVERSION = {
"atm": from_to(1, 1), "atm": FromTo(1, 1),
"pascal": from_to(0.0000098, 101325), "pascal": FromTo(0.0000098, 101325),
"bar": from_to(0.986923, 1.01325), "bar": FromTo(0.986923, 1.01325),
"kilopascal": from_to(0.00986923, 101.325), "kilopascal": FromTo(0.00986923, 101.325),
"megapascal": from_to(9.86923, 0.101325), "megapascal": FromTo(9.86923, 0.101325),
"psi": from_to(0.068046, 14.6959), "psi": FromTo(0.068046, 14.6959),
"inHg": from_to(0.0334211, 29.9213), "inHg": FromTo(0.0334211, 29.9213),
"torr": from_to(0.00131579, 760), "torr": FromTo(0.00131579, 760),
} }
@ -71,7 +75,9 @@ def pressure_conversion(value: float, from_type: str, to_type: str) -> float:
+ ", ".join(PRESSURE_CONVERSION) + ", ".join(PRESSURE_CONVERSION)
) )
return ( return (
value * PRESSURE_CONVERSION[from_type].from_ * PRESSURE_CONVERSION[to_type].to value
* PRESSURE_CONVERSION[from_type].from_factor
* PRESSURE_CONVERSION[to_type].to_factor
) )

View File

@ -18,35 +18,39 @@ REFERENCES :
-> Wikipedia reference: https://en.wikipedia.org/wiki/Cup_(unit) -> Wikipedia reference: https://en.wikipedia.org/wiki/Cup_(unit)
""" """
from collections import namedtuple from typing import NamedTuple
class FromTo(NamedTuple):
from_factor: float
to_factor: float
from_to = namedtuple("from_to", "from_ to")
METRIC_CONVERSION = { METRIC_CONVERSION = {
"cubicmeter": from_to(1, 1), "cubic meter": FromTo(1, 1),
"litre": from_to(0.001, 1000), "litre": FromTo(0.001, 1000),
"kilolitre": from_to(1, 1), "kilolitre": FromTo(1, 1),
"gallon": from_to(0.00454, 264.172), "gallon": FromTo(0.00454, 264.172),
"cubicyard": from_to(0.76455, 1.30795), "cubic yard": FromTo(0.76455, 1.30795),
"cubicfoot": from_to(0.028, 35.3147), "cubic foot": FromTo(0.028, 35.3147),
"cup": from_to(0.000236588, 4226.75), "cup": FromTo(0.000236588, 4226.75),
} }
def volume_conversion(value: float, from_type: str, to_type: str) -> float: def volume_conversion(value: float, from_type: str, to_type: str) -> float:
""" """
Conversion between volume units. Conversion between volume units.
>>> volume_conversion(4, "cubicmeter", "litre") >>> volume_conversion(4, "cubic meter", "litre")
4000 4000
>>> volume_conversion(1, "litre", "gallon") >>> volume_conversion(1, "litre", "gallon")
0.264172 0.264172
>>> volume_conversion(1, "kilolitre", "cubicmeter") >>> volume_conversion(1, "kilolitre", "cubic meter")
1 1
>>> volume_conversion(3, "gallon", "cubicyard") >>> volume_conversion(3, "gallon", "cubic yard")
0.017814279 0.017814279
>>> volume_conversion(2, "cubicyard", "litre") >>> volume_conversion(2, "cubic yard", "litre")
1529.1 1529.1
>>> volume_conversion(4, "cubicfoot", "cup") >>> volume_conversion(4, "cubic foot", "cup")
473.396 473.396
>>> volume_conversion(1, "cup", "kilolitre") >>> volume_conversion(1, "cup", "kilolitre")
0.000236588 0.000236588
@ -54,7 +58,7 @@ def volume_conversion(value: float, from_type: str, to_type: str) -> float:
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValueError: Invalid 'from_type' value: 'wrongUnit' Supported values are: ValueError: Invalid 'from_type' value: 'wrongUnit' Supported values are:
cubicmeter, litre, kilolitre, gallon, cubicyard, cubicfoot, cup cubic meter, litre, kilolitre, gallon, cubic yard, cubic foot, cup
""" """
if from_type not in METRIC_CONVERSION: if from_type not in METRIC_CONVERSION:
raise ValueError( raise ValueError(
@ -66,7 +70,11 @@ def volume_conversion(value: float, from_type: str, to_type: str) -> float:
f"Invalid 'to_type' value: {to_type!r}. Supported values are:\n" f"Invalid 'to_type' value: {to_type!r}. Supported values are:\n"
+ ", ".join(METRIC_CONVERSION) + ", ".join(METRIC_CONVERSION)
) )
return value * METRIC_CONVERSION[from_type].from_ * METRIC_CONVERSION[to_type].to return (
value
* METRIC_CONVERSION[from_type].from_factor
* METRIC_CONVERSION[to_type].to_factor
)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -39,8 +39,8 @@ Space: O(1)
from __future__ import annotations from __future__ import annotations
from collections import namedtuple
from dataclasses import dataclass from dataclasses import dataclass
from typing import NamedTuple
@dataclass @dataclass
@ -50,7 +50,9 @@ class TreeNode:
right: TreeNode | None = None right: TreeNode | None = None
CoinsDistribResult = namedtuple("CoinsDistribResult", "moves excess") class CoinsDistribResult(NamedTuple):
moves: int
excess: int
def distribute_coins(root: TreeNode | None) -> int: def distribute_coins(root: TreeNode | None) -> int:
@ -79,7 +81,7 @@ def distribute_coins(root: TreeNode | None) -> int:
# Validation # Validation
def count_nodes(node: TreeNode | None) -> int: def count_nodes(node: TreeNode | None) -> int:
""" """
>>> count_nodes(None): >>> count_nodes(None)
0 0
""" """
if node is None: if node is None:
@ -89,7 +91,7 @@ def distribute_coins(root: TreeNode | None) -> int:
def count_coins(node: TreeNode | None) -> int: def count_coins(node: TreeNode | None) -> int:
""" """
>>> count_coins(None): >>> count_coins(None)
0 0
""" """
if node is None: if node is None:

View File

@ -1,7 +1,12 @@
# https://en.m.wikipedia.org/wiki/Electric_power # https://en.m.wikipedia.org/wiki/Electric_power
from __future__ import annotations from __future__ import annotations
from collections import namedtuple from typing import NamedTuple
class Result(NamedTuple):
name: str
value: float
def electric_power(voltage: float, current: float, power: float) -> tuple: def electric_power(voltage: float, current: float, power: float) -> tuple:
@ -10,11 +15,11 @@ def electric_power(voltage: float, current: float, power: float) -> tuple:
fundamental value of electrical system. fundamental value of electrical system.
examples are below: examples are below:
>>> electric_power(voltage=0, current=2, power=5) >>> electric_power(voltage=0, current=2, power=5)
result(name='voltage', value=2.5) Result(name='voltage', value=2.5)
>>> electric_power(voltage=2, current=2, power=0) >>> electric_power(voltage=2, current=2, power=0)
result(name='power', value=4.0) Result(name='power', value=4.0)
>>> electric_power(voltage=-2, current=3, power=0) >>> electric_power(voltage=-2, current=3, power=0)
result(name='power', value=6.0) Result(name='power', value=6.0)
>>> electric_power(voltage=2, current=4, power=2) >>> electric_power(voltage=2, current=4, power=2)
Traceback (most recent call last): Traceback (most recent call last):
... ...
@ -28,9 +33,8 @@ def electric_power(voltage: float, current: float, power: float) -> tuple:
... ...
ValueError: Power cannot be negative in any electrical/electronics system ValueError: Power cannot be negative in any electrical/electronics system
>>> electric_power(voltage=2.2, current=2.2, power=0) >>> electric_power(voltage=2.2, current=2.2, power=0)
result(name='power', value=4.84) Result(name='power', value=4.84)
""" """
result = namedtuple("result", "name value")
if (voltage, current, power).count(0) != 1: if (voltage, current, power).count(0) != 1:
raise ValueError("Only one argument must be 0") raise ValueError("Only one argument must be 0")
elif power < 0: elif power < 0:
@ -38,11 +42,11 @@ def electric_power(voltage: float, current: float, power: float) -> tuple:
"Power cannot be negative in any electrical/electronics system" "Power cannot be negative in any electrical/electronics system"
) )
elif voltage == 0: elif voltage == 0:
return result("voltage", power / current) return Result("voltage", power / current)
elif current == 0: elif current == 0:
return result("current", power / voltage) return Result("current", power / voltage)
elif power == 0: elif power == 0:
return result("power", float(round(abs(voltage * current), 2))) return Result("power", float(round(abs(voltage * current), 2)))
else: else:
raise ValueError("Exactly one argument must be 0") raise ValueError("Exactly one argument must be 0")

View File

@ -26,8 +26,8 @@ def pass_and_relaxation(
cst_bwd: dict, cst_bwd: dict,
queue: PriorityQueue, queue: PriorityQueue,
parent: dict, parent: dict,
shortest_distance: float | int, shortest_distance: float,
) -> float | int: ) -> float:
for nxt, d in graph[v]: for nxt, d in graph[v]:
if nxt in visited_forward: if nxt in visited_forward:
continue continue

View File

@ -7,9 +7,9 @@ from collections.abc import Callable
def trapezoidal_area( def trapezoidal_area(
fnc: Callable[[int | float], int | float], fnc: Callable[[float], float],
x_start: int | float, x_start: float,
x_end: int | float, x_end: float,
steps: int = 100, steps: int = 100,
) -> float: ) -> float:
""" """

View File

@ -1,4 +1,4 @@
def decimal_to_fraction(decimal: int | float | str) -> tuple[int, int]: def decimal_to_fraction(decimal: float | str) -> tuple[int, int]:
""" """
Return a decimal number in its simplest fraction form Return a decimal number in its simplest fraction form
>>> decimal_to_fraction(2) >>> decimal_to_fraction(2)

View File

@ -0,0 +1,66 @@
"""
An implementation of interquartile range (IQR) which is a measure of statistical
dispersion, which is the spread of the data.
The function takes the list of numeric values as input and returns the IQR.
Script inspired by this Wikipedia article:
https://en.wikipedia.org/wiki/Interquartile_range
"""
from __future__ import annotations
def find_median(nums: list[int | float]) -> float:
"""
This is the implementation of the median.
:param nums: The list of numeric nums
:return: Median of the list
>>> find_median(nums=([1, 2, 2, 3, 4]))
2
>>> find_median(nums=([1, 2, 2, 3, 4, 4]))
2.5
>>> find_median(nums=([-1, 2, 0, 3, 4, -4]))
1.5
>>> find_median(nums=([1.1, 2.2, 2, 3.3, 4.4, 4]))
2.65
"""
div, mod = divmod(len(nums), 2)
if mod:
return nums[div]
return (nums[div] + nums[(div) - 1]) / 2
def interquartile_range(nums: list[int | float]) -> float:
"""
Return the interquartile range for a list of numeric values.
:param nums: The list of numeric values.
:return: interquartile range
>>> interquartile_range(nums=[4, 1, 2, 3, 2])
2.0
>>> interquartile_range(nums = [-2, -7, -10, 9, 8, 4, -67, 45])
17.0
>>> interquartile_range(nums = [-2.1, -7.1, -10.1, 9.1, 8.1, 4.1, -67.1, 45.1])
17.2
>>> interquartile_range(nums = [0, 0, 0, 0, 0])
0.0
>>> interquartile_range(nums=[])
Traceback (most recent call last):
...
ValueError: The list is empty. Provide a non-empty list.
"""
if not nums:
raise ValueError("The list is empty. Provide a non-empty list.")
nums.sort()
length = len(nums)
div, mod = divmod(length, 2)
q1 = find_median(nums[:div])
half_length = sum((div, mod))
q3 = find_median(nums[half_length:length])
return q3 - q1
if __name__ == "__main__":
import doctest
doctest.testmod()

View File

@ -5,9 +5,9 @@ from collections.abc import Callable
def line_length( def line_length(
fnc: Callable[[int | float], int | float], fnc: Callable[[float], float],
x_start: int | float, x_start: float,
x_end: int | float, x_end: float,
steps: int = 100, steps: int = 100,
) -> float: ) -> float:
""" """

View File

@ -7,9 +7,9 @@ from collections.abc import Callable
def trapezoidal_area( def trapezoidal_area(
fnc: Callable[[int | float], int | float], fnc: Callable[[float], float],
x_start: int | float, x_start: float,
x_end: int | float, x_end: float,
steps: int = 100, steps: int = 100,
) -> float: ) -> float:
""" """

View File

@ -87,7 +87,7 @@ class Polynomial:
return Polynomial(self.degree + polynomial_2.degree, coefficients) return Polynomial(self.degree + polynomial_2.degree, coefficients)
def evaluate(self, substitution: int | float) -> int | float: def evaluate(self, substitution: float) -> float:
""" """
Evaluates the polynomial at x. Evaluates the polynomial at x.
>>> p = Polynomial(2, [1, 2, 3]) >>> p = Polynomial(2, [1, 2, 3])
@ -144,7 +144,7 @@ class Polynomial:
coefficients[i] = self.coefficients[i + 1] * (i + 1) coefficients[i] = self.coefficients[i + 1] * (i + 1)
return Polynomial(self.degree - 1, coefficients) return Polynomial(self.degree - 1, coefficients)
def integral(self, constant: int | float = 0) -> Polynomial: def integral(self, constant: float = 0) -> Polynomial:
""" """
Returns the integral of the polynomial. Returns the integral of the polynomial.
>>> p = Polynomial(2, [1, 2, 3]) >>> p = Polynomial(2, [1, 2, 3])

View File

@ -14,10 +14,10 @@ from __future__ import annotations
def geometric_series( def geometric_series(
nth_term: float | int, nth_term: float,
start_term_a: float | int, start_term_a: float,
common_ratio_r: float | int, common_ratio_r: float,
) -> list[float | int]: ) -> list[float]:
""" """
Pure Python implementation of Geometric Series algorithm Pure Python implementation of Geometric Series algorithm
@ -48,7 +48,7 @@ def geometric_series(
""" """
if not all((nth_term, start_term_a, common_ratio_r)): if not all((nth_term, start_term_a, common_ratio_r)):
return [] return []
series: list[float | int] = [] series: list[float] = []
power = 1 power = 1
multiple = common_ratio_r multiple = common_ratio_r
for _ in range(int(nth_term)): for _ in range(int(nth_term)):

View File

@ -13,7 +13,7 @@ python3 p_series.py
from __future__ import annotations from __future__ import annotations
def p_series(nth_term: int | float | str, power: int | float | str) -> list[str]: def p_series(nth_term: float | str, power: float | str) -> list[str]:
""" """
Pure Python implementation of P-Series algorithm Pure Python implementation of P-Series algorithm
:return: The P-Series starting from 1 to last (nth) term :return: The P-Series starting from 1 to last (nth) term

View File

@ -8,7 +8,7 @@ from __future__ import annotations
from math import pi, pow from math import pi, pow
def vol_cube(side_length: int | float) -> float: def vol_cube(side_length: float) -> float:
""" """
Calculate the Volume of a Cube. Calculate the Volume of a Cube.
>>> vol_cube(1) >>> vol_cube(1)

View File

@ -141,7 +141,7 @@ class Matrix:
@property @property
def order(self) -> tuple[int, int]: def order(self) -> tuple[int, int]:
return (self.num_rows, self.num_columns) return self.num_rows, self.num_columns
@property @property
def is_square(self) -> bool: def is_square(self) -> bool:
@ -315,7 +315,7 @@ class Matrix:
] ]
) )
def __mul__(self, other: Matrix | int | float) -> Matrix: def __mul__(self, other: Matrix | float) -> Matrix:
if isinstance(other, (int, float)): if isinstance(other, (int, float)):
return Matrix( return Matrix(
[[int(element * other) for element in row] for row in self.rows] [[int(element * other) for element in row] for row in self.rows]

View File

@ -47,7 +47,7 @@ def subtract(matrix_a: list[list[int]], matrix_b: list[list[int]]) -> list[list[
raise TypeError("Expected a matrix, got int/list instead") raise TypeError("Expected a matrix, got int/list instead")
def scalar_multiply(matrix: list[list[int]], n: int | float) -> list[list[float]]: def scalar_multiply(matrix: list[list[int]], n: float) -> list[list[float]]:
""" """
>>> scalar_multiply([[1,2],[3,4]],5) >>> scalar_multiply([[1,2],[3,4]],5)
[[5, 10], [15, 20]] [[5, 10], [15, 20]]
@ -189,9 +189,7 @@ def main() -> None:
matrix_c = [[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34], [41, 42, 43, 44]] matrix_c = [[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34], [41, 42, 43, 44]]
matrix_d = [[3, 0, 2], [2, 0, -2], [0, 1, 1]] matrix_d = [[3, 0, 2], [2, 0, -2], [0, 1, 1]]
print(f"Add Operation, {add(matrix_a, matrix_b) = } \n") print(f"Add Operation, {add(matrix_a, matrix_b) = } \n")
print( print(f"Multiply Operation, {multiply(matrix_a, matrix_b) = } \n")
f"Multiply Operation, {multiply(matrix_a, matrix_b) = } \n",
)
print(f"Identity: {identity(5)}\n") print(f"Identity: {identity(5)}\n")
print(f"Minor of {matrix_c} = {minor(matrix_c, 1, 2)} \n") print(f"Minor of {matrix_c} = {minor(matrix_c, 1, 2)} \n")
print(f"Determinant of {matrix_b} = {determinant(matrix_b)} \n") print(f"Determinant of {matrix_b} = {determinant(matrix_b)} \n")

View File

@ -1,9 +1,7 @@
from __future__ import annotations from __future__ import annotations
def search_in_a_sorted_matrix( def search_in_a_sorted_matrix(mat: list[list[int]], m: int, n: int, key: float) -> None:
mat: list[list[int]], m: int, n: int, key: int | float
) -> None:
""" """
>>> search_in_a_sorted_matrix( >>> search_in_a_sorted_matrix(
... [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 5) ... [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 5)

View File

@ -22,7 +22,7 @@ class Matrix:
""" """
self.row, self.column = row, column self.row, self.column = row, column
self.array = [[default_value for c in range(column)] for r in range(row)] self.array = [[default_value for _ in range(column)] for _ in range(row)]
def __str__(self) -> str: def __str__(self) -> str:
""" """
@ -54,15 +54,15 @@ class Matrix:
def __repr__(self) -> str: def __repr__(self) -> str:
return str(self) return str(self)
def validate_indicies(self, loc: tuple[int, int]) -> bool: def validate_indices(self, loc: tuple[int, int]) -> bool:
""" """
<method Matrix.validate_indicies> <method Matrix.validate_indicies>
Check if given indices are valid to pick element from matrix. Check if given indices are valid to pick element from matrix.
Example: Example:
>>> a = Matrix(2, 6, 0) >>> a = Matrix(2, 6, 0)
>>> a.validate_indicies((2, 7)) >>> a.validate_indices((2, 7))
False False
>>> a.validate_indicies((0, 0)) >>> a.validate_indices((0, 0))
True True
""" """
if not (isinstance(loc, (list, tuple)) and len(loc) == 2): if not (isinstance(loc, (list, tuple)) and len(loc) == 2):
@ -81,7 +81,7 @@ class Matrix:
>>> a[1, 0] >>> a[1, 0]
7 7
""" """
assert self.validate_indicies(loc) assert self.validate_indices(loc)
return self.array[loc[0]][loc[1]] return self.array[loc[0]][loc[1]]
def __setitem__(self, loc: tuple[int, int], value: float) -> None: def __setitem__(self, loc: tuple[int, int], value: float) -> None:
@ -96,7 +96,7 @@ class Matrix:
[ 1, 1, 1] [ 1, 1, 1]
[ 1, 1, 51] [ 1, 1, 51]
""" """
assert self.validate_indicies(loc) assert self.validate_indices(loc)
self.array[loc[0]][loc[1]] = value self.array[loc[0]][loc[1]] = value
def __add__(self, another: Matrix) -> Matrix: def __add__(self, another: Matrix) -> Matrix:
@ -145,7 +145,7 @@ class Matrix:
def __sub__(self, another: Matrix) -> Matrix: def __sub__(self, another: Matrix) -> Matrix:
return self + (-another) return self + (-another)
def __mul__(self, another: int | float | Matrix) -> Matrix: def __mul__(self, another: float | Matrix) -> Matrix:
""" """
<method Matrix.__mul__> <method Matrix.__mul__>
Return self * another. Return self * another.
@ -233,7 +233,7 @@ class Matrix:
v_t = v.transpose() v_t = v.transpose()
numerator_factor = (v_t * self * u)[0, 0] + 1 numerator_factor = (v_t * self * u)[0, 0] + 1
if numerator_factor == 0: if numerator_factor == 0:
return None # It's not invertable return None # It's not invertible
return self - ((self * u) * (v_t * self) * (1.0 / numerator_factor)) return self - ((self * u) * (v_t * self) * (1.0 / numerator_factor))

View File

@ -4,14 +4,28 @@ This algorithm iterates through a sorted collection with a step of n^(1/2),
until the element compared is bigger than the one searched. until the element compared is bigger than the one searched.
It will then perform a linear search until it matches the wanted number. It will then perform a linear search until it matches the wanted number.
If not found, it returns -1. If not found, it returns -1.
https://en.wikipedia.org/wiki/Jump_search
""" """
import math import math
from collections.abc import Sequence
from typing import Any, Protocol, TypeVar
def jump_search(arr: list, x: int) -> int: class Comparable(Protocol):
def __lt__(self, other: Any, /) -> bool:
...
T = TypeVar("T", bound=Comparable)
def jump_search(arr: Sequence[T], item: T) -> int:
""" """
Pure Python implementation of the jump search algorithm. Python implementation of the jump search algorithm.
Return the index if the `item` is found, otherwise return -1.
Examples: Examples:
>>> jump_search([0, 1, 2, 3, 4, 5], 3) >>> jump_search([0, 1, 2, 3, 4, 5], 3)
3 3
@ -21,31 +35,36 @@ def jump_search(arr: list, x: int) -> int:
-1 -1
>>> jump_search([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610], 55) >>> jump_search([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610], 55)
10 10
>>> jump_search(["aa", "bb", "cc", "dd", "ee", "ff"], "ee")
4
""" """
n = len(arr) arr_size = len(arr)
step = int(math.floor(math.sqrt(n))) block_size = int(math.sqrt(arr_size))
prev = 0 prev = 0
while arr[min(step, n) - 1] < x: step = block_size
while arr[min(step, arr_size) - 1] < item:
prev = step prev = step
step += int(math.floor(math.sqrt(n))) step += block_size
if prev >= n: if prev >= arr_size:
return -1 return -1
while arr[prev] < x: while arr[prev] < item:
prev = prev + 1 prev += 1
if prev == min(step, n): if prev == min(step, arr_size):
return -1 return -1
if arr[prev] == x: if arr[prev] == item:
return prev return prev
return -1 return -1
if __name__ == "__main__": if __name__ == "__main__":
user_input = input("Enter numbers separated by a comma:\n").strip() user_input = input("Enter numbers separated by a comma:\n").strip()
arr = [int(item) for item in user_input.split(",")] array = [int(item) for item in user_input.split(",")]
x = int(input("Enter the number to be searched:\n")) x = int(input("Enter the number to be searched:\n"))
res = jump_search(arr, x)
res = jump_search(array, x)
if res == -1: if res == -1:
print("Number not found!") print("Number not found!")
else: else:

View File

@ -4,17 +4,21 @@ This is to show simple COVID19 info fetching from worldometers site using lxml
more convenient to use in Python web projects (e.g. Django or Flask-based) more convenient to use in Python web projects (e.g. Django or Flask-based)
""" """
from collections import namedtuple from typing import NamedTuple
import requests import requests
from lxml import html # type: ignore from lxml import html # type: ignore
covid_data = namedtuple("covid_data", "cases deaths recovered")
class CovidData(NamedTuple):
cases: int
deaths: int
recovered: int
def covid_stats(url: str = "https://www.worldometers.info/coronavirus/") -> covid_data: def covid_stats(url: str = "https://www.worldometers.info/coronavirus/") -> CovidData:
xpath_str = '//div[@class = "maincounter-number"]/span/text()' xpath_str = '//div[@class = "maincounter-number"]/span/text()'
return covid_data(*html.fromstring(requests.get(url).content).xpath(xpath_str)) return CovidData(*html.fromstring(requests.get(url).content).xpath(xpath_str))
fmt = """Total COVID-19 cases in the world: {} fmt = """Total COVID-19 cases in the world: {}

View File

@ -3,12 +3,18 @@ from bs4 import BeautifulSoup
def stock_price(symbol: str = "AAPL") -> str: def stock_price(symbol: str = "AAPL") -> str:
url = f"https://in.finance.yahoo.com/quote/{symbol}?s={symbol}" url = f"https://finance.yahoo.com/quote/{symbol}?p={symbol}"
soup = BeautifulSoup(requests.get(url).text, "html.parser") yahoo_finance_source = requests.get(url, headers={"USER-AGENT": "Mozilla/5.0"}).text
class_ = "My(6px) Pos(r) smartphone_Mt(6px)" soup = BeautifulSoup(yahoo_finance_source, "html.parser")
return soup.find("div", class_=class_).find("span").text specific_fin_streamer_tag = soup.find("fin-streamer", {"data-test": "qsp-price"})
if specific_fin_streamer_tag:
text = specific_fin_streamer_tag.get_text()
return text
return "No <fin-streamer> tag with the specified data-test attribute found."
# Search for the symbol at https://finance.yahoo.com/lookup
if __name__ == "__main__": if __name__ == "__main__":
for symbol in "AAPL AMZN IBM GOOG MSFT ORCL".split(): for symbol in "AAPL AMZN IBM GOOG MSFT ORCL".split():
print(f"Current {symbol:<4} stock price is {stock_price(symbol):>8}") print(f"Current {symbol:<4} stock price is {stock_price(symbol):>8}")