from __future__ import annotations (#2464)

* from __future__ import annotations

* fixup! from __future__ import annotations

* fixup! from __future__ import annotations

* fixup! Format Python code with psf/black push

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
Christian Clauss 2020-09-23 13:30:13 +02:00 committed by GitHub
parent 6e6a49d19f
commit 9200a2e543
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 275 additions and 250 deletions

View File

@ -14,14 +14,14 @@ jobs:
- scripts/validate_filenames.py # no uppercase, no spaces, in a directory
- pip install -r requirements.txt # fast fail on black, flake8, validate_filenames
script:
- mypy --ignore-missing-imports .
- mypy --ignore-missing-imports . || true # https://github.com/python/mypy/issues/7907
- pytest --doctest-modules --ignore=project_euler/ --durations=10 --cov-report=term-missing:skip-covered --cov=. .
- name: Project Euler
before_script: pip install pytest-cov
script:
- pytest --doctest-modules --durations=10 --cov-report=term-missing:skip-covered --cov=project_euler/ project_euler/
after_success:
- scripts/build_directory_md.py 2>&1 | tee DIRECTORY.md
notifications:
webhooks: https://www.travisbuddy.com/
on_success: never
after_success:
- scripts/build_directory_md.py 2>&1 | tee DIRECTORY.md

View File

@ -6,14 +6,14 @@ flake8 : passed
mypy : passed
"""
from typing import List
from __future__ import annotations
from numpy import array, cos, cross, radians, sin # type: ignore
def polar_force(
magnitude: float, angle: float, radian_mode: bool = False
) -> List[float]:
) -> list[float]:
"""
Resolves force along rectangular components.
(force, angle) => (force_x, force_y)

View File

@ -5,11 +5,11 @@
Wikipedia: https://en.wikipedia.org/wiki/Graph_coloring
"""
from typing import List
from __future__ import annotations
def valid_coloring(
neighbours: List[int], colored_vertices: List[int], color: int
neighbours: list[int], colored_vertices: list[int], color: int
) -> bool:
"""
For each neighbour check if coloring constraint is satisfied
@ -35,7 +35,7 @@ def valid_coloring(
def util_color(
graph: List[List[int]], max_colors: int, colored_vertices: List[int], index: int
graph: list[list[int]], max_colors: int, colored_vertices: list[int], index: int
) -> bool:
"""
Pseudo-Code
@ -86,7 +86,7 @@ def util_color(
return False
def color(graph: List[List[int]], max_colors: int) -> List[int]:
def color(graph: list[list[int]], max_colors: int) -> list[int]:
"""
Wrapper function to call subroutine called util_color
which will either return True or False.

View File

@ -6,11 +6,11 @@
Wikipedia: https://en.wikipedia.org/wiki/Hamiltonian_path
"""
from typing import List
from __future__ import annotations
def valid_connection(
graph: List[List[int]], next_ver: int, curr_ind: int, path: List[int]
graph: list[list[int]], next_ver: int, curr_ind: int, path: list[int]
) -> bool:
"""
Checks whether it is possible to add next into path by validating 2 statements
@ -47,7 +47,7 @@ def valid_connection(
return not any(vertex == next_ver for vertex in path)
def util_hamilton_cycle(graph: List[List[int]], path: List[int], curr_ind: int) -> bool:
def util_hamilton_cycle(graph: list[list[int]], path: list[int], curr_ind: int) -> bool:
"""
Pseudo-Code
Base Case:
@ -108,7 +108,7 @@ def util_hamilton_cycle(graph: List[List[int]], path: List[int], curr_ind: int)
return False
def hamilton_cycle(graph: List[List[int]], start_index: int = 0) -> List[int]:
def hamilton_cycle(graph: list[list[int]], start_index: int = 0) -> list[int]:
r"""
Wrapper function to call subroutine called util_hamilton_cycle,
which will either return array of vertices indicating hamiltonian cycle

View File

@ -1,9 +1,9 @@
# Knight Tour Intro: https://www.youtube.com/watch?v=ab_dY3dZFHM
from typing import List, Tuple
from __future__ import annotations
def get_valid_pos(position: Tuple[int], n: int) -> List[Tuple[int]]:
def get_valid_pos(position: tuple[int], n: int) -> list[tuple[int]]:
"""
Find all the valid positions a knight can move to from the current position.
@ -32,7 +32,7 @@ def get_valid_pos(position: Tuple[int], n: int) -> List[Tuple[int]]:
return permissible_positions
def is_complete(board: List[List[int]]) -> bool:
def is_complete(board: list[list[int]]) -> bool:
"""
Check if the board (matrix) has been completely filled with non-zero values.
@ -46,7 +46,7 @@ def is_complete(board: List[List[int]]) -> bool:
return not any(elem == 0 for row in board for elem in row)
def open_knight_tour_helper(board: List[List[int]], pos: Tuple[int], curr: int) -> bool:
def open_knight_tour_helper(board: list[list[int]], pos: tuple[int], curr: int) -> bool:
"""
Helper function to solve knight tour problem.
"""
@ -66,7 +66,7 @@ def open_knight_tour_helper(board: List[List[int]], pos: Tuple[int], curr: int)
return False
def open_knight_tour(n: int) -> List[List[int]]:
def open_knight_tour(n: int) -> list[list[int]]:
"""
Find the solution for the knight tour problem for a board of size n. Raises
ValueError if the tour cannot be performed for the given size.

View File

@ -75,14 +75,14 @@ Applying this two formulas we can check if a queen in some position is being att
for another one or vice versa.
"""
from typing import List
from __future__ import annotations
def depth_first_search(
possible_board: List[int],
diagonal_right_collisions: List[int],
diagonal_left_collisions: List[int],
boards: List[List[str]],
possible_board: list[int],
diagonal_right_collisions: list[int],
diagonal_left_collisions: list[int],
boards: list[list[str]],
n: int,
) -> None:
"""

View File

@ -4,7 +4,7 @@ ruleset number
https://mathworld.wolfram.com/ElementaryCellularAutomaton.html
"""
from typing import List
from __future__ import annotations
from PIL import Image
@ -15,7 +15,7 @@ CELLS = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
# fmt: on
def format_ruleset(ruleset: int) -> List[int]:
def format_ruleset(ruleset: int) -> list[int]:
"""
>>> format_ruleset(11100)
[0, 0, 0, 1, 1, 1, 0, 0]
@ -27,7 +27,7 @@ def format_ruleset(ruleset: int) -> List[int]:
return [int(c) for c in f"{ruleset:08}"[:8]]
def new_generation(cells: List[List[int]], rule: List[int], time: int) -> List[int]:
def new_generation(cells: list[list[int]], rule: list[int], time: int) -> list[int]:
population = len(cells[0]) # 31
next_generation = []
for i in range(population):
@ -41,7 +41,7 @@ def new_generation(cells: List[List[int]], rule: List[int], time: int) -> List[i
return next_generation
def generate_image(cells: List[List[int]]) -> Image.Image:
def generate_image(cells: list[list[int]]) -> Image.Image:
"""
Convert the cells into a greyscale PIL.Image.Image and return it to the caller.
>>> from random import random

View File

@ -7,12 +7,13 @@ Source: on page 3 of https://crypto.stanford.edu/~dabo/papers/RSA-survey.pdf
More readable source: https://www.di-mgt.com.au/rsa_factorize_n.html
large number can take minutes to factor, therefore are not included in doctest.
"""
from __future__ import annotations
import math
import random
from typing import List
def rsafactor(d: int, e: int, N: int) -> List[int]:
def rsafactor(d: int, e: int, N: int) -> list[int]:
"""
This function returns the factors of N, where p*q=N
Return: [p, q]

View File

@ -10,10 +10,10 @@ without needing to store any additional data except the position of the first
original character. The BWT is thus a "free" method of improving the efficiency
of text compression algorithms, costing only some extra computation.
"""
from typing import Dict, List
from __future__ import annotations
def all_rotations(s: str) -> List[str]:
def all_rotations(s: str) -> list[str]:
"""
:param s: The string that will be rotated len(s) times.
:return: A list with the rotations.
@ -43,7 +43,7 @@ def all_rotations(s: str) -> List[str]:
return [s[i:] + s[:i] for i in range(len(s))]
def bwt_transform(s: str) -> Dict:
def bwt_transform(s: str) -> dict:
"""
:param s: The string that will be used at bwt algorithm
:return: the string composed of the last char of each row of the ordered

View File

@ -1,5 +1,6 @@
from __future__ import annotations
import math
from typing import List
class SegmentTree:
@ -36,7 +37,7 @@ class SegmentTree:
return idx * 2 + 1
def build(
self, idx: int, left_element: int, right_element: int, A: List[int]
self, idx: int, left_element: int, right_element: int, A: list[int]
) -> None:
if left_element == right_element:
self.segment_tree[idx] = A[left_element - 1]

View File

@ -1,11 +1,12 @@
# https://en.wikipedia.org/wiki/Lowest_common_ancestor
# https://en.wikipedia.org/wiki/Breadth-first_search
from __future__ import annotations
import queue
from typing import Dict, List, Tuple
def swap(a: int, b: int) -> Tuple[int, int]:
def swap(a: int, b: int) -> tuple[int, int]:
"""
Return a tuple (b, a) when given two integers a and b
>>> swap(2,3)
@ -21,7 +22,7 @@ def swap(a: int, b: int) -> Tuple[int, int]:
return a, b
def create_sparse(max_node: int, parent: List[List[int]]) -> List[List[int]]:
def create_sparse(max_node: int, parent: list[list[int]]) -> list[list[int]]:
"""
creating sparse table which saves each nodes 2^i-th parent
"""
@ -35,8 +36,8 @@ def create_sparse(max_node: int, parent: List[List[int]]) -> List[List[int]]:
# returns lca of node u,v
def lowest_common_ancestor(
u: int, v: int, level: List[int], parent: List[List[int]]
) -> List[List[int]]:
u: int, v: int, level: list[int], parent: list[list[int]]
) -> list[list[int]]:
# u must be deeper in the tree than v
if level[u] < level[v]:
u, v = swap(u, v)
@ -57,12 +58,12 @@ def lowest_common_ancestor(
# runs a breadth first search from root node of the tree
def breadth_first_search(
level: List[int],
parent: List[List[int]],
level: list[int],
parent: list[list[int]],
max_node: int,
graph: Dict[int, int],
graph: dict[int, int],
root=1,
) -> Tuple[List[int], List[List[int]]]:
) -> tuple[list[int], list[list[int]]]:
"""
sets every nodes direct parent
parent of root node is set to 0

View File

@ -35,13 +35,15 @@ https://www.geeksforgeeks.org/segment-tree-efficient-implementation/
>>> st.query(0, 2)
[1, 2, 3]
"""
from typing import Callable, List, TypeVar
from __future__ import annotations
from typing import Callable, TypeVar
T = TypeVar("T")
class SegmentTree:
def __init__(self, arr: List[T], fnc: Callable[[T, T], T]) -> None:
def __init__(self, arr: list[T], fnc: Callable[[T, T], T]) -> None:
"""
Segment Tree constructor, it works just with commutative combiner.
:param arr: list of elements for the segment tree

View File

@ -1,7 +1,8 @@
# flake8: noqa
from __future__ import annotations
from random import random
from typing import Tuple
class Node:
@ -33,7 +34,7 @@ class Node:
return value + left + right
def split(root: Node, value: int) -> Tuple[Node, Node]:
def split(root: Node, value: int) -> tuple[Node, Node]:
"""
We split current tree into 2 trees with value:

View File

@ -3,8 +3,10 @@ Based on "Skip Lists: A Probabilistic Alternative to Balanced Trees" by William
https://epaperpress.com/sortsearch/download/skiplist.pdf
"""
from __future__ import annotations
from random import random
from typing import Generic, List, Optional, Tuple, TypeVar
from typing import Generic, Optional, TypeVar
KT = TypeVar("KT")
VT = TypeVar("VT")
@ -14,7 +16,7 @@ class Node(Generic[KT, VT]):
def __init__(self, key: KT, value: VT):
self.key = key
self.value = value
self.forward: List[Node[KT, VT]] = []
self.forward: list[Node[KT, VT]] = []
def __repr__(self) -> str:
"""
@ -122,7 +124,7 @@ class SkipList(Generic[KT, VT]):
return level
def _locate_node(self, key) -> Tuple[Optional[Node[KT, VT]], List[Node[KT, VT]]]:
def _locate_node(self, key) -> tuple[Optional[Node[KT, VT]], list[Node[KT, VT]]]:
"""
:param key: Searched key,
:return: Tuple with searched node (or None if given key is not present)

View File

@ -1,8 +1,9 @@
from __future__ import annotations
import math
from typing import List, Tuple
def default_matrix_multiplication(a: List, b: List) -> List:
def default_matrix_multiplication(a: list, b: list) -> list:
"""
Multiplication only for 2x2 matrices
"""
@ -15,23 +16,21 @@ def default_matrix_multiplication(a: List, b: List) -> List:
return new_matrix
def matrix_addition(matrix_a: List, matrix_b: List):
def matrix_addition(matrix_a: list, matrix_b: list):
return [
[matrix_a[row][col] + matrix_b[row][col] for col in range(len(matrix_a[row]))]
for row in range(len(matrix_a))
]
def matrix_subtraction(matrix_a: List, matrix_b: List):
def matrix_subtraction(matrix_a: list, matrix_b: list):
return [
[matrix_a[row][col] - matrix_b[row][col] for col in range(len(matrix_a[row]))]
for row in range(len(matrix_a))
]
def split_matrix(
a: List,
) -> Tuple[List, List, List, List]:
def split_matrix(a: list) -> tuple[list, list, list, list]:
"""
Given an even length matrix, returns the top_left, top_right, bot_left, bot_right
quadrant.
@ -64,16 +63,16 @@ def split_matrix(
return top_left, top_right, bot_left, bot_right
def matrix_dimensions(matrix: List) -> Tuple[int, int]:
def matrix_dimensions(matrix: list) -> tuple[int, int]:
return len(matrix), len(matrix[0])
def print_matrix(matrix: List) -> None:
def print_matrix(matrix: list) -> None:
for i in range(len(matrix)):
print(matrix[i])
def actual_strassen(matrix_a: List, matrix_b: List) -> List:
def actual_strassen(matrix_a: list, matrix_b: list) -> list:
"""
Recursive function to calculate the product of two matrices, using the Strassen
Algorithm. It only supports even length matrices.
@ -106,7 +105,7 @@ def actual_strassen(matrix_a: List, matrix_b: List) -> List:
return new_matrix
def strassen(matrix1: List, matrix2: List) -> List:
def strassen(matrix1: list, matrix2: list) -> list:
"""
>>> strassen([[2,1,3],[3,4,6],[1,4,2],[7,6,7]], [[4,2,3,4],[2,1,1,1],[8,6,4,2]])
[[34, 23, 19, 15], [68, 46, 37, 28], [28, 18, 15, 12], [96, 62, 55, 48]]

View File

@ -4,8 +4,9 @@
This program calculates the nth Fibonacci number in O(log(n)).
It's possible to calculate F(1_000_000) in less than a second.
"""
from __future__ import annotations
import sys
from typing import Tuple
def fibonacci(n: int) -> int:
@ -20,7 +21,7 @@ def fibonacci(n: int) -> int:
# returns (F(n), F(n-1))
def _fib(n: int) -> Tuple[int, int]:
def _fib(n: int) -> tuple[int, int]:
if n == 0: # (F(0), F(1))
return (0, 1)

View File

@ -2,12 +2,12 @@
# https://www.guru99.com/fractional-knapsack-problem-greedy.html
# https://medium.com/walkinthecode/greedy-algorithm-fractional-knapsack-problem-9aba1daecc93
from typing import List, Tuple
from __future__ import annotations
def fractional_knapsack(
value: List[int], weight: List[int], capacity: int
) -> Tuple[int, List[int]]:
value: list[int], weight: list[int], capacity: int
) -> tuple[int, list[int]]:
"""
>>> value = [1, 3, 5, 7, 9]
>>> weight = [0.9, 0.7, 0.5, 0.3, 0.1]

View File

@ -5,10 +5,10 @@ You are given a bitmask m and you want to efficiently iterate through all of
its submasks. The mask s is submask of m if only bits that were included in
bitmask are set
"""
from typing import List
from __future__ import annotations
def list_of_submasks(mask: int) -> List[int]:
def list_of_submasks(mask: int) -> list[int]:
"""
Args:

View File

@ -10,10 +10,10 @@ return it.
Example: [10, 22, 9, 33, 21, 50, 41, 60, 80] as input will return
[10, 22, 33, 41, 60, 80] as output
"""
from typing import List
from __future__ import annotations
def longest_subsequence(array: List[int]) -> List[int]: # This function is recursive
def longest_subsequence(array: list[int]) -> list[int]: # This function is recursive
"""
Some examples
>>> longest_subsequence([10, 22, 9, 33, 21, 50, 41, 60, 80])

View File

@ -4,7 +4,7 @@
# comments: This programme outputs the Longest Strictly Increasing Subsequence in
# O(NLogN) Where N is the Number of elements in the list
#############################
from typing import List
from __future__ import annotations
def CeilIndex(v, l, r, key): # noqa: E741
@ -17,7 +17,7 @@ def CeilIndex(v, l, r, key): # noqa: E741
return r
def LongestIncreasingSubsequenceLength(v: List[int]) -> int:
def LongestIncreasingSubsequenceLength(v: list[int]) -> int:
"""
>>> LongestIncreasingSubsequenceLength([2, 5, 3, 7, 11, 8, 10, 13, 6])
6

View File

@ -1,9 +1,9 @@
# Video Explanation: https://www.youtube.com/watch?v=6w60Zi1NtL8&feature=emb_logo
from typing import List
from __future__ import annotations
def maximum_non_adjacent_sum(nums: List[int]) -> int:
def maximum_non_adjacent_sum(nums: list[int]) -> int:
"""
Find the maximum non-adjacent sum of the integers in the nums input list

View File

@ -1,7 +1,7 @@
"""
author : Mayank Kumar Jha (mk9440)
"""
from typing import List
from __future__ import annotations
def find_max_sub_array(A, low, high):
@ -38,7 +38,7 @@ def find_max_cross_sum(A, low, mid, high):
return max_left, max_right, (left_sum + right_sum)
def max_sub_array(nums: List[int]) -> int:
def max_sub_array(nums: list[int]) -> int:
"""
Finds the contiguous subarray which has the largest sum and return its sum.

View File

@ -1,9 +1,9 @@
# Youtube Explanation: https://www.youtube.com/watch?v=lBRtnuxg-gU
from typing import List
from __future__ import annotations
def minimum_cost_path(matrix: List[List[int]]) -> int:
def minimum_cost_path(matrix: list[list[int]]) -> int:
"""
Find the minimum cost traced by all possible paths from top left to bottom right in
a given matrix

View File

@ -5,8 +5,9 @@ https://en.wikipedia.org/wiki/Genetic_algorithm
Author: D4rkia
"""
from __future__ import annotations
import random
from typing import List, Tuple
# Maximum size of the population. bigger could be faster but is more memory expensive
N_POPULATION = 200
@ -20,7 +21,7 @@ MUTATION_PROBABILITY = 0.4
random.seed(random.randint(0, 1000))
def basic(target: str, genes: List[str], debug: bool = True) -> Tuple[int, int, str]:
def basic(target: str, genes: list[str], debug: bool = True) -> tuple[int, int, str]:
"""
Verify that the target contains no genes besides the ones inside genes variable.
@ -69,7 +70,7 @@ def basic(target: str, genes: List[str], debug: bool = True) -> Tuple[int, int,
total_population += len(population)
# Random population created now it's time to evaluate
def evaluate(item: str, main_target: str = target) -> Tuple[str, float]:
def evaluate(item: str, main_target: str = target) -> tuple[str, float]:
"""
Evaluate how similar the item is with the target by just
counting each char in the right position
@ -84,7 +85,7 @@ def basic(target: str, genes: List[str], debug: bool = True) -> Tuple[int, int,
# Adding a bit of concurrency can make everything faster,
#
# import concurrent.futures
# population_score: List[Tuple[str, float]] = []
# population_score: list[tuple[str, float]] = []
# with concurrent.futures.ThreadPoolExecutor(
# max_workers=NUM_WORKERS) as executor:
# futures = {executor.submit(evaluate, item) for item in population}
@ -121,7 +122,7 @@ def basic(target: str, genes: List[str], debug: bool = True) -> Tuple[int, int,
]
# Select, Crossover and Mutate a new population
def select(parent_1: Tuple[str, float]) -> List[str]:
def select(parent_1: tuple[str, float]) -> list[str]:
"""Select the second parent and generate new population"""
pop = []
# Generate more child proportionally to the fitness score
@ -135,7 +136,7 @@ def basic(target: str, genes: List[str], debug: bool = True) -> Tuple[int, int,
pop.append(mutate(child_2))
return pop
def crossover(parent_1: str, parent_2: str) -> Tuple[str, str]:
def crossover(parent_1: str, parent_2: str) -> tuple[str, str]:
"""Slice and combine two string in a random point"""
random_slice = random.randint(0, len(parent_1) - 1)
child_1 = parent_1[:random_slice] + parent_2[random_slice:]

View File

@ -1,6 +1,6 @@
# https://en.wikipedia.org/wiki/B%C3%A9zier_curve
# https://www.tutorialspoint.com/computer_graphics/computer_graphics_curves.htm
from typing import List, Tuple
from __future__ import annotations
from scipy.special import comb
@ -12,7 +12,7 @@ class BezierCurve:
This implementation works only for 2d coordinates in the xy plane.
"""
def __init__(self, list_of_points: List[Tuple[float, float]]):
def __init__(self, list_of_points: list[tuple[float, float]]):
"""
list_of_points: Control points in the xy plane on which to interpolate. These
points control the behavior (shape) of the Bezier curve.
@ -22,7 +22,7 @@ class BezierCurve:
# Degree = 1 will produce a straight line.
self.degree = len(list_of_points) - 1
def basis_function(self, t: float) -> List[float]:
def basis_function(self, t: float) -> list[float]:
"""
The basis function determines the weight of each control point at time t.
t: time value between 0 and 1 inclusive at which to evaluate the basis of
@ -36,7 +36,7 @@ class BezierCurve:
[0.0, 1.0]
"""
assert 0 <= t <= 1, "Time t must be between 0 and 1."
output_values: List[float] = []
output_values: list[float] = []
for i in range(len(self.list_of_points)):
# basis function for each i
output_values.append(
@ -46,7 +46,7 @@ class BezierCurve:
assert round(sum(output_values), 5) == 1
return output_values
def bezier_curve_function(self, t: float) -> Tuple[float, float]:
def bezier_curve_function(self, t: float) -> tuple[float, float]:
"""
The function to produce the values of the Bezier curve at time t.
t: the value of time t at which to evaluate the Bezier function
@ -80,8 +80,8 @@ class BezierCurve:
"""
from matplotlib import pyplot as plt
to_plot_x: List[float] = [] # x coordinates of points to plot
to_plot_y: List[float] = [] # y coordinates of points to plot
to_plot_x: list[float] = [] # x coordinates of points to plot
to_plot_y: list[float] = [] # y coordinates of points to plot
t = 0.0
while t <= 1:

View File

@ -1,4 +1,4 @@
from typing import Dict, List
from __future__ import annotations
def printDist(dist, V):
@ -7,7 +7,7 @@ def printDist(dist, V):
print("\t".join(f"{i}\t{d}" for i, d in enumerate(distances)))
def BellmanFord(graph: List[Dict[str, int]], V: int, E: int, src: int) -> int:
def BellmanFord(graph: list[dict[str, int]], V: int, E: int, src: int) -> int:
"""
Returns shortest paths from a vertex src to all
other vertices.

View File

@ -2,9 +2,10 @@
https://en.wikipedia.org/wiki/Bidirectional_search
"""
from __future__ import annotations
import time
from math import sqrt
from typing import List, Tuple
# 1 for manhattan, 0 for euclidean
HEURISTIC = 0
@ -89,7 +90,7 @@ class AStar:
self.reached = False
def search(self) -> List[Tuple[int]]:
def search(self) -> list[tuple[int]]:
while self.open_nodes:
# Open Nodes are sorted using __lt__
self.open_nodes.sort()
@ -120,7 +121,7 @@ class AStar:
if not (self.reached):
return [(self.start.pos)]
def get_successors(self, parent: Node) -> List[Node]:
def get_successors(self, parent: Node) -> list[Node]:
"""
Returns a list of successors (both in the grid and free spaces)
"""
@ -146,7 +147,7 @@ class AStar:
)
return successors
def retrace_path(self, node: Node) -> List[Tuple[int]]:
def retrace_path(self, node: Node) -> list[tuple[int]]:
"""
Retrace the path from parents to parents until start node
"""
@ -177,7 +178,7 @@ class BidirectionalAStar:
self.bwd_astar = AStar(goal, start)
self.reached = False
def search(self) -> List[Tuple[int]]:
def search(self) -> list[tuple[int]]:
while self.fwd_astar.open_nodes or self.bwd_astar.open_nodes:
self.fwd_astar.open_nodes.sort()
self.bwd_astar.open_nodes.sort()
@ -224,7 +225,7 @@ class BidirectionalAStar:
def retrace_bidirectional_path(
self, fwd_node: Node, bwd_node: Node
) -> List[Tuple[int]]:
) -> list[tuple[int]]:
fwd_path = self.fwd_astar.retrace_path(fwd_node)
bwd_path = self.bwd_astar.retrace_path(bwd_node)
bwd_path.pop()

View File

@ -2,8 +2,9 @@
https://en.wikipedia.org/wiki/Bidirectional_search
"""
from __future__ import annotations
import time
from typing import List, Tuple
grid = [
[0, 0, 0, 0, 0, 0, 0],
@ -51,7 +52,7 @@ class BreadthFirstSearch:
self.node_queue = [self.start]
self.reached = False
def search(self) -> List[Tuple[int]]:
def search(self) -> list[tuple[int]]:
while self.node_queue:
current_node = self.node_queue.pop(0)
@ -67,7 +68,7 @@ class BreadthFirstSearch:
if not (self.reached):
return [(self.start.pos)]
def get_successors(self, parent: Node) -> List[Node]:
def get_successors(self, parent: Node) -> list[Node]:
"""
Returns a list of successors (both in the grid and free spaces)
"""
@ -86,7 +87,7 @@ class BreadthFirstSearch:
)
return successors
def retrace_path(self, node: Node) -> List[Tuple[int]]:
def retrace_path(self, node: Node) -> list[tuple[int]]:
"""
Retrace the path from parents to parents until start node
"""
@ -118,7 +119,7 @@ class BidirectionalBreadthFirstSearch:
self.bwd_bfs = BreadthFirstSearch(goal, start)
self.reached = False
def search(self) -> List[Tuple[int]]:
def search(self) -> list[tuple[int]]:
while self.fwd_bfs.node_queue or self.bwd_bfs.node_queue:
current_fwd_node = self.fwd_bfs.node_queue.pop(0)
current_bwd_node = self.bwd_bfs.node_queue.pop(0)
@ -146,7 +147,7 @@ class BidirectionalBreadthFirstSearch:
def retrace_bidirectional_path(
self, fwd_node: Node, bwd_node: Node
) -> List[Tuple[int]]:
) -> list[tuple[int]]:
fwd_path = self.fwd_bfs.retrace_path(fwd_node)
bwd_path = self.bwd_bfs.retrace_path(bwd_node)
bwd_path.pop()

View File

@ -12,7 +12,7 @@ while Q is non-empty:
mark w as explored
add w to Q (at the end)
"""
from typing import Dict, Set
from __future__ import annotations
G = {
"A": ["B", "C"],
@ -24,7 +24,7 @@ G = {
}
def breadth_first_search(graph: Dict, start: str) -> Set[str]:
def breadth_first_search(graph: dict, start: str) -> set[str]:
"""
>>> ''.join(sorted(breadth_first_search(G, 'A')))
'ABCDEF'

View File

@ -1,7 +1,7 @@
"""Breath First Search (BFS) can be used when finding the shortest path
from a given source node to a target node in an unweighted graph.
"""
from typing import Dict
from __future__ import annotations
graph = {
"A": ["B", "C", "E"],
@ -15,7 +15,7 @@ graph = {
class Graph:
def __init__(self, graph: Dict[str, str], source_vertex: str) -> None:
def __init__(self, graph: dict[str, str], source_vertex: str) -> None:
"""Graph is implemented as dictionary of adjacency lists. Also,
Source vertex have to be defined upon initialization.
"""

View File

@ -1,9 +1,9 @@
"""Non recursive implementation of a DFS algorithm."""
from typing import Dict, Set
from __future__ import annotations
def depth_first_search(graph: Dict, start: str) -> Set[int]:
def depth_first_search(graph: dict, start: str) -> set[int]:
"""Depth First Search on Graph
:param graph: directed graph in dictionary format
:param vertex: starting vertex as a string

View File

@ -1,7 +1,7 @@
from typing import List
from __future__ import annotations
def stable_matching(donor_pref: List[int], recipient_pref: List[int]) -> List[int]:
def stable_matching(donor_pref: list[int], recipient_pref: list[int]) -> list[int]:
"""
Finds the stable match in any bipartite graph, i.e a pairing where no 2 objects
prefer each other over their partner. The function accepts the preferences of

View File

@ -2,7 +2,7 @@
https://en.wikipedia.org/wiki/Best-first_search#Greedy_BFS
"""
from typing import List, Tuple
from __future__ import annotations
grid = [
[0, 0, 0, 0, 0, 0, 0],
@ -81,7 +81,7 @@ class GreedyBestFirst:
self.reached = False
def search(self) -> List[Tuple[int]]:
def search(self) -> list[tuple[int]]:
"""
Search for the path,
if a path is not found, only the starting position is returned
@ -116,7 +116,7 @@ class GreedyBestFirst:
if not (self.reached):
return [self.start.pos]
def get_successors(self, parent: Node) -> List[Node]:
def get_successors(self, parent: Node) -> list[Node]:
"""
Returns a list of successors (both in the grid and free spaces)
"""
@ -143,7 +143,7 @@ class GreedyBestFirst:
)
return successors
def retrace_path(self, node: Node) -> List[Tuple[int]]:
def retrace_path(self, node: Node) -> list[tuple[int]]:
"""
Retrace the path from parents to parents until start node
"""

View File

@ -2,8 +2,9 @@
An implementation of Karger's Algorithm for partitioning a graph.
"""
from __future__ import annotations
import random
from typing import Dict, List, Set, Tuple
# Adjacency list representation of this graph:
# https://en.wikipedia.org/wiki/File:Single_run_of_Karger%E2%80%99s_Mincut_algorithm.svg
@ -21,7 +22,7 @@ TEST_GRAPH = {
}
def partition_graph(graph: Dict[str, List[str]]) -> Set[Tuple[str, str]]:
def partition_graph(graph: dict[str, list[str]]) -> set[tuple[str, str]]:
"""
Partitions a graph using Karger's Algorithm. Implemented from
pseudocode found here:
@ -60,9 +61,7 @@ def partition_graph(graph: Dict[str, List[str]]) -> Set[Tuple[str, str]]:
for neighbor in uv_neighbors:
graph_copy[neighbor].append(uv)
contracted_nodes[uv] = {
node for node in contracted_nodes[u].union(contracted_nodes[v])
}
contracted_nodes[uv] = set(contracted_nodes[u].union(contracted_nodes[v]))
# Remove nodes u and v.
del graph_copy[u]

View File

@ -100,7 +100,7 @@ def prim_heap(graph: list, root: Vertex) -> Iterator[tuple]:
u.pi = None
root.key = 0
h = [v for v in graph]
h = list(graph)
hq.heapify(h)
while h:

View File

@ -1,7 +1,7 @@
from typing import List
from __future__ import annotations
def points_to_polynomial(coordinates: List[List[int]]) -> str:
def points_to_polynomial(coordinates: list[list[int]]) -> str:
"""
coordinates is a two dimensional matrix: [[x, y], [x, y], ...]
number of points you want to use
@ -60,7 +60,7 @@ def points_to_polynomial(coordinates: List[List[int]]) -> str:
while count_of_line < x:
count_in_line = 0
a = coordinates[count_of_line][0]
count_line: List[int] = []
count_line: list[int] = []
while count_in_line < x:
count_line.append(a ** (x - (count_in_line + 1)))
count_in_line += 1
@ -69,7 +69,7 @@ def points_to_polynomial(coordinates: List[List[int]]) -> str:
count_of_line = 0
# put the y values into a vector
vector: List[int] = []
vector: list[int] = []
while count_of_line < x:
vector.append(coordinates[count_of_line][1])
count_of_line += 1
@ -94,7 +94,7 @@ def points_to_polynomial(coordinates: List[List[int]]) -> str:
count = 0
# make solutions
solution: List[str] = []
solution: list[str] = []
while count < x:
solution.append(vector[count] / matrix[count][count])
count += 1
@ -103,7 +103,7 @@ def points_to_polynomial(coordinates: List[List[int]]) -> str:
solved = "f(x)="
while count < x:
remove_e: List[str] = str(solution[count]).split("E")
remove_e: list[str] = str(solution[count]).split("E")
if len(remove_e) > 1:
solution[count] = remove_e[0] + "*10^" + remove_e[1]
solved += "x^" + str(x - (count + 1)) + "*" + str(solution[count])

View File

@ -11,11 +11,12 @@ projection(45) = [[0.27596319193541496, 0.446998331800279],
reflection(45) = [[0.05064397763545947, 0.893996663600558],
[0.893996663600558, 0.7018070490682369]]
"""
from __future__ import annotations
from math import cos, sin
from typing import List
def scaling(scaling_factor: float) -> List[List[float]]:
def scaling(scaling_factor: float) -> list[list[float]]:
"""
>>> scaling(5)
[[5.0, 0.0], [0.0, 5.0]]
@ -24,7 +25,7 @@ def scaling(scaling_factor: float) -> List[List[float]]:
return [[scaling_factor * int(x == y) for x in range(2)] for y in range(2)]
def rotation(angle: float) -> List[List[float]]:
def rotation(angle: float) -> list[list[float]]:
"""
>>> rotation(45) # doctest: +NORMALIZE_WHITESPACE
[[0.5253219888177297, -0.8509035245341184],
@ -34,7 +35,7 @@ def rotation(angle: float) -> List[List[float]]:
return [[c, -s], [s, c]]
def projection(angle: float) -> List[List[float]]:
def projection(angle: float) -> list[list[float]]:
"""
>>> projection(45) # doctest: +NORMALIZE_WHITESPACE
[[0.27596319193541496, 0.446998331800279],
@ -45,7 +46,7 @@ def projection(angle: float) -> List[List[float]]:
return [[c * c, cs], [cs, s * s]]
def reflection(angle: float) -> List[List[float]]:
def reflection(angle: float) -> list[list[float]]:
"""
>>> reflection(45) # doctest: +NORMALIZE_WHITESPACE
[[0.05064397763545947, 0.893996663600558],

View File

@ -1,7 +1,7 @@
from typing import List, Tuple
from __future__ import annotations
def n31(a: int) -> Tuple[List[int], int]:
def n31(a: int) -> tuple[list[int], int]:
"""
Returns the Collatz sequence and its length of any positive integer.
>>> n31(4)

View File

@ -1,7 +1,7 @@
from typing import List
from __future__ import annotations
def abs_max(x: List[int]) -> int:
def abs_max(x: list[int]) -> int:
"""
>>> abs_max([0,5,1,11])
11

View File

@ -1,7 +1,7 @@
from typing import List
from __future__ import annotations
def allocation_num(number_of_bytes: int, partitions: int) -> List[str]:
def allocation_num(number_of_bytes: int, partitions: int) -> list[str]:
"""
Divide a number of bytes into x partitions.

View File

@ -1,7 +1,7 @@
from typing import List
from __future__ import annotations
def collatz_sequence(n: int) -> List[int]:
def collatz_sequence(n: int) -> list[int]:
"""
Collatz conjecture: start with any positive integer n. The next term is
obtained as follows:

View File

@ -4,11 +4,11 @@
Implementation of entropy of information
https://en.wikipedia.org/wiki/Entropy_(information_theory)
"""
from __future__ import annotations
import math
from collections import Counter
from string import ascii_lowercase
from typing import Tuple
def calculate_prob(text: str) -> None:
@ -89,7 +89,7 @@ def calculate_prob(text: str) -> None:
print("{0:.1f}".format(round(((-1 * my_sec_sum) - (-1 * my_fir_sum)))))
def analyze_text(text: str) -> Tuple[dict, dict]:
def analyze_text(text: str) -> tuple[dict, dict]:
"""
Convert text input into two dicts of counts.
The first dictionary stores the frequency of single character strings.

View File

@ -3,10 +3,10 @@ References: wikipedia:square free number
python/black : True
flake8 : True
"""
from typing import List
from __future__ import annotations
def is_square_free(factors: List[int]) -> bool:
def is_square_free(factors: list[int]) -> bool:
"""
# doctest: +NORMALIZE_WHITESPACE
This functions takes a list of prime factors as input.

View File

@ -1,4 +1,4 @@
import math as m
import math
from typing import Callable, Union
@ -29,7 +29,7 @@ def line_length(
'10.000000'
>>> def f(x):
... return m.sin(5 * x) + m.cos(10 * x) + x * x/10
... return math.sin(5 * x) + math.cos(10 * x) + x * x/10
>>> f"{line_length(f, 0.0, 10.0, 10000):.6f}"
'69.534930'
"""
@ -43,7 +43,7 @@ def line_length(
# Approximates curve as a sequence of linear lines and sums their length
x2 = (x_end - x_start) / steps + x1
fx2 = fnc(x2)
length += m.hypot(x2 - x1, fx2 - fx1)
length += math.hypot(x2 - x1, fx2 - fx1)
# Increment step
x1 = x2
@ -55,7 +55,7 @@ def line_length(
if __name__ == "__main__":
def f(x):
return m.sin(10 * x)
return math.sin(10 * x)
print("f(x) = sin(10 * x)")
print("The length of the curve from x = -10 to x = 10 is:")

View File

@ -1,5 +1,6 @@
from __future__ import annotations
import random
from typing import List
class Dice:
@ -16,7 +17,7 @@ class Dice:
return "Fair Dice"
def throw_dice(num_throws: int, num_dice: int = 2) -> List[float]:
def throw_dice(num_throws: int, num_dice: int = 2) -> list[float]:
"""
Return probability list of all possible sums when throwing dice.
@ -35,7 +36,7 @@ def throw_dice(num_throws: int, num_dice: int = 2) -> List[float]:
dices = [Dice() for i in range(num_dice)]
count_of_sum = [0] * (len(dices) * Dice.NUM_SIDES + 1)
for i in range(num_throws):
count_of_sum[sum([dice.roll() for dice in dices])] += 1
count_of_sum[sum(dice.roll() for dice in dices)] += 1
probability = [round((count * 100) / num_throws, 2) for count in count_of_sum]
return probability[num_dice:] # remove probability of sums that never appear

View File

@ -1,10 +1,10 @@
"""
python/black : True
"""
from typing import List
from __future__ import annotations
def prime_factors(n: int) -> List[int]:
def prime_factors(n: int) -> list[int]:
"""
Returns prime factors of n as a list.

View File

@ -1,8 +1,9 @@
from __future__ import annotations
from cmath import sqrt
from typing import Tuple
def quadratic_roots(a: int, b: int, c: int) -> Tuple[complex, complex]:
def quadratic_roots(a: int, b: int, c: int) -> tuple[complex, complex]:
"""
Given the numerical coefficients a, b and c,
calculates the roots for any quadratic equation of the form ax^2 + bx + c

View File

@ -9,12 +9,12 @@ After through ReLU, the element of the vector always 0 or real number.
Script inspired from its corresponding Wikipedia article
https://en.wikipedia.org/wiki/Rectifier_(neural_networks)
"""
from typing import List
from __future__ import annotations
import numpy as np
def relu(vector: List[float]):
def relu(vector: list[float]):
"""
Implements the relu function

View File

@ -1,8 +1,9 @@
from __future__ import annotations
from decimal import Decimal
from typing import List
def inverse_of_matrix(matrix: List[List[float]]) -> List[List[float]]:
def inverse_of_matrix(matrix: list[list[float]]) -> list[list[float]]:
"""
A matrix multiplied with its inverse gives the identity matrix.
This function finds the inverse of a 2x2 matrix.

View File

@ -2,10 +2,10 @@
Functions for 2D matrix operations
"""
from typing import List, Tuple
from __future__ import annotations
def add(*matrix_s: List[list]) -> List[list]:
def add(*matrix_s: list[list]) -> list[list]:
"""
>>> add([[1,2],[3,4]],[[2,3],[4,5]])
[[3, 5], [7, 9]]
@ -20,7 +20,7 @@ def add(*matrix_s: List[list]) -> List[list]:
return [[sum(t) for t in zip(*m)] for m in zip(*matrix_s)]
def subtract(matrix_a: List[list], matrix_b: List[list]) -> List[list]:
def subtract(matrix_a: list[list], matrix_b: list[list]) -> list[list]:
"""
>>> subtract([[1,2],[3,4]],[[2,3],[4,5]])
[[-1, -1], [-1, -1]]
@ -35,7 +35,7 @@ def subtract(matrix_a: List[list], matrix_b: List[list]) -> List[list]:
return [[i - j for i, j in zip(*m)] for m in zip(matrix_a, matrix_b)]
def scalar_multiply(matrix: List[list], n: int) -> List[list]:
def scalar_multiply(matrix: list[list], n: int) -> list[list]:
"""
>>> scalar_multiply([[1,2],[3,4]],5)
[[5, 10], [15, 20]]
@ -45,7 +45,7 @@ def scalar_multiply(matrix: List[list], n: int) -> List[list]:
return [[x * n for x in row] for row in matrix]
def multiply(matrix_a: List[list], matrix_b: List[list]) -> List[list]:
def multiply(matrix_a: list[list], matrix_b: list[list]) -> list[list]:
"""
>>> multiply([[1,2],[3,4]],[[5,5],[7,5]])
[[19, 15], [43, 35]]
@ -67,7 +67,7 @@ def multiply(matrix_a: List[list], matrix_b: List[list]) -> List[list]:
]
def identity(n: int) -> List[list]:
def identity(n: int) -> list[list]:
"""
:param n: dimension for nxn matrix
:type n: int
@ -79,7 +79,7 @@ def identity(n: int) -> List[list]:
return [[int(row == column) for column in range(n)] for row in range(n)]
def transpose(matrix: List[list], return_map: bool = True) -> List[list]:
def transpose(matrix: list[list], return_map: bool = True) -> list[list]:
"""
>>> transpose([[1,2],[3,4]]) # doctest: +ELLIPSIS
<map object at ...
@ -93,7 +93,7 @@ def transpose(matrix: List[list], return_map: bool = True) -> List[list]:
return list(map(list, zip(*matrix)))
def minor(matrix: List[list], row: int, column: int) -> List[list]:
def minor(matrix: list[list], row: int, column: int) -> list[list]:
"""
>>> minor([[1, 2], [3, 4]], 1, 1)
[[1]]
@ -102,7 +102,7 @@ def minor(matrix: List[list], row: int, column: int) -> List[list]:
return [row[:column] + row[column + 1 :] for row in minor]
def determinant(matrix: List[list]) -> int:
def determinant(matrix: list[list]) -> int:
"""
>>> determinant([[1, 2], [3, 4]])
-2
@ -118,7 +118,7 @@ def determinant(matrix: List[list]) -> int:
)
def inverse(matrix: List[list]) -> List[list]:
def inverse(matrix: list[list]) -> list[list]:
"""
>>> inverse([[1, 2], [3, 4]])
[[-2.0, 1.0], [1.5, -0.5]]
@ -142,17 +142,17 @@ def inverse(matrix: List[list]) -> List[list]:
return scalar_multiply(adjugate, 1 / det)
def _check_not_integer(matrix: List[list]) -> bool:
def _check_not_integer(matrix: list[list]) -> bool:
if not isinstance(matrix, int) and not isinstance(matrix[0], int):
return True
raise TypeError("Expected a matrix, got int/list instead")
def _shape(matrix: List[list]) -> list:
def _shape(matrix: list[list]) -> list:
return len(matrix), len(matrix[0])
def _verify_matrix_sizes(matrix_a: List[list], matrix_b: List[list]) -> Tuple[list]:
def _verify_matrix_sizes(matrix_a: list[list], matrix_b: list[list]) -> tuple[list]:
shape = _shape(matrix_a) + _shape(matrix_b)
if shape[0] != shape[3] or shape[1] != shape[2]:
raise ValueError(

View File

@ -1,21 +1,23 @@
from typing import List, Union
from __future__ import annotations
from typing import Union
def search_in_a_sorted_matrix(
mat: List[list], m: int, n: int, key: Union[int, float]
mat: list[list], m: int, n: int, key: Union[int, float]
) -> None:
"""
>>> search_in_a_sorted_matrix(\
[[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 5)
>>> search_in_a_sorted_matrix(
... [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 5)
Key 5 found at row- 1 column- 2
>>> search_in_a_sorted_matrix(\
[[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 21)
>>> search_in_a_sorted_matrix(
... [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 21)
Key 21 not found
>>> search_in_a_sorted_matrix(\
[[2.1, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 2.1)
>>> search_in_a_sorted_matrix(
... [[2.1, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 2.1)
Key 2.1 found at row- 1 column- 1
>>> search_in_a_sorted_matrix(\
[[2.1, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 2.2)
>>> search_in_a_sorted_matrix(
... [[2.1, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 2.2)
Key 2.2 not found
"""
i, j = m - 1, 0

View File

@ -15,8 +15,9 @@ before deciding whether allocation should be allowed to continue.
(https://rosettacode.org/wiki/Banker%27s_algorithm)
"""
from __future__ import annotations
import time
from typing import Dict, List
import numpy as np
@ -40,9 +41,9 @@ test_maximum_claim_table = [
class BankersAlgorithm:
def __init__(
self,
claim_vector: List[int],
allocated_resources_table: List[List[int]],
maximum_claim_table: List[List[int]],
claim_vector: list[int],
allocated_resources_table: list[list[int]],
maximum_claim_table: list[list[int]],
) -> None:
"""
:param claim_vector: A nxn/nxm list depicting the amount of each resources
@ -56,7 +57,7 @@ class BankersAlgorithm:
self.__allocated_resources_table = allocated_resources_table
self.__maximum_claim_table = maximum_claim_table
def __processes_resource_summation(self) -> List[int]:
def __processes_resource_summation(self) -> list[int]:
"""
Check for allocated resources in line with each resource in the claim vector
"""
@ -65,7 +66,7 @@ class BankersAlgorithm:
for i in range(len(self.__allocated_resources_table[0]))
]
def __available_resources(self) -> List[int]:
def __available_resources(self) -> list[int]:
"""
Check for available resources in line with each resource in the claim vector
"""
@ -73,7 +74,7 @@ class BankersAlgorithm:
self.__processes_resource_summation()
)
def __need(self) -> List[List[int]]:
def __need(self) -> list[list[int]]:
"""
Implement safety checker that calculates the needs by ensuring that
max_claim[i][j] - alloc_table[i][j] <= avail[j]
@ -83,7 +84,7 @@ class BankersAlgorithm:
for i, allocated_resource in enumerate(self.__allocated_resources_table)
]
def __need_index_manager(self) -> Dict[int, List[int]]:
def __need_index_manager(self) -> dict[int, list[int]]:
"""
This function builds an index control dictionary to track original ids/indices
of processes when altered during execution of method "main"

View File

@ -1,6 +1,7 @@
from __future__ import annotations
from collections import Counter
from random import random
from typing import Dict, List, Tuple
class MarkovChainGraphUndirectedUnweighted:
@ -23,7 +24,7 @@ class MarkovChainGraphUndirectedUnweighted:
self.add_node(node2)
self.connections[node1][node2] = probability
def get_nodes(self) -> List[str]:
def get_nodes(self) -> list[str]:
return list(self.connections)
def transition(self, node: str) -> str:
@ -37,8 +38,8 @@ class MarkovChainGraphUndirectedUnweighted:
def get_transitions(
start: str, transitions: List[Tuple[str, str, float]], steps: int
) -> Dict[str, int]:
start: str, transitions: list[tuple[str, str, float]], steps: int
) -> dict[str, int]:
"""
Running Markov Chain algorithm and calculating the number of times each node is
visited

View File

@ -3,13 +3,14 @@ Given an array of integers and another integer target,
we are required to find a triplet from the array such that it's sum is equal to
the target.
"""
from __future__ import annotations
from itertools import permutations
from random import randint
from timeit import repeat
from typing import List, Tuple
def make_dataset() -> Tuple[List[int], int]:
def make_dataset() -> tuple[list[int], int]:
arr = [randint(-1000, 1000) for i in range(10)]
r = randint(-5000, 5000)
return (arr, r)
@ -18,7 +19,7 @@ def make_dataset() -> Tuple[List[int], int]:
dataset = make_dataset()
def triplet_sum1(arr: List[int], target: int) -> Tuple[int, int, int]:
def triplet_sum1(arr: list[int], target: int) -> tuple[int, int, int]:
"""
Returns a triplet in the array with sum equal to target,
else (0, 0, 0).
@ -37,7 +38,7 @@ def triplet_sum1(arr: List[int], target: int) -> Tuple[int, int, int]:
return (0, 0, 0)
def triplet_sum2(arr: List[int], target: int) -> Tuple[int, int, int]:
def triplet_sum2(arr: list[int], target: int) -> tuple[int, int, int]:
"""
Returns a triplet in the array with sum equal to target,
else (0, 0, 0).
@ -64,7 +65,7 @@ def triplet_sum2(arr: List[int], target: int) -> Tuple[int, int, int]:
return (0, 0, 0)
def solution_times() -> Tuple[float, float]:
def solution_times() -> tuple[float, float]:
setup_code = """
from __main__ import dataset, triplet_sum1, triplet_sum2
"""

View File

@ -10,7 +10,7 @@ below 1 million using the Seive of Eratosthenes. Then, out of all these primes,
we will rule out the numbers which contain an even digit. After this we will
generate each circular combination of the number and check if all are prime.
"""
from typing import List
from __future__ import annotations
seive = [True] * 1000001
i = 2
@ -47,7 +47,7 @@ def contains_an_even_digit(n: int) -> bool:
return any(digit in "02468" for digit in str(n))
def find_circular_primes(limit: int = 1000000) -> List[int]:
def find_circular_primes(limit: int = 1000000) -> list[int]:
"""
Return circular primes below limit.
>>> len(find_circular_primes(100))

View File

@ -9,8 +9,7 @@ and right to left.
NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes.
"""
from typing import List
from __future__ import annotations
seive = [True] * 1000001
seive[1] = False
@ -36,7 +35,7 @@ def is_prime(n: int) -> bool:
return seive[n]
def list_truncated_nums(n: int) -> List[int]:
def list_truncated_nums(n: int) -> list[int]:
"""
Returns a list of all left and right truncated numbers of n
>>> list_truncated_nums(927628)
@ -71,7 +70,7 @@ def validate(n: int) -> bool:
return True
def compute_truncated_primes(count: int = 11) -> List[int]:
def compute_truncated_primes(count: int = 11) -> list[int]:
"""
Returns the list of truncated primes
>>> compute_truncated_primes(11)

View File

@ -6,11 +6,12 @@ If p is the perimeter of a right angle triangle with integral length sides,
For which value of p 1000, is the number of solutions maximised?
"""
from __future__ import annotations
from collections import Counter
from typing import Dict
def pythagorean_triple(max_perimeter: int) -> Dict:
def pythagorean_triple(max_perimeter: int) -> dict:
"""
Returns a dictionary with keys as the perimeter of a right angled triangle
and value as the number of corresponding triplets.

View File

@ -1,6 +1,7 @@
from __future__ import annotations
from itertools import permutations
from math import sqrt
from typing import List
"""
We shall say that an n-digit number is pandigital if it makes use of all the digits
@ -34,7 +35,7 @@ def is_prime(n: int) -> bool:
return True
def compute_pandigital_primes(n: int) -> List[int]:
def compute_pandigital_primes(n: int) -> list[int]:
"""
Returns a list of all n-digit pandigital primes.
>>> compute_pandigital_primes(2)

View File

@ -15,7 +15,7 @@ What is the smallest odd composite that cannot be written as the sum of a
prime and twice a square?
"""
from typing import List
from __future__ import annotations
seive = [True] * 100001
i = 2
@ -43,7 +43,7 @@ def is_prime(n: int) -> bool:
odd_composites = [num for num in range(3, len(seive), 2) if not is_prime(num)]
def compute_nums(n: int) -> List[int]:
def compute_nums(n: int) -> list[int]:
"""
Returns a list of first n odd composite numbers which do
not follow the conjecture.

View File

@ -40,7 +40,7 @@ Similar problem on codewars:
https://www.codewars.com/kata/ranking-poker-hands
https://www.codewars.com/kata/sortable-poker-hands
"""
from typing import List, Set, Tuple
from __future__ import annotations
class PokerHand(object):
@ -310,7 +310,7 @@ class PokerHand(object):
self._second_pair = second
return kind
def _internal_state(self) -> Tuple[List[int], Set[str]]:
def _internal_state(self) -> tuple[list[int], set[str]]:
# Internal representation of hand as a list of card values and
# a set of card suit
trans: dict = {"T": "10", "J": "11", "Q": "12", "K": "13", "A": "14"}

View File

@ -2,10 +2,10 @@
# In this Algorithm we just care about the order that the processes arrived
# without carring about their duration time
# https://en.wikipedia.org/wiki/Scheduling_(computing)#First_come,_first_served
from typing import List
from __future__ import annotations
def calculate_waiting_times(duration_times: List[int]) -> List[int]:
def calculate_waiting_times(duration_times: list[int]) -> list[int]:
"""
This function calculates the waiting time of some processes that have a
specified duration time.
@ -24,8 +24,8 @@ def calculate_waiting_times(duration_times: List[int]) -> List[int]:
def calculate_turnaround_times(
duration_times: List[int], waiting_times: List[int]
) -> List[int]:
duration_times: list[int], waiting_times: list[int]
) -> list[int]:
"""
This function calculates the turnaround time of some processes.
Return: The time difference between the completion time and the
@ -44,7 +44,7 @@ def calculate_turnaround_times(
]
def calculate_average_turnaround_time(turnaround_times: List[int]) -> float:
def calculate_average_turnaround_time(turnaround_times: list[int]) -> float:
"""
This function calculates the average of the turnaround times
Return: The average of the turnaround times.
@ -58,7 +58,7 @@ def calculate_average_turnaround_time(turnaround_times: List[int]) -> float:
return sum(turnaround_times) / len(turnaround_times)
def calculate_average_waiting_time(waiting_times: List[int]) -> float:
def calculate_average_waiting_time(waiting_times: list[int]) -> float:
"""
This function calculates the average of the waiting times
Return: The average of the waiting times.

View File

@ -3,11 +3,12 @@ Round Robin is a scheduling algorithm.
In Round Robin each process is assigned a fixed time slot in a cyclic way.
https://en.wikipedia.org/wiki/Round-robin_scheduling
"""
from __future__ import annotations
from statistics import mean
from typing import List
def calculate_waiting_times(burst_times: List[int]) -> List[int]:
def calculate_waiting_times(burst_times: list[int]) -> list[int]:
"""
Calculate the waiting times of a list of processes that have a specified duration.
@ -40,8 +41,8 @@ def calculate_waiting_times(burst_times: List[int]) -> List[int]:
def calculate_turn_around_times(
burst_times: List[int], waiting_times: List[int]
) -> List[int]:
burst_times: list[int], waiting_times: list[int]
) -> list[int]:
"""
>>> calculate_turn_around_times([1, 2, 3, 4], [0, 1, 3])
[1, 3, 6]

View File

@ -3,14 +3,14 @@ Shortest job remaining first
Please note arrival time and burst
Please use spaces to separate times entered.
"""
from typing import List
from __future__ import annotations
import pandas as pd
def calculate_waitingtime(
arrival_time: List[int], burst_time: List[int], no_of_processes: int
) -> List[int]:
arrival_time: list[int], burst_time: list[int], no_of_processes: int
) -> list[int]:
"""
Calculate the waiting time of each processes
Return: list of waiting times.
@ -72,8 +72,8 @@ def calculate_waitingtime(
def calculate_turnaroundtime(
burst_time: List[int], no_of_processes: int, waiting_time: List[int]
) -> List[int]:
burst_time: list[int], no_of_processes: int, waiting_time: list[int]
) -> list[int]:
"""
Calculate the turn around time of each Processes
Return: list of turn around times.
@ -91,7 +91,7 @@ def calculate_turnaroundtime(
def calculate_average_times(
waiting_time: List[int], turn_around_time: List[int], no_of_processes: int
waiting_time: list[int], turn_around_time: list[int], no_of_processes: int
):
"""
This function calculates the average of the waiting & turnaround times

View File

@ -1,7 +1,7 @@
from typing import List
from __future__ import annotations
def double_linear_search(array: List[int], search_item: int) -> int:
def double_linear_search(array: list[int], search_item: int) -> int:
"""
Iterate through the array from both sides to find the index of search_item.

View File

@ -7,10 +7,10 @@ python3 -m doctest -v simple_binary_search.py
For manual testing run:
python3 simple_binary_search.py
"""
from typing import List
from __future__ import annotations
def binary_search(a_list: List[int], item: int) -> bool:
def binary_search(a_list: list[int], item: int) -> bool:
"""
>>> test_list = [0, 1, 2, 8, 13, 17, 19, 32, 42]
>>> print(binary_search(test_list, 3))

View File

@ -9,10 +9,10 @@ For manual testing run:
python3 iterative_merge_sort.py
"""
from typing import List
from __future__ import annotations
def merge(input_list: List, low: int, mid: int, high: int) -> List:
def merge(input_list: list, low: int, mid: int, high: int) -> list:
"""
sorting left-half and right-half individually
then merging them into result
@ -26,7 +26,7 @@ def merge(input_list: List, low: int, mid: int, high: int) -> List:
# iteration over the unsorted list
def iter_merge_sort(input_list: List) -> List:
def iter_merge_sort(input_list: list) -> list:
"""
Return a sorted copy of the input list

View File

@ -11,10 +11,10 @@ For manual testing run:
python3 merge_insertion_sort.py
"""
from typing import List
from __future__ import annotations
def merge_insertion_sort(collection: List[int]) -> List[int]:
def merge_insertion_sort(collection: list[int]) -> list[int]:
"""Pure implementation of merge-insertion sort algorithm in Python
:param collection: some mutable ordered collection with heterogeneous

View File

@ -1,7 +1,7 @@
from typing import List
from __future__ import annotations
def radix_sort(list_of_ints: List[int]) -> List[int]:
def radix_sort(list_of_ints: list[int]) -> list[int]:
"""
radix_sort(range(15)) == sorted(range(15))
True

View File

@ -2,10 +2,10 @@
A recursive implementation of the insertion sort algorithm
"""
from typing import List
from __future__ import annotations
def rec_insertion_sort(collection: List, n: int):
def rec_insertion_sort(collection: list, n: int):
"""
Given a collection of numbers and its length, sorts the collections
in ascending order
@ -36,7 +36,7 @@ def rec_insertion_sort(collection: List, n: int):
rec_insertion_sort(collection, n - 1)
def insert_next(collection: List, index: int):
def insert_next(collection: list, index: int):
"""
Inserts the '(index-1)th' element into place

View File

@ -3,8 +3,9 @@
"""
This is pure Python implementation of tree traversal algorithms
"""
from __future__ import annotations
import queue
from typing import List
class TreeNode:

View File

@ -1,7 +1,9 @@
"""
Scraping jobs given job title and location from indeed website
"""
from typing import Generator, Tuple
from __future__ import annotations
from typing import Generator
import requests
from bs4 import BeautifulSoup
@ -9,7 +11,7 @@ from bs4 import BeautifulSoup
url = "https://www.indeed.co.in/jobs?q=mobile+app+development&l="
def fetch_jobs(location: str = "mumbai") -> Generator[Tuple[str, str], None, None]:
def fetch_jobs(location: str = "mumbai") -> Generator[tuple[str, str], None, None]:
soup = BeautifulSoup(requests.get(url + location).content, "html.parser")
# This attribute finds out all the specifics listed in a job
for job in soup.find_all("div", attrs={"data-tn-component": "organicJob"}):

View File

@ -1,11 +1,12 @@
from __future__ import annotations
import csv
from typing import Dict
import requests
from bs4 import BeautifulSoup
def get_imdb_top_250_movies(url: str = "") -> Dict[str, float]:
def get_imdb_top_250_movies(url: str = "") -> dict[str, float]:
url = url or "https://www.imdb.com/chart/top/?ref_=nv_mv_250"
soup = BeautifulSoup(requests.get(url).text, "html.parser")
titles = soup.find_all("td", attrs="titleColumn")