From cecf43d6481173e831af829da77911e1a3868a6c Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Tue, 7 Sep 2021 13:37:03 +0200 Subject: [PATCH] Pyupgrade to Python 3.9 (#4718) * Pyupgrade to Python 3.9 * updating DIRECTORY.md Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 3 ++- arithmetic_analysis/in_static_equilibrium.py | 4 +-- arithmetic_analysis/lu_decomposition.py | 4 +-- .../newton_forward_interpolation.py | 4 +-- arithmetic_analysis/newton_raphson.py | 5 ++-- backtracking/all_combinations.py | 12 ++++----- backtracking/all_permutations.py | 14 +++++----- backtracking/all_subsequences.py | 10 ++++--- backtracking/coloring.py | 7 +++-- backtracking/hamiltonian_cycle.py | 7 +++-- backtracking/knight_tour.py | 10 +++---- backtracking/minimax.py | 5 ++-- backtracking/n_queens.py | 8 +++--- backtracking/n_queens_math.py | 12 ++++----- backtracking/rat_in_maze.py | 6 ++--- backtracking/sudoku.py | 8 +++--- backtracking/sum_of_subsets.py | 14 +++++----- blockchain/chinese_remainder_theorem.py | 4 +-- blockchain/diophantine_equation.py | 6 ++--- blockchain/modular_division.py | 6 ++--- boolean_algebra/quine_mc_cluskey.py | 12 ++++----- cellular_automata/conways_game_of_life.py | 5 +--- ciphers/caesar_cipher.py | 9 ++++--- ciphers/decrypt_caesar_with_chi_squared.py | 7 +++-- ciphers/diffie.py | 4 +-- ciphers/shuffled_shift_cipher.py | 5 ++-- compression/huffman.py | 2 +- conversions/molecular_chemistry.py | 2 +- conversions/prefix_conversions.py | 11 ++++---- data_structures/binary_tree/avl_tree.py | 25 +++++++++--------- .../binary_tree/basic_binary_tree.py | 10 +++---- .../binary_search_tree_recursive.py | 24 ++++++++--------- .../binary_tree/binary_tree_traversals.py | 7 ++--- .../binary_tree/lazy_segment_tree.py | 5 ++-- .../binary_tree/merge_two_binary_trees.py | 10 +++---- data_structures/binary_tree/red_black_tree.py | 26 ++++++++++--------- data_structures/binary_tree/treap.py | 21 +++++++-------- data_structures/binary_tree/wavelet_tree.py | 7 +++-- data_structures/hashing/hash_table.py | 2 +- .../hashing/hash_table_with_linked_list.py | 2 +- data_structures/heap/heap.py | 12 +++++---- data_structures/heap/randomized_heap.py | 16 ++++++------ data_structures/heap/skew_heap.py | 14 +++++----- .../linked_list/merge_two_lists.py | 5 ++-- data_structures/linked_list/print_reverse.py | 4 +-- data_structures/linked_list/skip_list.py | 7 +++-- .../stacks/evaluate_postfix_notations.py | 7 ++--- data_structures/stacks/linked_stack.py | 6 +++-- data_structures/stacks/stack.py | 4 +-- divide_and_conquer/convex_hull.py | 19 +++++++------- divide_and_conquer/kth_order_statistic.py | 5 ++-- divide_and_conquer/mergesort.py | 6 ++--- divide_and_conquer/peak.py | 4 +-- electronics/electric_power.py | 5 ++-- electronics/ohms_law.py | 4 +-- graphs/basic_graphs.py | 8 +++--- graphs/bellman_ford.py | 8 +++--- graphs/bfs_zero_one_shortest_path.py | 14 +++++----- graphs/bidirectional_a_star.py | 7 ++--- graphs/bidirectional_breadth_first_search.py | 10 +++---- graphs/breadth_first_search.py | 7 +++-- graphs/breadth_first_search_shortest_path.py | 4 +-- graphs/depth_first_search.py | 5 +--- graphs/greedy_best_first.py | 8 +++--- graphs/minimum_spanning_tree_kruskal.py | 2 +- graphs/minimum_spanning_tree_prims2.py | 7 ++--- graphs/page_rank.py | 2 +- graphs/scc_kosaraju.py | 14 +++++----- hashes/luhn.py | 6 ++--- knapsack/knapsack.py | 5 ++-- linear_algebra/src/lib.py | 26 +++++++++---------- machine_learning/similarity_search.py | 5 ++-- maths/area_under_curve.py | 9 ++++--- maths/average_mean.py | 4 +-- maths/average_median.py | 4 +-- maths/entropy.py | 6 ++--- maths/euclidean_distance.py | 2 ++ maths/extended_euclidean_algorithm.py | 4 +-- maths/hardy_ramanujanalgo.py | 2 +- maths/line_length.py | 10 ++++--- maths/max_sum_sliding_window.py | 4 +-- maths/median_of_two_arrays.py | 4 +-- maths/numerical_integration.py | 9 ++++--- maths/sieve_of_eratosthenes.py | 5 ++-- maths/volume.py | 5 ++-- matrix/searching_in_sorted_matrix.py | 4 +-- other/date_to_weekday.py | 2 +- .../davisb_putnamb_logemannb_loveland.py | 24 ++++++++--------- other/lfu_cache.py | 6 +++-- other/lru_cache.py | 6 +++-- project_euler/problem_001/sol1.py | 2 +- project_euler/problem_001/sol5.py | 2 +- project_euler/problem_006/sol3.py | 2 +- project_euler/problem_008/sol2.py | 5 +--- project_euler/problem_012/sol2.py | 2 +- project_euler/problem_013/sol1.py | 2 +- project_euler/problem_014/sol2.py | 6 ++--- project_euler/problem_020/sol2.py | 2 +- project_euler/problem_021/sol1.py | 8 +++--- project_euler/problem_033/sol1.py | 5 ++-- project_euler/problem_036/sol1.py | 5 ++-- project_euler/problem_038/sol1.py | 5 ++-- project_euler/problem_049/sol1.py | 2 +- project_euler/problem_050/sol1.py | 4 +-- project_euler/problem_051/sol1.py | 6 ++--- project_euler/problem_054/sol1.py | 4 +-- project_euler/problem_056/sol1.py | 8 +++--- project_euler/problem_059/sol1.py | 23 ++++++++-------- project_euler/problem_070/sol1.py | 4 +-- project_euler/problem_074/sol1.py | 2 +- project_euler/problem_077/sol1.py | 8 +++--- project_euler/problem_080/sol1.py | 2 +- project_euler/problem_081/sol1.py | 2 +- project_euler/problem_085/sol1.py | 5 ++-- project_euler/problem_089/sol1.py | 2 +- project_euler/problem_101/sol1.py | 18 ++++++------- project_euler/problem_102/sol1.py | 14 +++++----- project_euler/problem_107/sol1.py | 21 ++++++++------- project_euler/problem_119/sol1.py | 2 +- project_euler/problem_123/sol1.py | 5 ++-- project_euler/problem_180/sol1.py | 7 +++-- project_euler/problem_203/sol1.py | 12 ++++----- scheduling/first_come_first_served.py | 12 ++++----- scheduling/round_robin.py | 9 ++++--- scheduling/shortest_job_first.py | 12 ++++----- searches/binary_search.py | 19 +++++++------- searches/fibonacci_search.py | 2 +- searches/ternary_search.py | 8 +++--- sorts/bitonic_sort.py | 8 +++--- sorts/bucket_sort.py | 4 +-- sorts/msd_radix_sort.py | 10 +++---- sorts/patience_sort.py | 7 ++--- sorts/pigeon_sort.py | 4 +-- sorts/quick_sort.py | 6 ++--- sorts/radix_sort.py | 6 ++--- sorts/recursive_insertion_sort.py | 5 +--- sorts/slowsort.py | 7 ++--- strings/aho_corasick.py | 7 ++--- strings/boyer_moore_search.py | 4 +-- strings/knuth_morris_pratt.py | 4 +-- web_programming/emails_from_url.py | 5 ++-- web_programming/fetch_github_info.py | 6 +++-- 142 files changed, 523 insertions(+), 530 deletions(-) rename "other/davis\342\200\223putnam\342\200\223logemann\342\200\223loveland.py" => other/davisb_putnamb_logemannb_loveland.py (94%) diff --git a/DIRECTORY.md b/DIRECTORY.md index 41485f6f0ca4..0c00d5ca7f70 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -545,7 +545,7 @@ ## Other * [Activity Selection](https://github.com/TheAlgorithms/Python/blob/master/other/activity_selection.py) * [Date To Weekday](https://github.com/TheAlgorithms/Python/blob/master/other/date_to_weekday.py) - * [Davis–Putnam–Logemann–Loveland](https://github.com/TheAlgorithms/Python/blob/master/other/davis–putnam–logemann–loveland.py) + * [Davisb Putnamb Logemannb Loveland](https://github.com/TheAlgorithms/Python/blob/master/other/davisb_putnamb_logemannb_loveland.py) * [Dijkstra Bankers Algorithm](https://github.com/TheAlgorithms/Python/blob/master/other/dijkstra_bankers_algorithm.py) * [Doomsday](https://github.com/TheAlgorithms/Python/blob/master/other/doomsday.py) * [Fischer Yates Shuffle](https://github.com/TheAlgorithms/Python/blob/master/other/fischer_yates_shuffle.py) @@ -860,6 +860,7 @@ * [Counting Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/counting_sort.py) * [Cycle Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/cycle_sort.py) * [Double Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/double_sort.py) + * [Dutch National Flag Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/dutch_national_flag_sort.py) * [Exchange Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/exchange_sort.py) * [External Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/external_sort.py) * [Gnome Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/gnome_sort.py) diff --git a/arithmetic_analysis/in_static_equilibrium.py b/arithmetic_analysis/in_static_equilibrium.py index 7b5006a1a82c..6e8d1d043036 100644 --- a/arithmetic_analysis/in_static_equilibrium.py +++ b/arithmetic_analysis/in_static_equilibrium.py @@ -1,14 +1,14 @@ """ Checks if a system of forces is in static equilibrium. """ -from typing import List +from __future__ import annotations from numpy import array, cos, cross, ndarray, radians, sin 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) diff --git a/arithmetic_analysis/lu_decomposition.py b/arithmetic_analysis/lu_decomposition.py index 5bb631758c21..b488b1bb3211 100644 --- a/arithmetic_analysis/lu_decomposition.py +++ b/arithmetic_analysis/lu_decomposition.py @@ -3,12 +3,12 @@ Reference: - https://en.wikipedia.org/wiki/LU_decomposition """ -from typing import Tuple +from __future__ import annotations import numpy as np -def lower_upper_decomposition(table: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: +def lower_upper_decomposition(table: np.ndarray) -> tuple[np.ndarray, np.ndarray]: """Lower-Upper (LU) Decomposition Example: diff --git a/arithmetic_analysis/newton_forward_interpolation.py b/arithmetic_analysis/newton_forward_interpolation.py index 66cde4b73c4f..490e0687f15f 100644 --- a/arithmetic_analysis/newton_forward_interpolation.py +++ b/arithmetic_analysis/newton_forward_interpolation.py @@ -1,7 +1,7 @@ # https://www.geeksforgeeks.org/newton-forward-backward-interpolation/ +from __future__ import annotations import math -from typing import List # for calculating u value @@ -22,7 +22,7 @@ def ucal(u: float, p: int) -> float: def main() -> None: n = int(input("enter the numbers of values: ")) - y: List[List[float]] = [] + y: list[list[float]] = [] for i in range(n): y.append([]) for i in range(n): diff --git a/arithmetic_analysis/newton_raphson.py b/arithmetic_analysis/newton_raphson.py index 146bb0aa5adf..1a820538630f 100644 --- a/arithmetic_analysis/newton_raphson.py +++ b/arithmetic_analysis/newton_raphson.py @@ -2,15 +2,16 @@ # Author: Syed Haseeb Shah (github.com/QuantumNovice) # The Newton-Raphson method (also known as Newton's method) is a way to # quickly find a good approximation for the root of a real-valued function +from __future__ import annotations + from decimal import Decimal from math import * # noqa: F401, F403 -from typing import Union from sympy import diff def newton_raphson( - func: str, a: Union[float, Decimal], precision: float = 10 ** -10 + func: str, a: float | Decimal, precision: float = 10 ** -10 ) -> float: """Finds root from the point 'a' onwards by Newton-Raphson method >>> newton_raphson("sin(x)", 2) diff --git a/backtracking/all_combinations.py b/backtracking/all_combinations.py index 76462837ce35..bde60f0328ba 100644 --- a/backtracking/all_combinations.py +++ b/backtracking/all_combinations.py @@ -3,16 +3,16 @@ numbers out of 1 ... n. We use backtracking to solve this problem. Time complexity: O(C(n,k)) which is O(n choose k) = O((n!/(k! * (n - k)!))) """ -from typing import List +from __future__ import annotations -def generate_all_combinations(n: int, k: int) -> List[List[int]]: +def generate_all_combinations(n: int, k: int) -> list[list[int]]: """ >>> generate_all_combinations(n=4, k=2) [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]] """ - result: List[List[int]] = [] + result: list[list[int]] = [] create_all_state(1, n, k, [], result) return result @@ -21,8 +21,8 @@ def create_all_state( increment: int, total_number: int, level: int, - current_list: List[int], - total_list: List[List[int]], + current_list: list[int], + total_list: list[list[int]], ) -> None: if level == 0: total_list.append(current_list[:]) @@ -34,7 +34,7 @@ def create_all_state( current_list.pop() -def print_all_state(total_list: List[List[int]]) -> None: +def print_all_state(total_list: list[list[int]]) -> None: for i in total_list: print(*i) diff --git a/backtracking/all_permutations.py b/backtracking/all_permutations.py index a0032c5ca814..ff8a53e0dd0e 100644 --- a/backtracking/all_permutations.py +++ b/backtracking/all_permutations.py @@ -5,18 +5,18 @@ Time complexity: O(n! * n), where n denotes the length of the given sequence. """ -from typing import List, Union +from __future__ import annotations -def generate_all_permutations(sequence: List[Union[int, str]]) -> None: +def generate_all_permutations(sequence: list[int | str]) -> None: create_state_space_tree(sequence, [], 0, [0 for i in range(len(sequence))]) def create_state_space_tree( - sequence: List[Union[int, str]], - current_sequence: List[Union[int, str]], + sequence: list[int | str], + current_sequence: list[int | str], index: int, - index_used: List[int], + index_used: list[int], ) -> None: """ Creates a state space tree to iterate through each branch using DFS. @@ -44,8 +44,8 @@ def create_state_space_tree( sequence = list(map(int, input().split())) """ -sequence: List[Union[int, str]] = [3, 1, 2, 4] +sequence: list[int | str] = [3, 1, 2, 4] generate_all_permutations(sequence) -sequence_2: List[Union[int, str]] = ["A", "B", "C"] +sequence_2: list[int | str] = ["A", "B", "C"] generate_all_permutations(sequence_2) diff --git a/backtracking/all_subsequences.py b/backtracking/all_subsequences.py index 99db4ea46589..c465fc542407 100644 --- a/backtracking/all_subsequences.py +++ b/backtracking/all_subsequences.py @@ -5,15 +5,17 @@ Time complexity: O(2^n), where n denotes the length of the given sequence. """ -from typing import Any, List +from __future__ import annotations +from typing import Any -def generate_all_subsequences(sequence: List[Any]) -> None: + +def generate_all_subsequences(sequence: list[Any]) -> None: create_state_space_tree(sequence, [], 0) def create_state_space_tree( - sequence: List[Any], current_subsequence: List[Any], index: int + sequence: list[Any], current_subsequence: list[Any], index: int ) -> None: """ Creates a state space tree to iterate through each branch using DFS. @@ -32,7 +34,7 @@ def create_state_space_tree( if __name__ == "__main__": - seq: List[Any] = [3, 1, 2, 4] + seq: list[Any] = [3, 1, 2, 4] generate_all_subsequences(seq) seq.clear() diff --git a/backtracking/coloring.py b/backtracking/coloring.py index 3956b21a9182..8bda4b5871df 100644 --- a/backtracking/coloring.py +++ b/backtracking/coloring.py @@ -5,11 +5,10 @@ Wikipedia: https://en.wikipedia.org/wiki/Graph_coloring """ -from typing import List 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 +34,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 +85,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. diff --git a/backtracking/hamiltonian_cycle.py b/backtracking/hamiltonian_cycle.py index 7be1ea350d7c..19751b347320 100644 --- a/backtracking/hamiltonian_cycle.py +++ b/backtracking/hamiltonian_cycle.py @@ -6,11 +6,10 @@ Wikipedia: https://en.wikipedia.org/wiki/Hamiltonian_path """ -from typing import List 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 +46,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 +107,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 diff --git a/backtracking/knight_tour.py b/backtracking/knight_tour.py index 8e6613e07d8b..6e9b31bd1133 100644 --- a/backtracking/knight_tour.py +++ b/backtracking/knight_tour.py @@ -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, int], n: int) -> List[Tuple[int, int]]: +def get_valid_pos(position: tuple[int, int], n: int) -> list[tuple[int, 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, int], n: int) -> List[Tuple[int, 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. @@ -47,7 +47,7 @@ def is_complete(board: List[List[int]]) -> bool: def open_knight_tour_helper( - board: List[List[int]], pos: Tuple[int, int], curr: int + board: list[list[int]], pos: tuple[int, int], curr: int ) -> bool: """ Helper function to solve knight tour problem. @@ -68,7 +68,7 @@ def open_knight_tour_helper( 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. diff --git a/backtracking/minimax.py b/backtracking/minimax.py index dda29b47d6cc..6e310131e069 100644 --- a/backtracking/minimax.py +++ b/backtracking/minimax.py @@ -7,12 +7,13 @@ leaves of game tree is stored in scores[] height is maximum height of Game tree """ +from __future__ import annotations + import math -from typing import List def minimax( - depth: int, node_index: int, is_max: bool, scores: List[int], height: float + depth: int, node_index: int, is_max: bool, scores: list[int], height: float ) -> int: """ >>> import math diff --git a/backtracking/n_queens.py b/backtracking/n_queens.py index 29b8d819acf3..b8ace59781f5 100644 --- a/backtracking/n_queens.py +++ b/backtracking/n_queens.py @@ -7,12 +7,12 @@ diagonal lines. """ -from typing import List +from __future__ import annotations solution = [] -def isSafe(board: List[List[int]], row: int, column: int) -> bool: +def isSafe(board: list[list[int]], row: int, column: int) -> bool: """ This function returns a boolean value True if it is safe to place a queen there considering the current state of the board. @@ -40,7 +40,7 @@ def isSafe(board: List[List[int]], row: int, column: int) -> bool: return True -def solve(board: List[List[int]], row: int) -> bool: +def solve(board: list[list[int]], row: int) -> bool: """ It creates a state space tree and calls the safe function until it receives a False Boolean and terminates that branch and backtracks to the next @@ -70,7 +70,7 @@ def solve(board: List[List[int]], row: int) -> bool: return False -def printboard(board: List[List[int]]) -> None: +def printboard(board: list[list[int]]) -> None: """ Prints the boards that have a successful combination. """ diff --git a/backtracking/n_queens_math.py b/backtracking/n_queens_math.py index a8651c5c362e..c12aa6c3387d 100644 --- a/backtracking/n_queens_math.py +++ b/backtracking/n_queens_math.py @@ -75,14 +75,14 @@ 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: """ @@ -139,7 +139,7 @@ def depth_first_search( def n_queens_solution(n: int) -> None: - boards: List[List[str]] = [] + boards: list[list[str]] = [] depth_first_search([], [], [], boards, n) # Print all the boards diff --git a/backtracking/rat_in_maze.py b/backtracking/rat_in_maze.py index cd2a8f41daa8..2860880db540 100644 --- a/backtracking/rat_in_maze.py +++ b/backtracking/rat_in_maze.py @@ -1,7 +1,7 @@ -from typing import List +from __future__ import annotations -def solve_maze(maze: List[List[int]]) -> bool: +def solve_maze(maze: list[list[int]]) -> bool: """ This method solves the "rat in maze" problem. In this problem we have some n by n matrix, a start point and an end point. @@ -70,7 +70,7 @@ def solve_maze(maze: List[List[int]]) -> bool: return solved -def run_maze(maze: List[List[int]], i: int, j: int, solutions: List[List[int]]) -> bool: +def run_maze(maze: list[list[int]], i: int, j: int, solutions: list[list[int]]) -> bool: """ This method is recursive starting from (i, j) and going in one of four directions: up, down, left, right. diff --git a/backtracking/sudoku.py b/backtracking/sudoku.py index 593fa52d6d8a..698dedcc2125 100644 --- a/backtracking/sudoku.py +++ b/backtracking/sudoku.py @@ -9,9 +9,9 @@ have solved the puzzle. else, we backtrack and place another number in that cell and repeat this process. """ -from typing import List, Optional, Tuple +from __future__ import annotations -Matrix = List[List[int]] +Matrix = list[list[int]] # assigning initial values to the grid initial_grid: Matrix = [ @@ -59,7 +59,7 @@ def is_safe(grid: Matrix, row: int, column: int, n: int) -> bool: return True -def find_empty_location(grid: Matrix) -> Optional[Tuple[int, int]]: +def find_empty_location(grid: Matrix) -> tuple[int, int] | None: """ This function finds an empty location so that we can assign a number for that particular row and column. @@ -71,7 +71,7 @@ def find_empty_location(grid: Matrix) -> Optional[Tuple[int, int]]: return None -def sudoku(grid: Matrix) -> Optional[Matrix]: +def sudoku(grid: Matrix) -> Matrix | None: """ Takes a partially filled-in grid and attempts to assign values to all unassigned locations in such a way to meet the requirements diff --git a/backtracking/sum_of_subsets.py b/backtracking/sum_of_subsets.py index f695b8f7a80e..8348544c0175 100644 --- a/backtracking/sum_of_subsets.py +++ b/backtracking/sum_of_subsets.py @@ -6,12 +6,12 @@ Summation of the chosen numbers must be equal to given number M and one number can be used only once. """ -from typing import List +from __future__ import annotations -def generate_sum_of_subsets_soln(nums: List[int], max_sum: int) -> List[List[int]]: - result: List[List[int]] = [] - path: List[int] = [] +def generate_sum_of_subsets_soln(nums: list[int], max_sum: int) -> list[list[int]]: + result: list[list[int]] = [] + path: list[int] = [] num_index = 0 remaining_nums_sum = sum(nums) create_state_space_tree(nums, max_sum, num_index, path, result, remaining_nums_sum) @@ -19,11 +19,11 @@ def generate_sum_of_subsets_soln(nums: List[int], max_sum: int) -> List[List[int def create_state_space_tree( - nums: List[int], + nums: list[int], max_sum: int, num_index: int, - path: List[int], - result: List[List[int]], + path: list[int], + result: list[list[int]], remaining_nums_sum: int, ) -> None: """ diff --git a/blockchain/chinese_remainder_theorem.py b/blockchain/chinese_remainder_theorem.py index b50147ac1215..54d861dd9f10 100644 --- a/blockchain/chinese_remainder_theorem.py +++ b/blockchain/chinese_remainder_theorem.py @@ -11,11 +11,11 @@ 1. Use extended euclid algorithm to find x,y such that a*x + b*y = 1 2. Take n = ra*by + rb*ax """ -from typing import Tuple +from __future__ import annotations # Extended Euclid -def extended_euclid(a: int, b: int) -> Tuple[int, int]: +def extended_euclid(a: int, b: int) -> tuple[int, int]: """ >>> extended_euclid(10, 6) (-1, 2) diff --git a/blockchain/diophantine_equation.py b/blockchain/diophantine_equation.py index 7df674cb1438..22b0cad75c63 100644 --- a/blockchain/diophantine_equation.py +++ b/blockchain/diophantine_equation.py @@ -1,7 +1,7 @@ -from typing import Tuple +from __future__ import annotations -def diophantine(a: int, b: int, c: int) -> Tuple[float, float]: +def diophantine(a: int, b: int, c: int) -> tuple[float, float]: """ Diophantine Equation : Given integers a,b,c ( at least one of a and b != 0), the diophantine equation a*x + b*y = c has a solution (where x and y are integers) @@ -95,7 +95,7 @@ def greatest_common_divisor(a: int, b: int) -> int: return b -def extended_gcd(a: int, b: int) -> Tuple[int, int, int]: +def extended_gcd(a: int, b: int) -> tuple[int, int, int]: """ Extended Euclid's Algorithm : If d divides a and b and d = a*x + b*y for integers x and y, then d = gcd(a,b) diff --git a/blockchain/modular_division.py b/blockchain/modular_division.py index 4f7f50a92ad0..a9d0f65c5b27 100644 --- a/blockchain/modular_division.py +++ b/blockchain/modular_division.py @@ -1,4 +1,4 @@ -from typing import Tuple +from __future__ import annotations def modular_division(a: int, b: int, n: int) -> int: @@ -73,7 +73,7 @@ def modular_division2(a: int, b: int, n: int) -> int: return x -def extended_gcd(a: int, b: int) -> Tuple[int, int, int]: +def extended_gcd(a: int, b: int) -> tuple[int, int, int]: """ Extended Euclid's Algorithm : If d divides a and b and d = a*x + b*y for integers x and y, then d = gcd(a,b) @@ -101,7 +101,7 @@ def extended_gcd(a: int, b: int) -> Tuple[int, int, int]: return (d, x, y) -def extended_euclid(a: int, b: int) -> Tuple[int, int]: +def extended_euclid(a: int, b: int) -> tuple[int, int]: """ Extended Euclid >>> extended_euclid(10, 6) diff --git a/boolean_algebra/quine_mc_cluskey.py b/boolean_algebra/quine_mc_cluskey.py index 70cdf25a701d..9cc99b1eeabb 100644 --- a/boolean_algebra/quine_mc_cluskey.py +++ b/boolean_algebra/quine_mc_cluskey.py @@ -1,4 +1,4 @@ -from typing import List +from __future__ import annotations def compare_string(string1: str, string2: str) -> str: @@ -22,7 +22,7 @@ def compare_string(string1: str, string2: str) -> str: return "".join(l1) -def check(binary: List[str]) -> List[str]: +def check(binary: list[str]) -> list[str]: """ >>> check(['0.00.01.5']) ['0.00.01.5'] @@ -46,7 +46,7 @@ def check(binary: List[str]) -> List[str]: binary = list(set(temp)) -def decimal_to_binary(no_of_variable: int, minterms: List[float]) -> List[str]: +def decimal_to_binary(no_of_variable: int, minterms: list[float]) -> list[str]: """ >>> decimal_to_binary(3,[1.5]) ['0.00.01.5'] @@ -82,7 +82,7 @@ def is_for_table(string1: str, string2: str, count: int) -> bool: return False -def selection(chart: List[List[int]], prime_implicants: List[str]) -> List[str]: +def selection(chart: list[list[int]], prime_implicants: list[str]) -> list[str]: """ >>> selection([[1]],['0.00.01.5']) ['0.00.01.5'] @@ -130,8 +130,8 @@ def selection(chart: List[List[int]], prime_implicants: List[str]) -> List[str]: def prime_implicant_chart( - prime_implicants: List[str], binary: List[str] -) -> List[List[int]]: + prime_implicants: list[str], binary: list[str] +) -> list[list[int]]: """ >>> prime_implicant_chart(['0.00.01.5'],['0.00.01.5']) [[1]] diff --git a/cellular_automata/conways_game_of_life.py b/cellular_automata/conways_game_of_life.py index 321baa3a3794..079fb4d04499 100644 --- a/cellular_automata/conways_game_of_life.py +++ b/cellular_automata/conways_game_of_life.py @@ -2,11 +2,8 @@ Conway's Game of Life implemented in Python. https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life """ - from __future__ import annotations -from typing import List - from PIL import Image # Define glider example @@ -25,7 +22,7 @@ BLINKER = [[0, 1, 0], [0, 1, 0], [0, 1, 0]] -def new_generation(cells: List[List[int]]) -> List[List[int]]: +def new_generation(cells: list[list[int]]) -> list[list[int]]: """ Generates the next generation for a given state of Conway's Game of Life. >>> new_generation(BLINKER) diff --git a/ciphers/caesar_cipher.py b/ciphers/caesar_cipher.py index 4b2f76c7d873..8cd9fab58471 100644 --- a/ciphers/caesar_cipher.py +++ b/ciphers/caesar_cipher.py @@ -1,8 +1,9 @@ +from __future__ import annotations + from string import ascii_letters -from typing import Dict, Optional -def encrypt(input_string: str, key: int, alphabet: Optional[str] = None) -> str: +def encrypt(input_string: str, key: int, alphabet: str | None = None) -> str: """ encrypt ======= @@ -80,7 +81,7 @@ def encrypt(input_string: str, key: int, alphabet: Optional[str] = None) -> str: return result -def decrypt(input_string: str, key: int, alphabet: Optional[str] = None) -> str: +def decrypt(input_string: str, key: int, alphabet: str | None = None) -> str: """ decrypt ======= @@ -145,7 +146,7 @@ def decrypt(input_string: str, key: int, alphabet: Optional[str] = None) -> str: return encrypt(input_string, key, alphabet) -def brute_force(input_string: str, alphabet: Optional[str] = None) -> Dict[int, str]: +def brute_force(input_string: str, alphabet: str | None = None) -> dict[int, str]: """ brute_force =========== diff --git a/ciphers/decrypt_caesar_with_chi_squared.py b/ciphers/decrypt_caesar_with_chi_squared.py index 7e3705b8f71f..89477914a030 100644 --- a/ciphers/decrypt_caesar_with_chi_squared.py +++ b/ciphers/decrypt_caesar_with_chi_squared.py @@ -1,12 +1,11 @@ #!/usr/bin/env python3 - -from typing import Optional +from __future__ import annotations def decrypt_caesar_with_chi_squared( ciphertext: str, - cipher_alphabet: Optional[list[str]] = None, - frequencies_dict: Optional[dict[str, float]] = None, + cipher_alphabet: list[str] | None = None, + frequencies_dict: dict[str, float] | None = None, case_sensetive: bool = False, ) -> tuple[int, float, str]: """ diff --git a/ciphers/diffie.py b/ciphers/diffie.py index a23a8104afe2..4ff90be009c1 100644 --- a/ciphers/diffie.py +++ b/ciphers/diffie.py @@ -1,7 +1,7 @@ -from typing import Optional +from __future__ import annotations -def find_primitive(n: int) -> Optional[int]: +def find_primitive(n: int) -> int | None: for r in range(1, n): li = [] for x in range(n - 1): diff --git a/ciphers/shuffled_shift_cipher.py b/ciphers/shuffled_shift_cipher.py index 01d099641dd2..3b84f97f6769 100644 --- a/ciphers/shuffled_shift_cipher.py +++ b/ciphers/shuffled_shift_cipher.py @@ -1,6 +1,7 @@ +from __future__ import annotations + import random import string -from typing import Optional class ShuffledShiftCipher: @@ -27,7 +28,7 @@ class ShuffledShiftCipher: cip2 = ShuffledShiftCipher() """ - def __init__(self, passcode: Optional[str] = None) -> None: + def __init__(self, passcode: str | None = None) -> None: """ Initializes a cipher object with a passcode as it's entity Note: No new passcode is generated if user provides a passcode diff --git a/compression/huffman.py b/compression/huffman.py index b6cc4de1e8e6..8f37a53ce2b7 100644 --- a/compression/huffman.py +++ b/compression/huffman.py @@ -30,7 +30,7 @@ def parse_file(file_path): if not c: break chars[c] = chars[c] + 1 if c in chars.keys() else 1 - return sorted([Letter(c, f) for c, f in chars.items()], key=lambda l: l.freq) + return sorted((Letter(c, f) for c, f in chars.items()), key=lambda l: l.freq) def build_tree(letters): diff --git a/conversions/molecular_chemistry.py b/conversions/molecular_chemistry.py index 8c68459965b0..0024eb5cb5b8 100644 --- a/conversions/molecular_chemistry.py +++ b/conversions/molecular_chemistry.py @@ -20,7 +20,7 @@ def molarity_to_normality(nfactor: int, moles: float, volume: float) -> float: >>> molarity_to_normality(4, 11.4, 5.7) 8 """ - return round((float(moles / volume) * nfactor)) + return round(float(moles / volume) * nfactor) def moles_to_pressure(volume: float, moles: float, temperature: float) -> float: diff --git a/conversions/prefix_conversions.py b/conversions/prefix_conversions.py index 78db4a91709c..a77556433c66 100644 --- a/conversions/prefix_conversions.py +++ b/conversions/prefix_conversions.py @@ -1,8 +1,9 @@ """ Convert International System of Units (SI) and Binary prefixes """ +from __future__ import annotations + from enum import Enum -from typing import Union class SI_Unit(Enum): @@ -41,8 +42,8 @@ class Binary_Unit(Enum): def convert_si_prefix( known_amount: float, - known_prefix: Union[str, SI_Unit], - unknown_prefix: Union[str, SI_Unit], + known_prefix: str | SI_Unit, + unknown_prefix: str | SI_Unit, ) -> float: """ Wikipedia reference: https://en.wikipedia.org/wiki/Binary_prefix @@ -70,8 +71,8 @@ def convert_si_prefix( def convert_binary_prefix( known_amount: float, - known_prefix: Union[str, Binary_Unit], - unknown_prefix: Union[str, Binary_Unit], + known_prefix: str | Binary_Unit, + unknown_prefix: str | Binary_Unit, ) -> float: """ Wikipedia reference: https://en.wikipedia.org/wiki/Metric_prefix diff --git a/data_structures/binary_tree/avl_tree.py b/data_structures/binary_tree/avl_tree.py index e0d3e4d438a8..1ab13777b7a6 100644 --- a/data_structures/binary_tree/avl_tree.py +++ b/data_structures/binary_tree/avl_tree.py @@ -5,15 +5,16 @@ For testing run: python avl_tree.py """ +from __future__ import annotations import math import random -from typing import Any, List, Optional +from typing import Any class my_queue: def __init__(self) -> None: - self.data: List[Any] = [] + self.data: list[Any] = [] self.head: int = 0 self.tail: int = 0 @@ -41,17 +42,17 @@ def print(self) -> None: class my_node: def __init__(self, data: Any) -> None: self.data = data - self.left: Optional[my_node] = None - self.right: Optional[my_node] = None + self.left: my_node | None = None + self.right: my_node | None = None self.height: int = 1 def get_data(self) -> Any: return self.data - def get_left(self) -> Optional["my_node"]: + def get_left(self) -> my_node | None: return self.left - def get_right(self) -> Optional["my_node"]: + def get_right(self) -> my_node | None: return self.right def get_height(self) -> int: @@ -61,11 +62,11 @@ def set_data(self, data: Any) -> None: self.data = data return - def set_left(self, node: Optional["my_node"]) -> None: + def set_left(self, node: my_node | None) -> None: self.left = node return - def set_right(self, node: Optional["my_node"]) -> None: + def set_right(self, node: my_node | None) -> None: self.right = node return @@ -74,7 +75,7 @@ def set_height(self, height: int) -> None: return -def get_height(node: Optional["my_node"]) -> int: +def get_height(node: my_node | None) -> int: if node is None: return 0 return node.get_height() @@ -149,7 +150,7 @@ def rl_rotation(node: my_node) -> my_node: return left_rotation(node) -def insert_node(node: Optional["my_node"], data: Any) -> Optional["my_node"]: +def insert_node(node: my_node | None, data: Any) -> my_node | None: if node is None: return my_node(data) if data < node.get_data(): @@ -197,7 +198,7 @@ def get_leftMost(root: my_node) -> Any: return root.get_data() -def del_node(root: my_node, data: Any) -> Optional["my_node"]: +def del_node(root: my_node, data: Any) -> my_node | None: left_child = root.get_left() right_child = root.get_right() if root.get_data() == data: @@ -275,7 +276,7 @@ class AVLtree: """ def __init__(self) -> None: - self.root: Optional[my_node] = None + self.root: my_node | None = None def get_height(self) -> int: return get_height(self.root) diff --git a/data_structures/binary_tree/basic_binary_tree.py b/data_structures/binary_tree/basic_binary_tree.py index 575b157ee78a..65dccf247b51 100644 --- a/data_structures/binary_tree/basic_binary_tree.py +++ b/data_structures/binary_tree/basic_binary_tree.py @@ -1,4 +1,4 @@ -from typing import Optional +from __future__ import annotations class Node: @@ -8,11 +8,11 @@ class Node: def __init__(self, data: int) -> None: self.data = data - self.left: Optional[Node] = None - self.right: Optional[Node] = None + self.left: Node | None = None + self.right: Node | None = None -def display(tree: Optional[Node]) -> None: # In Order traversal of the tree +def display(tree: Node | None) -> None: # In Order traversal of the tree """ >>> root = Node(1) >>> root.left = Node(0) @@ -30,7 +30,7 @@ def display(tree: Optional[Node]) -> None: # In Order traversal of the tree display(tree.right) -def depth_of_tree(tree: Optional[Node]) -> int: +def depth_of_tree(tree: Node | None) -> int: """ Recursive function that returns the depth of a binary tree. diff --git a/data_structures/binary_tree/binary_search_tree_recursive.py b/data_structures/binary_tree/binary_search_tree_recursive.py index a05e28a7bd54..4bdf4e33dcc3 100644 --- a/data_structures/binary_tree/binary_search_tree_recursive.py +++ b/data_structures/binary_tree/binary_search_tree_recursive.py @@ -7,21 +7,23 @@ To run an example: python binary_search_tree_recursive.py """ +from __future__ import annotations + import unittest -from typing import Iterator, Optional +from typing import Iterator class Node: - def __init__(self, label: int, parent: Optional["Node"]) -> None: + def __init__(self, label: int, parent: Node | None) -> None: self.label = label self.parent = parent - self.left: Optional[Node] = None - self.right: Optional[Node] = None + self.left: Node | None = None + self.right: Node | None = None class BinarySearchTree: def __init__(self) -> None: - self.root: Optional[Node] = None + self.root: Node | None = None def empty(self) -> None: """ @@ -66,9 +68,7 @@ def put(self, label: int) -> None: """ self.root = self._put(self.root, label) - def _put( - self, node: Optional[Node], label: int, parent: Optional[Node] = None - ) -> Node: + def _put(self, node: Node | None, label: int, parent: Node | None = None) -> Node: if node is None: node = Node(label, parent) else: @@ -98,7 +98,7 @@ def search(self, label: int) -> Node: """ return self._search(self.root, label) - def _search(self, node: Optional[Node], label: int) -> Node: + def _search(self, node: Node | None, label: int) -> Node: if node is None: raise Exception(f"Node with label {label} does not exist") else: @@ -140,7 +140,7 @@ def remove(self, label: int) -> None: else: self._reassign_nodes(node, None) - def _reassign_nodes(self, node: Node, new_children: Optional[Node]) -> None: + def _reassign_nodes(self, node: Node, new_children: Node | None) -> None: if new_children: new_children.parent = node.parent @@ -244,7 +244,7 @@ def inorder_traversal(self) -> Iterator[Node]: """ return self._inorder_traversal(self.root) - def _inorder_traversal(self, node: Optional[Node]) -> Iterator[Node]: + def _inorder_traversal(self, node: Node | None) -> Iterator[Node]: if node is not None: yield from self._inorder_traversal(node.left) yield node @@ -266,7 +266,7 @@ def preorder_traversal(self) -> Iterator[Node]: """ return self._preorder_traversal(self.root) - def _preorder_traversal(self, node: Optional[Node]) -> Iterator[Node]: + def _preorder_traversal(self, node: Node | None) -> Iterator[Node]: if node is not None: yield node yield from self._preorder_traversal(node.left) diff --git a/data_structures/binary_tree/binary_tree_traversals.py b/data_structures/binary_tree/binary_tree_traversals.py index 7857880dada9..de9e9d60d272 100644 --- a/data_structures/binary_tree/binary_tree_traversals.py +++ b/data_structures/binary_tree/binary_tree_traversals.py @@ -1,13 +1,14 @@ # https://en.wikipedia.org/wiki/Tree_traversal +from __future__ import annotations + from dataclasses import dataclass -from typing import Optional @dataclass class Node: data: int - left: Optional["Node"] = None - right: Optional["Node"] = None + left: Node | None = None + right: Node | None = None def make_tree() -> Node: diff --git a/data_structures/binary_tree/lazy_segment_tree.py b/data_structures/binary_tree/lazy_segment_tree.py index 9066db294613..94329cb43a76 100644 --- a/data_structures/binary_tree/lazy_segment_tree.py +++ b/data_structures/binary_tree/lazy_segment_tree.py @@ -1,7 +1,6 @@ from __future__ import annotations import math -from typing import List, Union class SegmentTree: @@ -38,7 +37,7 @@ def right(self, idx: int) -> int: 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] @@ -89,7 +88,7 @@ def update( # query with O(lg n) def query( self, idx: int, left_element: int, right_element: int, a: int, b: int - ) -> Union[int, float]: + ) -> int | float: """ query(1, 1, size, a, b) for query max of [a,b] >>> A = [1, 2, -4, 7, 3, -5, 6, 11, -20, 9, 14, 15, 5, 2, -8] diff --git a/data_structures/binary_tree/merge_two_binary_trees.py b/data_structures/binary_tree/merge_two_binary_trees.py index 6b202adb3cf5..d169e0e75b82 100644 --- a/data_structures/binary_tree/merge_two_binary_trees.py +++ b/data_structures/binary_tree/merge_two_binary_trees.py @@ -5,7 +5,7 @@ both nodes to the new value of the merged node. Otherwise, the NOT null node will be used as the node of new tree. """ -from typing import Optional +from __future__ import annotations class Node: @@ -15,11 +15,11 @@ class Node: def __init__(self, value: int = 0) -> None: self.value = value - self.left: Optional[Node] = None - self.right: Optional[Node] = None + self.left: Node | None = None + self.right: Node | None = None -def merge_two_binary_trees(tree1: Optional[Node], tree2: Optional[Node]) -> Node: +def merge_two_binary_trees(tree1: Node | None, tree2: Node | None) -> Node: """ Returns root node of the merged tree. @@ -52,7 +52,7 @@ def merge_two_binary_trees(tree1: Optional[Node], tree2: Optional[Node]) -> Node return tree1 -def print_preorder(root: Optional[Node]) -> None: +def print_preorder(root: Node | None) -> None: """ Print pre-order traversal of the tree. diff --git a/data_structures/binary_tree/red_black_tree.py b/data_structures/binary_tree/red_black_tree.py index de971a712fc1..e27757f20062 100644 --- a/data_structures/binary_tree/red_black_tree.py +++ b/data_structures/binary_tree/red_black_tree.py @@ -2,7 +2,9 @@ python/black : true flake8 : passed """ -from typing import Iterator, Optional +from __future__ import annotations + +from typing import Iterator class RedBlackTree: @@ -21,11 +23,11 @@ class RedBlackTree: def __init__( self, - label: Optional[int] = None, + label: int | None = None, color: int = 0, - parent: Optional["RedBlackTree"] = None, - left: Optional["RedBlackTree"] = None, - right: Optional["RedBlackTree"] = None, + parent: RedBlackTree | None = None, + left: RedBlackTree | None = None, + right: RedBlackTree | None = None, ) -> None: """Initialize a new Red-Black Tree node with the given values: label: The value associated with this node @@ -42,7 +44,7 @@ def __init__( # Here are functions which are specific to red-black trees - def rotate_left(self) -> "RedBlackTree": + def rotate_left(self) -> RedBlackTree: """Rotate the subtree rooted at this node to the left and returns the new root to this subtree. Performing one rotation can be done in O(1). @@ -62,7 +64,7 @@ def rotate_left(self) -> "RedBlackTree": right.parent = parent return right - def rotate_right(self) -> "RedBlackTree": + def rotate_right(self) -> RedBlackTree: """Rotate the subtree rooted at this node to the right and returns the new root to this subtree. Performing one rotation can be done in O(1). @@ -82,7 +84,7 @@ def rotate_right(self) -> "RedBlackTree": left.parent = parent return left - def insert(self, label: int) -> "RedBlackTree": + def insert(self, label: int) -> RedBlackTree: """Inserts label into the subtree rooted at self, performs any rotations necessary to maintain balance, and then returns the new root to this subtree (likely self). @@ -139,7 +141,7 @@ def _insert_repair(self) -> None: self.grandparent.color = 1 self.grandparent._insert_repair() - def remove(self, label: int) -> "RedBlackTree": + def remove(self, label: int) -> RedBlackTree: """Remove label from this tree.""" if self.label == label: if self.left and self.right: @@ -337,7 +339,7 @@ def __contains__(self, label) -> bool: """ return self.search(label) is not None - def search(self, label: int) -> "RedBlackTree": + def search(self, label: int) -> RedBlackTree: """Search through the tree for label, returning its node if it's found, and None otherwise. This method is guaranteed to run in O(log(n)) time. @@ -411,7 +413,7 @@ def get_min(self) -> int: return self.label @property - def grandparent(self) -> "RedBlackTree": + def grandparent(self) -> RedBlackTree: """Get the current node's grandparent, or None if it doesn't exist.""" if self.parent is None: return None @@ -419,7 +421,7 @@ def grandparent(self) -> "RedBlackTree": return self.parent.parent @property - def sibling(self) -> "RedBlackTree": + def sibling(self) -> RedBlackTree: """Get the current node's sibling, or None if it doesn't exist.""" if self.parent is None: return None diff --git a/data_structures/binary_tree/treap.py b/data_structures/binary_tree/treap.py index a09dcc928143..0526b139b3c7 100644 --- a/data_structures/binary_tree/treap.py +++ b/data_structures/binary_tree/treap.py @@ -1,9 +1,6 @@ -# flake8: noqa - from __future__ import annotations from random import random -from typing import Optional, Tuple class Node: @@ -12,11 +9,11 @@ class Node: Treap is a binary tree by value and heap by priority """ - def __init__(self, value: Optional[int] = None): + def __init__(self, value: int | None = None): self.value = value self.prior = random() - self.left: Optional[Node] = None - self.right: Optional[Node] = None + self.left: Node | None = None + self.right: Node | None = None def __repr__(self) -> str: from pprint import pformat @@ -35,7 +32,7 @@ def __str__(self) -> str: return value + left + right -def split(root: Optional[Node], value: int) -> Tuple[Optional[Node], Optional[Node]]: +def split(root: Node | None, value: int) -> tuple[Node | None, Node | None]: """ We split current tree into 2 trees with value: @@ -64,7 +61,7 @@ def split(root: Optional[Node], value: int) -> Tuple[Optional[Node], Optional[No return root, right -def merge(left: Optional[Node], right: Optional[Node]) -> Optional[Node]: +def merge(left: Node | None, right: Node | None) -> Node | None: """ We merge 2 trees into one. Note: all left tree's values must be less than all right tree's @@ -86,7 +83,7 @@ def merge(left: Optional[Node], right: Optional[Node]) -> Optional[Node]: return right -def insert(root: Optional[Node], value: int) -> Optional[Node]: +def insert(root: Node | None, value: int) -> Node | None: """ Insert element @@ -99,7 +96,7 @@ def insert(root: Optional[Node], value: int) -> Optional[Node]: return merge(merge(left, node), right) -def erase(root: Optional[Node], value: int) -> Optional[Node]: +def erase(root: Node | None, value: int) -> Node | None: """ Erase element @@ -112,7 +109,7 @@ def erase(root: Optional[Node], value: int) -> Optional[Node]: return merge(left, right) -def inorder(root: Optional[Node]) -> None: +def inorder(root: Node | None) -> None: """ Just recursive print of a tree """ @@ -124,7 +121,7 @@ def inorder(root: Optional[Node]) -> None: inorder(root.right) -def interactTreap(root: Optional[Node], args: str) -> Optional[Node]: +def interactTreap(root: Node | None, args: str) -> Node | None: """ Commands: + value to add value into treap diff --git a/data_structures/binary_tree/wavelet_tree.py b/data_structures/binary_tree/wavelet_tree.py index 1607244f74ed..173a88ab7316 100644 --- a/data_structures/binary_tree/wavelet_tree.py +++ b/data_structures/binary_tree/wavelet_tree.py @@ -7,8 +7,7 @@ 2. https://www.youtube.com/watch?v=4aSv9PcecDw&t=811s 3. https://www.youtube.com/watch?v=CybAgVF-MMc&t=1178s """ - -from typing import Optional +from __future__ import annotations test_array = [2, 1, 4, 5, 6, 0, 8, 9, 1, 2, 0, 6, 4, 2, 0, 6, 5, 3, 2, 7] @@ -18,8 +17,8 @@ def __init__(self, length: int) -> None: self.minn: int = -1 self.maxx: int = -1 self.map_left: list[int] = [-1] * length - self.left: Optional[Node] = None - self.right: Optional[Node] = None + self.left: Node | None = None + self.right: Node | None = None def __repr__(self) -> str: """ diff --git a/data_structures/hashing/hash_table.py b/data_structures/hashing/hash_table.py index fd9e6eec134c..f4422de53821 100644 --- a/data_structures/hashing/hash_table.py +++ b/data_structures/hashing/hash_table.py @@ -19,7 +19,7 @@ def keys(self): return self._keys def balanced_factor(self): - return sum([1 for slot in self.values if slot is not None]) / ( + return sum(1 for slot in self.values if slot is not None) / ( self.size_table * self.charge_factor ) diff --git a/data_structures/hashing/hash_table_with_linked_list.py b/data_structures/hashing/hash_table_with_linked_list.py index fe838268fce8..f404c5251246 100644 --- a/data_structures/hashing/hash_table_with_linked_list.py +++ b/data_structures/hashing/hash_table_with_linked_list.py @@ -14,7 +14,7 @@ def _set_value(self, key, data): def balanced_factor(self): return ( - sum([self.charge_factor - len(slot) for slot in self.values]) + sum(self.charge_factor - len(slot) for slot in self.values) / self.size_table * self.charge_factor ) diff --git a/data_structures/heap/heap.py b/data_structures/heap/heap.py index 65a70e468d1c..550439edd239 100644 --- a/data_structures/heap/heap.py +++ b/data_structures/heap/heap.py @@ -1,4 +1,6 @@ -from typing import Iterable, List, Optional +from __future__ import annotations + +from typing import Iterable class Heap: @@ -25,19 +27,19 @@ class Heap: """ def __init__(self) -> None: - self.h: List[float] = [] + self.h: list[float] = [] self.heap_size: int = 0 def __repr__(self) -> str: return str(self.h) - def parent_index(self, child_idx: int) -> Optional[int]: + def parent_index(self, child_idx: int) -> int | None: """return the parent index of given child""" if child_idx > 0: return (child_idx - 1) // 2 return None - def left_child_idx(self, parent_idx: int) -> Optional[int]: + def left_child_idx(self, parent_idx: int) -> int | None: """ return the left child index if the left child exists. if not, return None. @@ -47,7 +49,7 @@ def left_child_idx(self, parent_idx: int) -> Optional[int]: return left_child_index return None - def right_child_idx(self, parent_idx: int) -> Optional[int]: + def right_child_idx(self, parent_idx: int) -> int | None: """ return the right child index if the right child exists. if not, return None. diff --git a/data_structures/heap/randomized_heap.py b/data_structures/heap/randomized_heap.py index 0ddc2272efe8..f584f5cb3342 100644 --- a/data_structures/heap/randomized_heap.py +++ b/data_structures/heap/randomized_heap.py @@ -3,7 +3,7 @@ from __future__ import annotations import random -from typing import Generic, Iterable, List, Optional, TypeVar +from typing import Generic, Iterable, TypeVar T = TypeVar("T") @@ -16,8 +16,8 @@ class RandomizedHeapNode(Generic[T]): def __init__(self, value: T) -> None: self._value: T = value - self.left: Optional[RandomizedHeapNode[T]] = None - self.right: Optional[RandomizedHeapNode[T]] = None + self.left: RandomizedHeapNode[T] | None = None + self.right: RandomizedHeapNode[T] | None = None @property def value(self) -> T: @@ -26,8 +26,8 @@ def value(self) -> T: @staticmethod def merge( - root1: Optional[RandomizedHeapNode[T]], root2: Optional[RandomizedHeapNode[T]] - ) -> Optional[RandomizedHeapNode[T]]: + root1: RandomizedHeapNode[T] | None, root2: RandomizedHeapNode[T] | None + ) -> RandomizedHeapNode[T] | None: """Merge 2 nodes together.""" if not root1: return root2 @@ -69,13 +69,13 @@ class RandomizedHeap(Generic[T]): [-1, 0, 1] """ - def __init__(self, data: Optional[Iterable[T]] = ()) -> None: + def __init__(self, data: Iterable[T] | None = ()) -> None: """ >>> rh = RandomizedHeap([3, 1, 3, 7]) >>> rh.to_sorted_list() [1, 3, 3, 7] """ - self._root: Optional[RandomizedHeapNode[T]] = None + self._root: RandomizedHeapNode[T] | None = None for item in data: self.insert(item) @@ -151,7 +151,7 @@ def clear(self): """ self._root = None - def to_sorted_list(self) -> List[T]: + def to_sorted_list(self) -> list[T]: """ Returns sorted list containing all the values in the heap. diff --git a/data_structures/heap/skew_heap.py b/data_structures/heap/skew_heap.py index 417a383f733e..b59441389a91 100644 --- a/data_structures/heap/skew_heap.py +++ b/data_structures/heap/skew_heap.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Generic, Iterable, Iterator, Optional, TypeVar +from typing import Generic, Iterable, Iterator, TypeVar T = TypeVar("T") @@ -15,8 +15,8 @@ class SkewNode(Generic[T]): def __init__(self, value: T) -> None: self._value: T = value - self.left: Optional[SkewNode[T]] = None - self.right: Optional[SkewNode[T]] = None + self.left: SkewNode[T] | None = None + self.right: SkewNode[T] | None = None @property def value(self) -> T: @@ -25,8 +25,8 @@ def value(self) -> T: @staticmethod def merge( - root1: Optional[SkewNode[T]], root2: Optional[SkewNode[T]] - ) -> Optional[SkewNode[T]]: + root1: SkewNode[T] | None, root2: SkewNode[T] | None + ) -> SkewNode[T] | None: """Merge 2 nodes together.""" if not root1: return root2 @@ -69,13 +69,13 @@ class SkewHeap(Generic[T]): [-1, 0, 1] """ - def __init__(self, data: Optional[Iterable[T]] = ()) -> None: + def __init__(self, data: Iterable[T] | None = ()) -> None: """ >>> sh = SkewHeap([3, 1, 3, 7]) >>> list(sh) [1, 3, 3, 7] """ - self._root: Optional[SkewNode[T]] = None + self._root: SkewNode[T] | None = None for item in data: self.insert(item) diff --git a/data_structures/linked_list/merge_two_lists.py b/data_structures/linked_list/merge_two_lists.py index 96ec6b8abc85..43dd461867f1 100644 --- a/data_structures/linked_list/merge_two_lists.py +++ b/data_structures/linked_list/merge_two_lists.py @@ -5,7 +5,6 @@ from collections.abc import Iterable, Iterator from dataclasses import dataclass -from typing import Optional test_data_odd = (3, 9, -11, 0, 7, 5, 1, -1) test_data_even = (4, 6, 2, 0, 8, 10, 3, -2) @@ -14,12 +13,12 @@ @dataclass class Node: data: int - next: Optional[Node] + next: Node | None class SortedLinkedList: def __init__(self, ints: Iterable[int]) -> None: - self.head: Optional[Node] = None + self.head: Node | None = None for i in reversed(sorted(ints)): self.head = Node(i, self.head) diff --git a/data_structures/linked_list/print_reverse.py b/data_structures/linked_list/print_reverse.py index c46f228e7260..f83d5607ffdd 100644 --- a/data_structures/linked_list/print_reverse.py +++ b/data_structures/linked_list/print_reverse.py @@ -1,4 +1,4 @@ -from typing import List +from __future__ import annotations class Node: @@ -16,7 +16,7 @@ def __repr__(self): return "->".join(string_rep) -def make_linked_list(elements_list: List): +def make_linked_list(elements_list: list): """Creates a Linked List from the elements of the given sequence (list/tuple) and returns the head of the Linked List. >>> make_linked_list([]) diff --git a/data_structures/linked_list/skip_list.py b/data_structures/linked_list/skip_list.py index 8f06e6193d52..ee0b4460730c 100644 --- a/data_structures/linked_list/skip_list.py +++ b/data_structures/linked_list/skip_list.py @@ -2,11 +2,10 @@ Based on "Skip Lists: A Probabilistic Alternative to Balanced Trees" by William Pugh https://epaperpress.com/sortsearch/download/skiplist.pdf """ - from __future__ import annotations from random import random -from typing import Generic, Optional, TypeVar +from typing import Generic, TypeVar KT = TypeVar("KT") VT = TypeVar("VT") @@ -124,7 +123,7 @@ def random_level(self) -> int: return level - def _locate_node(self, key) -> tuple[Optional[Node[KT, VT]], list[Node[KT, VT]]]: + def _locate_node(self, key) -> tuple[Node[KT, VT] | None, list[Node[KT, VT]]]: """ :param key: Searched key, :return: Tuple with searched node (or None if given key is not present) @@ -222,7 +221,7 @@ def insert(self, key: KT, value: VT): else: update_node.forward[i] = new_node - def find(self, key: VT) -> Optional[VT]: + def find(self, key: VT) -> VT | None: """ :param key: Search key. :return: Value associated with given key or None if given key is not present. diff --git a/data_structures/stacks/evaluate_postfix_notations.py b/data_structures/stacks/evaluate_postfix_notations.py index 2a4baf9d6b52..51ea353b17de 100644 --- a/data_structures/stacks/evaluate_postfix_notations.py +++ b/data_structures/stacks/evaluate_postfix_notations.py @@ -1,5 +1,3 @@ -from typing import Any, List - """ The Reverse Polish Nation also known as Polish postfix notation or simply postfix notation. @@ -8,6 +6,9 @@ Valid operators are +, -, *, /. Each operand may be an integer or another expression. """ +from __future__ import annotations + +from typing import Any def evaluate_postfix(postfix_notation: list) -> int: @@ -23,7 +24,7 @@ def evaluate_postfix(postfix_notation: list) -> int: return 0 operations = {"+", "-", "*", "/"} - stack: List[Any] = [] + stack: list[Any] = [] for token in postfix_notation: if token in operations: diff --git a/data_structures/stacks/linked_stack.py b/data_structures/stacks/linked_stack.py index 0b9c9d45e61f..85b59a940e39 100644 --- a/data_structures/stacks/linked_stack.py +++ b/data_structures/stacks/linked_stack.py @@ -1,5 +1,7 @@ """ A Stack using a linked list like structure """ -from typing import Any, Optional +from __future__ import annotations + +from typing import Any class Node: @@ -42,7 +44,7 @@ class LinkedStack: """ def __init__(self) -> None: - self.top: Optional[Node] = None + self.top: Node | None = None def __iter__(self): node = self.top diff --git a/data_structures/stacks/stack.py b/data_structures/stacks/stack.py index 245d39b32c07..c62412150626 100644 --- a/data_structures/stacks/stack.py +++ b/data_structures/stacks/stack.py @@ -1,4 +1,4 @@ -from typing import List +from __future__ import annotations class StackOverflowError(BaseException): @@ -15,7 +15,7 @@ class Stack: """ def __init__(self, limit: int = 10): - self.stack: List[int] = [] + self.stack: list[int] = [] self.limit = limit def __bool__(self) -> bool: diff --git a/divide_and_conquer/convex_hull.py b/divide_and_conquer/convex_hull.py index 9c096f671385..63f8dbb20cc0 100644 --- a/divide_and_conquer/convex_hull.py +++ b/divide_and_conquer/convex_hull.py @@ -12,8 +12,9 @@ which have not been implemented here, yet. """ +from __future__ import annotations -from typing import Iterable, List, Set, Union +from typing import Iterable class Point: @@ -84,8 +85,8 @@ def __hash__(self): def _construct_points( - list_of_tuples: Union[List[Point], List[List[float]], Iterable[List[float]]] -) -> List[Point]: + list_of_tuples: list[Point] | list[list[float]] | Iterable[list[float]], +) -> list[Point]: """ constructs a list of points from an array-like object of numbers @@ -114,7 +115,7 @@ def _construct_points( [] """ - points: List[Point] = [] + points: list[Point] = [] if list_of_tuples: for p in list_of_tuples: if isinstance(p, Point): @@ -130,7 +131,7 @@ def _construct_points( return points -def _validate_input(points: Union[List[Point], List[List[float]]]) -> List[Point]: +def _validate_input(points: list[Point] | list[list[float]]) -> list[Point]: """ validates an input instance before a convex-hull algorithms uses it @@ -218,7 +219,7 @@ def _det(a: Point, b: Point, c: Point) -> float: return det -def convex_hull_bf(points: List[Point]) -> List[Point]: +def convex_hull_bf(points: list[Point]) -> list[Point]: """ Constructs the convex hull of a set of 2D points using a brute force algorithm. The algorithm basically considers all combinations of points (i, j) and uses the @@ -291,7 +292,7 @@ def convex_hull_bf(points: List[Point]) -> List[Point]: return sorted(convex_set) -def convex_hull_recursive(points: List[Point]) -> List[Point]: +def convex_hull_recursive(points: list[Point]) -> list[Point]: """ Constructs the convex hull of a set of 2D points using a divide-and-conquer strategy The algorithm exploits the geometric properties of the problem by repeatedly @@ -362,7 +363,7 @@ def convex_hull_recursive(points: List[Point]) -> List[Point]: def _construct_hull( - points: List[Point], left: Point, right: Point, convex_set: Set[Point] + points: list[Point], left: Point, right: Point, convex_set: set[Point] ) -> None: """ @@ -405,7 +406,7 @@ def _construct_hull( _construct_hull(candidate_points, extreme_point, right, convex_set) -def convex_hull_melkman(points: List[Point]) -> List[Point]: +def convex_hull_melkman(points: list[Point]) -> list[Point]: """ Constructs the convex hull of a set of 2D points using the melkman algorithm. The algorithm works by iteratively inserting points of a simple polygonal chain diff --git a/divide_and_conquer/kth_order_statistic.py b/divide_and_conquer/kth_order_statistic.py index f6e81a306bff..666ad1a39b8a 100644 --- a/divide_and_conquer/kth_order_statistic.py +++ b/divide_and_conquer/kth_order_statistic.py @@ -8,8 +8,9 @@ For more information of this algorithm: https://web.stanford.edu/class/archive/cs/cs161/cs161.1138/lectures/08/Small08.pdf """ +from __future__ import annotations + from random import choice -from typing import List def random_pivot(lst): @@ -21,7 +22,7 @@ def random_pivot(lst): return choice(lst) -def kth_number(lst: List[int], k: int) -> int: +def kth_number(lst: list[int], k: int) -> int: """ Return the kth smallest number in lst. >>> kth_number([2, 1, 3, 4, 5], 3) diff --git a/divide_and_conquer/mergesort.py b/divide_and_conquer/mergesort.py index 46a46941cab3..628080cefc9b 100644 --- a/divide_and_conquer/mergesort.py +++ b/divide_and_conquer/mergesort.py @@ -1,7 +1,7 @@ -from typing import List +from __future__ import annotations -def merge(left_half: List, right_half: List) -> List: +def merge(left_half: list, right_half: list) -> list: """Helper function for mergesort. >>> left_half = [-2] @@ -57,7 +57,7 @@ def merge(left_half: List, right_half: List) -> List: return sorted_array -def merge_sort(array: List) -> List: +def merge_sort(array: list) -> list: """Returns a list of sorted array elements using merge sort. >>> from random import shuffle diff --git a/divide_and_conquer/peak.py b/divide_and_conquer/peak.py index f94f83ed3fcb..e60f28bfbe29 100644 --- a/divide_and_conquer/peak.py +++ b/divide_and_conquer/peak.py @@ -7,10 +7,10 @@ (From Kleinberg and Tardos. Algorithm Design. Addison Wesley 2006: Chapter 5 Solved Exercise 1) """ -from typing import List +from __future__ import annotations -def peak(lst: List[int]) -> int: +def peak(lst: list[int]) -> int: """ Return the peak value of `lst`. >>> peak([1, 2, 3, 4, 5, 4, 3, 2, 1]) diff --git a/electronics/electric_power.py b/electronics/electric_power.py index e4e685bbd0f0..ac673d7e3a94 100644 --- a/electronics/electric_power.py +++ b/electronics/electric_power.py @@ -1,9 +1,10 @@ # https://en.m.wikipedia.org/wiki/Electric_power +from __future__ import annotations + from collections import namedtuple -from typing import Tuple -def electric_power(voltage: float, current: float, power: float) -> Tuple: +def electric_power(voltage: float, current: float, power: float) -> tuple: """ This function can calculate any one of the three (voltage, current, power), fundamental value of electrical system. diff --git a/electronics/ohms_law.py b/electronics/ohms_law.py index 41bffa9f87c8..66e737c1f909 100644 --- a/electronics/ohms_law.py +++ b/electronics/ohms_law.py @@ -1,8 +1,8 @@ # https://en.wikipedia.org/wiki/Ohm%27s_law -from typing import Dict +from __future__ import annotations -def ohms_law(voltage: float, current: float, resistance: float) -> Dict[str, float]: +def ohms_law(voltage: float, current: float, resistance: float) -> dict[str, float]: """ Apply Ohm's Law, on any two given electrical values, which can be voltage, current, and resistance, and then in a Python dict return name/value pair of the zero value. diff --git a/graphs/basic_graphs.py b/graphs/basic_graphs.py index 9cd6dd0f9635..db0ef8e7b3ac 100644 --- a/graphs/basic_graphs.py +++ b/graphs/basic_graphs.py @@ -13,7 +13,7 @@ def initialize_unweighted_directed_graph( graph[i + 1] = [] for e in range(edge_count): - x, y = [int(i) for i in _input(f"Edge {e + 1}: ")] + x, y = (int(i) for i in _input(f"Edge {e + 1}: ")) graph[x].append(y) return graph @@ -26,7 +26,7 @@ def initialize_unweighted_undirected_graph( graph[i + 1] = [] for e in range(edge_count): - x, y = [int(i) for i in _input(f"Edge {e + 1}: ")] + x, y = (int(i) for i in _input(f"Edge {e + 1}: ")) graph[x].append(y) graph[y].append(x) return graph @@ -40,14 +40,14 @@ def initialize_weighted_undirected_graph( graph[i + 1] = [] for e in range(edge_count): - x, y, w = [int(i) for i in _input(f"Edge {e + 1}: ")] + x, y, w = (int(i) for i in _input(f"Edge {e + 1}: ")) graph[x].append((y, w)) graph[y].append((x, w)) return graph if __name__ == "__main__": - n, m = [int(i) for i in _input("Number of nodes and edges: ")] + n, m = (int(i) for i in _input("Number of nodes and edges: ")) graph_choice = int( _input( diff --git a/graphs/bellman_ford.py b/graphs/bellman_ford.py index d6d6b2ac7349..0f654a510b59 100644 --- a/graphs/bellman_ford.py +++ b/graphs/bellman_ford.py @@ -11,7 +11,7 @@ def check_negative_cycle( graph: list[dict[str, int]], distance: list[float], edge_count: int ): for j in range(edge_count): - u, v, w = [graph[j][k] for k in ["src", "dst", "weight"]] + u, v, w = (graph[j][k] for k in ["src", "dst", "weight"]) if distance[u] != float("inf") and distance[u] + w < distance[v]: return True return False @@ -38,7 +38,7 @@ def bellman_ford( for i in range(vertex_count - 1): for j in range(edge_count): - u, v, w = [graph[j][k] for k in ["src", "dst", "weight"]] + u, v, w = (graph[j][k] for k in ["src", "dst", "weight"]) if distance[u] != float("inf") and distance[u] + w < distance[v]: distance[v] = distance[u] + w @@ -62,10 +62,10 @@ def bellman_ford( for i in range(E): print("Edge ", i + 1) - src, dest, weight = [ + src, dest, weight = ( int(x) for x in input("Enter source, destination, weight: ").strip().split(" ") - ] + ) graph[i] = {"src": src, "dst": dest, "weight": weight} source = int(input("\nEnter shortest path source:").strip()) diff --git a/graphs/bfs_zero_one_shortest_path.py b/graphs/bfs_zero_one_shortest_path.py index a68b5602c2d1..78047c5d2237 100644 --- a/graphs/bfs_zero_one_shortest_path.py +++ b/graphs/bfs_zero_one_shortest_path.py @@ -1,13 +1,13 @@ -from collections import deque -from collections.abc import Iterator -from dataclasses import dataclass -from typing import Optional, Union - """ Finding the shortest path in 0-1-graph in O(E + V) which is faster than dijkstra. 0-1-graph is the weighted graph with the weights equal to 0 or 1. Link: https://codeforces.com/blog/entry/22276 """ +from __future__ import annotations + +from collections import deque +from collections.abc import Iterator +from dataclasses import dataclass @dataclass @@ -59,7 +59,7 @@ def add_edge(self, from_vertex: int, to_vertex: int, weight: int): self._graph[from_vertex].append(Edge(to_vertex, weight)) - def get_shortest_path(self, start_vertex: int, finish_vertex: int) -> Optional[int]: + def get_shortest_path(self, start_vertex: int, finish_vertex: int) -> int | None: """ Return the shortest distance from start_vertex to finish_vertex in 0-1-graph. 1 1 1 @@ -107,7 +107,7 @@ def get_shortest_path(self, start_vertex: int, finish_vertex: int) -> Optional[i ValueError: No path from start_vertex to finish_vertex. """ queue = deque([start_vertex]) - distances: list[Union[int, None]] = [None] * self.size + distances: list[int | None] = [None] * self.size distances[start_vertex] = 0 while queue: diff --git a/graphs/bidirectional_a_star.py b/graphs/bidirectional_a_star.py index 729d8957bdef..071f1cd685b1 100644 --- a/graphs/bidirectional_a_star.py +++ b/graphs/bidirectional_a_star.py @@ -1,15 +1,12 @@ """ https://en.wikipedia.org/wiki/Bidirectional_search """ - from __future__ import annotations import time from math import sqrt # 1 for manhattan, 0 for euclidean -from typing import Optional - HEURISTIC = 0 grid = [ @@ -50,7 +47,7 @@ def __init__( goal_x: int, goal_y: int, g_cost: int, - parent: Optional[Node], + parent: Node | None, ) -> None: self.pos_x = pos_x self.pos_y = pos_y @@ -157,7 +154,7 @@ def get_successors(self, parent: Node) -> list[Node]: ) return successors - def retrace_path(self, node: Optional[Node]) -> list[TPosition]: + def retrace_path(self, node: Node | None) -> list[TPosition]: """ Retrace the path from parents to parents until start node """ diff --git a/graphs/bidirectional_breadth_first_search.py b/graphs/bidirectional_breadth_first_search.py index 9b84ab21bf7f..27e4f0b16bbf 100644 --- a/graphs/bidirectional_breadth_first_search.py +++ b/graphs/bidirectional_breadth_first_search.py @@ -1,11 +1,9 @@ """ https://en.wikipedia.org/wiki/Bidirectional_search """ - from __future__ import annotations import time -from typing import Optional Path = list[tuple[int, int]] @@ -24,7 +22,7 @@ class Node: def __init__( - self, pos_x: int, pos_y: int, goal_x: int, goal_y: int, parent: Optional[Node] + self, pos_x: int, pos_y: int, goal_x: int, goal_y: int, parent: Node | None ): self.pos_x = pos_x self.pos_y = pos_y @@ -57,7 +55,7 @@ def __init__(self, start: tuple[int, int], goal: tuple[int, int]): self.node_queue = [self.start] self.reached = False - def search(self) -> Optional[Path]: + def search(self) -> Path | None: while self.node_queue: current_node = self.node_queue.pop(0) @@ -93,7 +91,7 @@ def get_successors(self, parent: Node) -> list[Node]: ) return successors - def retrace_path(self, node: Optional[Node]) -> Path: + def retrace_path(self, node: Node | None) -> Path: """ Retrace the path from parents to parents until start node """ @@ -125,7 +123,7 @@ def __init__(self, start, goal): self.bwd_bfs = BreadthFirstSearch(goal, start) self.reached = False - def search(self) -> Optional[Path]: + def search(self) -> Path | None: 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) diff --git a/graphs/breadth_first_search.py b/graphs/breadth_first_search.py index 305db01e19e4..7c626429e5c0 100644 --- a/graphs/breadth_first_search.py +++ b/graphs/breadth_first_search.py @@ -1,13 +1,12 @@ #!/usr/bin/python """ Author: OMKAR PATHAK """ - -from typing import Dict, List, Set +from __future__ import annotations class Graph: def __init__(self) -> None: - self.vertices: Dict[int, List[int]] = {} + self.vertices: dict[int, list[int]] = {} def print_graph(self) -> None: """ @@ -35,7 +34,7 @@ def add_edge(self, from_vertex: int, to_vertex: int) -> None: else: self.vertices[from_vertex] = [to_vertex] - def bfs(self, start_vertex: int) -> Set[int]: + def bfs(self, start_vertex: int) -> set[int]: """ >>> g = Graph() >>> g.add_edge(0, 1) diff --git a/graphs/breadth_first_search_shortest_path.py b/graphs/breadth_first_search_shortest_path.py index 48f8ab1a4956..697a8c634859 100644 --- a/graphs/breadth_first_search_shortest_path.py +++ b/graphs/breadth_first_search_shortest_path.py @@ -3,8 +3,6 @@ """ from __future__ import annotations -from typing import Optional - graph = { "A": ["B", "C", "E"], "B": ["A", "D", "E"], @@ -24,7 +22,7 @@ def __init__(self, graph: dict[str, list[str]], source_vertex: str) -> None: """ self.graph = graph # mapping node to its parent in resulting breadth first tree - self.parent: dict[str, Optional[str]] = {} + self.parent: dict[str, str | None] = {} self.source_vertex = source_vertex def breath_first_search(self) -> None: diff --git a/graphs/depth_first_search.py b/graphs/depth_first_search.py index 5d74a6db9c6b..f20a503ca395 100644 --- a/graphs/depth_first_search.py +++ b/graphs/depth_first_search.py @@ -1,11 +1,8 @@ """Non recursive implementation of a DFS algorithm.""" - from __future__ import annotations -from typing import Set - -def depth_first_search(graph: dict, start: str) -> Set[str]: +def depth_first_search(graph: dict, start: str) -> set[str]: """Depth First Search on Graph :param graph: directed graph in dictionary format :param start: starting vertex as a string diff --git a/graphs/greedy_best_first.py b/graphs/greedy_best_first.py index d5e80247a9b4..d49e65b9d814 100644 --- a/graphs/greedy_best_first.py +++ b/graphs/greedy_best_first.py @@ -4,8 +4,6 @@ from __future__ import annotations -from typing import Optional - Path = list[tuple[int, int]] grid = [ @@ -44,7 +42,7 @@ def __init__( goal_x: int, goal_y: int, g_cost: float, - parent: Optional[Node], + parent: Node | None, ): self.pos_x = pos_x self.pos_y = pos_y @@ -93,7 +91,7 @@ def __init__(self, start: tuple[int, int], goal: tuple[int, int]): self.reached = False - def search(self) -> Optional[Path]: + def search(self) -> Path | None: """ Search for the path, if a path is not found, only the starting position is returned @@ -156,7 +154,7 @@ def get_successors(self, parent: Node) -> list[Node]: ) return successors - def retrace_path(self, node: Optional[Node]) -> Path: + def retrace_path(self, node: Node | None) -> Path: """ Retrace the path from parents to parents until start node """ diff --git a/graphs/minimum_spanning_tree_kruskal.py b/graphs/minimum_spanning_tree_kruskal.py index f21a87a7d534..85d937010489 100644 --- a/graphs/minimum_spanning_tree_kruskal.py +++ b/graphs/minimum_spanning_tree_kruskal.py @@ -40,7 +40,7 @@ def find_parent(i): edges = [] for _ in range(num_edges): - node1, node2, cost = [int(x) for x in input().strip().split()] + node1, node2, cost = (int(x) for x in input().strip().split()) edges.append((node1, node2, cost)) kruskal(num_nodes, edges) diff --git a/graphs/minimum_spanning_tree_prims2.py b/graphs/minimum_spanning_tree_prims2.py index c3444c36f1cf..d924ee3db1e5 100644 --- a/graphs/minimum_spanning_tree_prims2.py +++ b/graphs/minimum_spanning_tree_prims2.py @@ -6,9 +6,10 @@ at a time, from an arbitrary starting vertex, at each step adding the cheapest possible connection from the tree to another vertex. """ +from __future__ import annotations from sys import maxsize -from typing import Generic, Optional, TypeVar +from typing import Generic, TypeVar T = TypeVar("T") @@ -219,7 +220,7 @@ def add_edge(self, node1: T, node2: T, weight: int) -> None: def prims_algo( graph: GraphUndirectedWeighted[T], -) -> tuple[dict[T, int], dict[T, Optional[T]]]: +) -> tuple[dict[T, int], dict[T, T | None]]: """ >>> graph = GraphUndirectedWeighted() @@ -240,7 +241,7 @@ def prims_algo( """ # prim's algorithm for minimum spanning tree dist: dict[T, int] = {node: maxsize for node in graph.connections} - parent: dict[T, Optional[T]] = {node: None for node in graph.connections} + parent: dict[T, T | None] = {node: None for node in graph.connections} priority_queue: MinPriorityQueue[T] = MinPriorityQueue() for node, weight in dist.items(): diff --git a/graphs/page_rank.py b/graphs/page_rank.py index 0f5129146ddf..672405b7345b 100644 --- a/graphs/page_rank.py +++ b/graphs/page_rank.py @@ -43,7 +43,7 @@ def page_rank(nodes, limit=3, d=0.85): print(f"======= Iteration {i + 1} =======") for j, node in enumerate(nodes): ranks[node.name] = (1 - d) + d * sum( - [ranks[ib] / outbounds[ib] for ib in node.inbound] + ranks[ib] / outbounds[ib] for ib in node.inbound ) print(ranks) diff --git a/graphs/scc_kosaraju.py b/graphs/scc_kosaraju.py index 2b34170149bc..fa182aa2faf1 100644 --- a/graphs/scc_kosaraju.py +++ b/graphs/scc_kosaraju.py @@ -1,4 +1,4 @@ -from typing import List +from __future__ import annotations def dfs(u): @@ -39,16 +39,16 @@ def kosaraju(): # n - no of nodes, m - no of edges n, m = list(map(int, input().strip().split())) - graph: List[List[int]] = [[] for i in range(n)] # graph - reversedGraph: List[List[int]] = [[] for i in range(n)] # reversed graph + graph: list[list[int]] = [[] for i in range(n)] # graph + reversedGraph: list[list[int]] = [[] for i in range(n)] # reversed graph # input graph data (edges) for i in range(m): u, v = list(map(int, input().strip().split())) graph[u].append(v) reversedGraph[v].append(u) - stack: List[int] = [] - visit: List[bool] = [False] * n - scc: List[int] = [] - component: List[int] = [] + stack: list[int] = [] + visit: list[bool] = [False] * n + scc: list[int] = [] + component: list[int] = [] print(kosaraju()) diff --git a/hashes/luhn.py b/hashes/luhn.py index 81014120dd80..bb77fd05c556 100644 --- a/hashes/luhn.py +++ b/hashes/luhn.py @@ -1,5 +1,5 @@ """ Luhn Algorithm """ -from typing import List +from __future__ import annotations def is_luhn(string: str) -> bool: @@ -17,9 +17,9 @@ def is_luhn(string: str) -> bool: [False, False, False, True, False, False, False, False, False, False] """ check_digit: int - _vector: List[str] = list(string) + _vector: list[str] = list(string) __vector, check_digit = _vector[:-1], int(_vector[-1]) - vector: List[int] = [int(digit) for digit in __vector] + vector: list[int] = [int(digit) for digit in __vector] vector.reverse() for i, digit in enumerate(vector): diff --git a/knapsack/knapsack.py b/knapsack/knapsack.py index 756443ea6163..18a36c3bcdda 100644 --- a/knapsack/knapsack.py +++ b/knapsack/knapsack.py @@ -1,11 +1,10 @@ -from typing import List - """ A naive recursive implementation of 0-1 Knapsack Problem https://en.wikipedia.org/wiki/Knapsack_problem """ +from __future__ import annotations -def knapsack(capacity: int, weights: List[int], values: List[int], counter: int) -> int: +def knapsack(capacity: int, weights: list[int], values: list[int], counter: int) -> int: """ Returns the maximum value that can be put in a knapsack of a capacity cap, whereby each weight w has a specific value val. diff --git a/linear_algebra/src/lib.py b/linear_algebra/src/lib.py index 5e2f82018f38..74aeb9137666 100644 --- a/linear_algebra/src/lib.py +++ b/linear_algebra/src/lib.py @@ -18,11 +18,11 @@ - function squareZeroMatrix(N) - function randomMatrix(W,H,a,b) """ - +from __future__ import annotations import math import random -from typing import Collection, Optional, Union, overload +from typing import Collection, overload class Vector: @@ -46,7 +46,7 @@ class Vector: TODO: compare-operator """ - def __init__(self, components: Optional[Collection[float]] = None) -> None: + def __init__(self, components: Collection[float] | None = None) -> None: """ input: components or nothing simple constructor for init the vector @@ -97,7 +97,7 @@ def euclidLength(self) -> float: summe += c ** 2 return math.sqrt(summe) - def __add__(self, other: "Vector") -> "Vector": + def __add__(self, other: Vector) -> Vector: """ input: other vector assumes: other vector has the same size @@ -110,7 +110,7 @@ def __add__(self, other: "Vector") -> "Vector": else: raise Exception("must have the same size") - def __sub__(self, other: "Vector") -> "Vector": + def __sub__(self, other: Vector) -> Vector: """ input: other vector assumes: other vector has the same size @@ -124,14 +124,14 @@ def __sub__(self, other: "Vector") -> "Vector": raise Exception("must have the same size") @overload - def __mul__(self, other: float) -> "Vector": + def __mul__(self, other: float) -> Vector: ... @overload - def __mul__(self, other: "Vector") -> float: + def __mul__(self, other: Vector) -> float: ... - def __mul__(self, other: Union[float, "Vector"]) -> Union[float, "Vector"]: + def __mul__(self, other: float | Vector) -> float | Vector: """ mul implements the scalar multiplication and the dot-product @@ -148,7 +148,7 @@ def __mul__(self, other: Union[float, "Vector"]) -> Union[float, "Vector"]: else: # error case raise Exception("invalid operand!") - def copy(self) -> "Vector": + def copy(self) -> Vector: """ copies this vector and returns it. """ @@ -313,14 +313,14 @@ def determinate(self) -> float: raise Exception("matrix is not square") @overload - def __mul__(self, other: float) -> "Matrix": + def __mul__(self, other: float) -> Matrix: ... @overload def __mul__(self, other: Vector) -> Vector: ... - def __mul__(self, other: Union[float, Vector]) -> Union[Vector, "Matrix"]: + def __mul__(self, other: float | Vector) -> Vector | Matrix: """ implements the matrix-vector multiplication. implements the matrix-scalar multiplication @@ -347,7 +347,7 @@ def __mul__(self, other: Union[float, Vector]) -> Union[Vector, "Matrix"]: ] return Matrix(matrix, self.__width, self.__height) - def __add__(self, other: "Matrix") -> "Matrix": + def __add__(self, other: Matrix) -> Matrix: """ implements the matrix-addition. """ @@ -362,7 +362,7 @@ def __add__(self, other: "Matrix") -> "Matrix": else: raise Exception("matrix must have the same dimension!") - def __sub__(self, other: "Matrix") -> "Matrix": + def __sub__(self, other: Matrix) -> Matrix: """ implements the matrix-subtraction. """ diff --git a/machine_learning/similarity_search.py b/machine_learning/similarity_search.py index af845c9109b1..ec1b9f9e3e13 100644 --- a/machine_learning/similarity_search.py +++ b/machine_learning/similarity_search.py @@ -7,8 +7,9 @@ 1. the nearest vector 2. distance between the vector and the nearest vector (float) """ +from __future__ import annotations + import math -from typing import List, Union import numpy as np @@ -33,7 +34,7 @@ def euclidean(input_a: np.ndarray, input_b: np.ndarray) -> float: def similarity_search( dataset: np.ndarray, value_array: np.ndarray -) -> List[List[Union[List[float], float]]]: +) -> list[list[list[float] | float]]: """ :param dataset: Set containing the vectors. Should be ndarray. :param value_array: vector/vectors we want to know the nearest vector from dataset. diff --git a/maths/area_under_curve.py b/maths/area_under_curve.py index 2d01e414b63b..ce0932426ef6 100644 --- a/maths/area_under_curve.py +++ b/maths/area_under_curve.py @@ -1,14 +1,15 @@ """ Approximates the area under the curve using the trapezoidal rule """ +from __future__ import annotations -from typing import Callable, Union +from typing import Callable def trapezoidal_area( - fnc: Callable[[Union[int, float]], Union[int, float]], - x_start: Union[int, float], - x_end: Union[int, float], + fnc: Callable[[int | float], int | float], + x_start: int | float, + x_end: int | float, steps: int = 100, ) -> float: """ diff --git a/maths/average_mean.py b/maths/average_mean.py index e02e307f20c8..274c434ab885 100644 --- a/maths/average_mean.py +++ b/maths/average_mean.py @@ -1,7 +1,7 @@ -from typing import List +from __future__ import annotations -def mean(nums: List) -> float: +def mean(nums: list) -> float: """ Find mean of a list of numbers. Wiki: https://en.wikipedia.org/wiki/Mean diff --git a/maths/average_median.py b/maths/average_median.py index 497bf0c3a714..cd1ec1574893 100644 --- a/maths/average_median.py +++ b/maths/average_median.py @@ -1,7 +1,7 @@ -from typing import Union +from __future__ import annotations -def median(nums: list) -> Union[int, float]: +def median(nums: list) -> int | float: """ Find median of a list of numbers. Wiki: https://en.wikipedia.org/wiki/Median diff --git a/maths/entropy.py b/maths/entropy.py index 43bb3860fc12..498c28f31bc4 100644 --- a/maths/entropy.py +++ b/maths/entropy.py @@ -68,7 +68,7 @@ def calculate_prob(text: str) -> None: my_fir_sum += prob * math.log2(prob) # entropy formula. # print entropy - print("{:.1f}".format(round(-1 * my_fir_sum))) + print(f"{round(-1 * my_fir_sum):.1f}") # two len string all_sum = sum(two_char_strings.values()) @@ -83,10 +83,10 @@ def calculate_prob(text: str) -> None: my_sec_sum += prob * math.log2(prob) # print second entropy - print("{:.1f}".format(round(-1 * my_sec_sum))) + print(f"{round(-1 * my_sec_sum):.1f}") # print the difference between them - print("{:.1f}".format(round((-1 * my_sec_sum) - (-1 * my_fir_sum)))) + print(f"{round((-1 * my_sec_sum) - (-1 * my_fir_sum)):.1f}") def analyze_text(text: str) -> tuple[dict, dict]: diff --git a/maths/euclidean_distance.py b/maths/euclidean_distance.py index 6e0da6370219..a2078161374b 100644 --- a/maths/euclidean_distance.py +++ b/maths/euclidean_distance.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Iterable, Union import numpy as np diff --git a/maths/extended_euclidean_algorithm.py b/maths/extended_euclidean_algorithm.py index e7087636ce09..72afd40aa707 100644 --- a/maths/extended_euclidean_algorithm.py +++ b/maths/extended_euclidean_algorithm.py @@ -12,12 +12,12 @@ # @Email: silentcat@protonmail.com # @Last modified by: pikulet # @Last modified time: 2020-10-02 +from __future__ import annotations import sys -from typing import Tuple -def extended_euclidean_algorithm(a: int, b: int) -> Tuple[int, int]: +def extended_euclidean_algorithm(a: int, b: int) -> tuple[int, int]: """ Extended Euclidean Algorithm. diff --git a/maths/hardy_ramanujanalgo.py b/maths/hardy_ramanujanalgo.py index 90e4913c70a7..e36f763da19e 100644 --- a/maths/hardy_ramanujanalgo.py +++ b/maths/hardy_ramanujanalgo.py @@ -37,7 +37,7 @@ def exactPrimeFactorCount(n): if __name__ == "__main__": n = 51242183 print(f"The number of distinct prime factors is/are {exactPrimeFactorCount(n)}") - print("The value of log(log(n)) is {:.4f}".format(math.log(math.log(n)))) + print(f"The value of log(log(n)) is {math.log(math.log(n)):.4f}") """ The number of distinct prime factors is/are 3 diff --git a/maths/line_length.py b/maths/line_length.py index 1d386b44b50d..c4d986279cda 100644 --- a/maths/line_length.py +++ b/maths/line_length.py @@ -1,11 +1,13 @@ +from __future__ import annotations + import math -from typing import Callable, Union +from typing import Callable def line_length( - fnc: Callable[[Union[int, float]], Union[int, float]], - x_start: Union[int, float], - x_end: Union[int, float], + fnc: Callable[[int | float], int | float], + x_start: int | float, + x_end: int | float, steps: int = 100, ) -> float: diff --git a/maths/max_sum_sliding_window.py b/maths/max_sum_sliding_window.py index 593cb5c8bd67..c6f9b4ed0ad7 100644 --- a/maths/max_sum_sliding_window.py +++ b/maths/max_sum_sliding_window.py @@ -6,10 +6,10 @@ called 'Window sliding technique' where the nested loops can be converted to a single loop to reduce time complexity. """ -from typing import List +from __future__ import annotations -def max_sum_in_array(array: List[int], k: int) -> int: +def max_sum_in_array(array: list[int], k: int) -> int: """ Returns the maximum sum of k consecutive elements >>> arr = [1, 4, 2, 10, 2, 3, 1, 0, 20] diff --git a/maths/median_of_two_arrays.py b/maths/median_of_two_arrays.py index cde12f5d7e3b..55aa587a9c4b 100644 --- a/maths/median_of_two_arrays.py +++ b/maths/median_of_two_arrays.py @@ -1,7 +1,7 @@ -from typing import List +from __future__ import annotations -def median_of_two_arrays(nums1: List[float], nums2: List[float]) -> float: +def median_of_two_arrays(nums1: list[float], nums2: list[float]) -> float: """ >>> median_of_two_arrays([1, 2], [3]) 2 diff --git a/maths/numerical_integration.py b/maths/numerical_integration.py index 87184a76b740..577c41a4440e 100644 --- a/maths/numerical_integration.py +++ b/maths/numerical_integration.py @@ -1,14 +1,15 @@ """ Approximates the area under the curve using the trapezoidal rule """ +from __future__ import annotations -from typing import Callable, Union +from typing import Callable def trapezoidal_area( - fnc: Callable[[Union[int, float]], Union[int, float]], - x_start: Union[int, float], - x_end: Union[int, float], + fnc: Callable[[int | float], int | float], + x_start: int | float, + x_end: int | float, steps: int = 100, ) -> float: diff --git a/maths/sieve_of_eratosthenes.py b/maths/sieve_of_eratosthenes.py index 47a086546900..3cd6ce0b4d9d 100644 --- a/maths/sieve_of_eratosthenes.py +++ b/maths/sieve_of_eratosthenes.py @@ -10,13 +10,12 @@ doctest provider: Bruno Simas Hadlich (https://github.com/brunohadlich) Also thanks to Dmitry (https://github.com/LizardWizzard) for finding the problem """ - +from __future__ import annotations import math -from typing import List -def prime_sieve(num: int) -> List[int]: +def prime_sieve(num: int) -> list[int]: """ Returns a list with all prime numbers up to n. diff --git a/maths/volume.py b/maths/volume.py index 41d2331db3cb..51b2b9fc0334 100644 --- a/maths/volume.py +++ b/maths/volume.py @@ -3,11 +3,12 @@ Wikipedia reference: https://en.wikipedia.org/wiki/Volume """ +from __future__ import annotations + from math import pi, pow -from typing import Union -def vol_cube(side_length: Union[int, float]) -> float: +def vol_cube(side_length: int | float) -> float: """ Calculate the Volume of a Cube. diff --git a/matrix/searching_in_sorted_matrix.py b/matrix/searching_in_sorted_matrix.py index ca6263a32f50..ae81361499e5 100644 --- a/matrix/searching_in_sorted_matrix.py +++ b/matrix/searching_in_sorted_matrix.py @@ -1,10 +1,8 @@ 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: int | float ) -> None: """ >>> search_in_a_sorted_matrix( diff --git a/other/date_to_weekday.py b/other/date_to_weekday.py index bb17130c0da5..9dc68666e3b4 100644 --- a/other/date_to_weekday.py +++ b/other/date_to_weekday.py @@ -14,7 +14,7 @@ def date_to_weekday(inp_date: str) -> str: >>> date_to_weekday("1/1/2021") 'Friday' """ - day, month, year = [int(x) for x in inp_date.split("/")] + day, month, year = (int(x) for x in inp_date.split("/")) if year % 100 == 0: year = "00" new_base_date: str = f"{day}/{month}/{year%100} 0:0:0" diff --git "a/other/davis\342\200\223putnam\342\200\223logemann\342\200\223loveland.py" b/other/davisb_putnamb_logemannb_loveland.py similarity index 94% rename from "other/davis\342\200\223putnam\342\200\223logemann\342\200\223loveland.py" rename to other/davisb_putnamb_logemannb_loveland.py index d16de6dd988b..00068930b89e 100644 --- "a/other/davis\342\200\223putnam\342\200\223logemann\342\200\223loveland.py" +++ b/other/davisb_putnamb_logemannb_loveland.py @@ -8,9 +8,9 @@ For more information about the algorithm: https://en.wikipedia.org/wiki/DPLL_algorithm """ +from __future__ import annotations import random -from typing import Dict, List class Clause: @@ -27,7 +27,7 @@ class Clause: True """ - def __init__(self, literals: List[int]) -> None: + def __init__(self, literals: list[int]) -> None: """ Represent the literals and an assignment in a clause." """ @@ -52,7 +52,7 @@ def __len__(self) -> int: """ return len(self.literals) - def assign(self, model: Dict[str, bool]) -> None: + def assign(self, model: dict[str, bool]) -> None: """ Assign values to literals of the clause as given by model. """ @@ -68,7 +68,7 @@ def assign(self, model: Dict[str, bool]) -> None: value = not value self.literals[literal] = value - def evaluate(self, model: Dict[str, bool]) -> bool: + def evaluate(self, model: dict[str, bool]) -> bool: """ Evaluates the clause with the assignments in model. This has the following steps: @@ -97,7 +97,7 @@ class Formula: {{A1, A2, A3'}, {A5', A2', A1}} is ((A1 v A2 v A3') and (A5' v A2' v A1)) """ - def __init__(self, clauses: List[Clause]) -> None: + def __init__(self, clauses: list[Clause]) -> None: """ Represent the number of clauses and the clauses themselves. """ @@ -146,7 +146,7 @@ def generate_formula() -> Formula: return Formula(set(clauses)) -def generate_parameters(formula: Formula) -> (List[Clause], List[str]): +def generate_parameters(formula: Formula) -> (list[Clause], list[str]): """ Return the clauses and symbols from a formula. A symbol is the uncomplemented form of a literal. @@ -173,8 +173,8 @@ def generate_parameters(formula: Formula) -> (List[Clause], List[str]): def find_pure_symbols( - clauses: List[Clause], symbols: List[str], model: Dict[str, bool] -) -> (List[str], Dict[str, bool]): + clauses: list[Clause], symbols: list[str], model: dict[str, bool] +) -> (list[str], dict[str, bool]): """ Return pure symbols and their values to satisfy clause. Pure symbols are symbols in a formula that exist only @@ -225,8 +225,8 @@ def find_pure_symbols( def find_unit_clauses( - clauses: List[Clause], model: Dict[str, bool] -) -> (List[str], Dict[str, bool]): + clauses: list[Clause], model: dict[str, bool] +) -> (list[str], dict[str, bool]): """ Returns the unit symbols and their values to satisfy clause. Unit symbols are symbols in a formula that are: @@ -273,8 +273,8 @@ def find_unit_clauses( def dpll_algorithm( - clauses: List[Clause], symbols: List[str], model: Dict[str, bool] -) -> (bool, Dict[str, bool]): + clauses: list[Clause], symbols: list[str], model: dict[str, bool] +) -> (bool, dict[str, bool]): """ Returns the model if the formula is satisfiable, else None This has the following steps: diff --git a/other/lfu_cache.py b/other/lfu_cache.py index 40268242f564..88167ac1f2cb 100644 --- a/other/lfu_cache.py +++ b/other/lfu_cache.py @@ -1,4 +1,6 @@ -from typing import Callable, Optional +from __future__ import annotations + +from typing import Callable class DoubleLinkedListNode: @@ -119,7 +121,7 @@ def __contains__(self, key: int) -> bool: """ return key in self.cache - def get(self, key: int) -> Optional[int]: + def get(self, key: int) -> int | None: """ Returns the value for the input key and updates the Double Linked List. Returns None if key is not present in cache diff --git a/other/lru_cache.py b/other/lru_cache.py index 2a9d7e49b279..b74c0a45caf9 100644 --- a/other/lru_cache.py +++ b/other/lru_cache.py @@ -1,4 +1,6 @@ -from typing import Callable, Optional +from __future__ import annotations + +from typing import Callable class DoubleLinkedListNode: @@ -125,7 +127,7 @@ def __contains__(self, key: int) -> bool: return key in self.cache - def get(self, key: int) -> Optional[int]: + def get(self, key: int) -> int | None: """ Returns the value for the input key and updates the Double Linked List. Returns None if key is not present in cache diff --git a/project_euler/problem_001/sol1.py b/project_euler/problem_001/sol1.py index 85ad32294c9b..fcc24c86ec54 100644 --- a/project_euler/problem_001/sol1.py +++ b/project_euler/problem_001/sol1.py @@ -26,7 +26,7 @@ def solution(n: int = 1000) -> int: 0 """ - return sum([e for e in range(3, n) if e % 3 == 0 or e % 5 == 0]) + return sum(e for e in range(3, n) if e % 3 == 0 or e % 5 == 0) if __name__ == "__main__": diff --git a/project_euler/problem_001/sol5.py b/project_euler/problem_001/sol5.py index 7f0b0bd1bc7c..3edc6f245a67 100644 --- a/project_euler/problem_001/sol5.py +++ b/project_euler/problem_001/sol5.py @@ -25,7 +25,7 @@ def solution(n: int = 1000) -> int: 83700 """ - return sum([i for i in range(n) if i % 3 == 0 or i % 5 == 0]) + return sum(i for i in range(n) if i % 3 == 0 or i % 5 == 0) if __name__ == "__main__": diff --git a/project_euler/problem_006/sol3.py b/project_euler/problem_006/sol3.py index c87931309574..529f233c9f8e 100644 --- a/project_euler/problem_006/sol3.py +++ b/project_euler/problem_006/sol3.py @@ -33,7 +33,7 @@ def solution(n: int = 100) -> int: 1582700 """ - sum_of_squares = sum([i * i for i in range(1, n + 1)]) + sum_of_squares = sum(i * i for i in range(1, n + 1)) square_of_sum = int(math.pow(sum(range(1, n + 1)), 2)) return square_of_sum - sum_of_squares diff --git a/project_euler/problem_008/sol2.py b/project_euler/problem_008/sol2.py index d2c1b4f7ca48..7f0540263278 100644 --- a/project_euler/problem_008/sol2.py +++ b/project_euler/problem_008/sol2.py @@ -70,10 +70,7 @@ def solution(n: str = N) -> int: """ return max( - [ - reduce(lambda x, y: int(x) * int(y), n[i : i + 13]) - for i in range(len(n) - 12) - ] + reduce(lambda x, y: int(x) * int(y), n[i : i + 13]) for i in range(len(n) - 12) ) diff --git a/project_euler/problem_012/sol2.py b/project_euler/problem_012/sol2.py index 5ff0d8349b90..7578caa98938 100644 --- a/project_euler/problem_012/sol2.py +++ b/project_euler/problem_012/sol2.py @@ -29,7 +29,7 @@ def triangle_number_generator(): def count_divisors(n): - return sum([2 for i in range(1, int(n ** 0.5) + 1) if n % i == 0 and i * i != n]) + return sum(2 for i in range(1, int(n ** 0.5) + 1) if n % i == 0 and i * i != n) def solution(): diff --git a/project_euler/problem_013/sol1.py b/project_euler/problem_013/sol1.py index 1ea08b12ee93..7a414a9379e0 100644 --- a/project_euler/problem_013/sol1.py +++ b/project_euler/problem_013/sol1.py @@ -18,7 +18,7 @@ def solution(): """ file_path = os.path.join(os.path.dirname(__file__), "num.txt") with open(file_path) as file_hand: - return str(sum([int(line) for line in file_hand]))[:10] + return str(sum(int(line) for line in file_hand))[:10] if __name__ == "__main__": diff --git a/project_euler/problem_014/sol2.py b/project_euler/problem_014/sol2.py index 20ad96327498..7ed68273bcd7 100644 --- a/project_euler/problem_014/sol2.py +++ b/project_euler/problem_014/sol2.py @@ -25,10 +25,10 @@ Which starting number, under one million, produces the longest chain? """ -from typing import List +from __future__ import annotations -def collatz_sequence(n: int) -> List[int]: +def collatz_sequence(n: int) -> list[int]: """Returns the Collatz sequence for n.""" sequence = [n] while n != 1: @@ -54,7 +54,7 @@ def solution(n: int = 1000000) -> int: 13255 """ - result = max([(len(collatz_sequence(i)), i) for i in range(1, n)]) + result = max((len(collatz_sequence(i)), i) for i in range(1, n)) return result[1] diff --git a/project_euler/problem_020/sol2.py b/project_euler/problem_020/sol2.py index 92e1e724a647..676e96e7836a 100644 --- a/project_euler/problem_020/sol2.py +++ b/project_euler/problem_020/sol2.py @@ -28,7 +28,7 @@ def solution(num: int = 100) -> int: >>> solution(1) 1 """ - return sum([int(x) for x in str(factorial(num))]) + return sum(int(x) for x in str(factorial(num))) if __name__ == "__main__": diff --git a/project_euler/problem_021/sol1.py b/project_euler/problem_021/sol1.py index 3fac79156e41..353510ae8f94 100644 --- a/project_euler/problem_021/sol1.py +++ b/project_euler/problem_021/sol1.py @@ -41,11 +41,9 @@ def solution(n: int = 10000) -> int: 0 """ total = sum( - [ - i - for i in range(1, n) - if sum_of_divisors(sum_of_divisors(i)) == i and sum_of_divisors(i) != i - ] + i + for i in range(1, n) + if sum_of_divisors(sum_of_divisors(i)) == i and sum_of_divisors(i) != i ) return total diff --git a/project_euler/problem_033/sol1.py b/project_euler/problem_033/sol1.py index ba6e553d8689..e0c9a058af53 100644 --- a/project_euler/problem_033/sol1.py +++ b/project_euler/problem_033/sol1.py @@ -14,8 +14,9 @@ If the product of these four fractions is given in its lowest common terms, find the value of the denominator. """ +from __future__ import annotations + from fractions import Fraction -from typing import List def is_digit_cancelling(num: int, den: int) -> bool: @@ -26,7 +27,7 @@ def is_digit_cancelling(num: int, den: int) -> bool: return False -def fraction_list(digit_len: int) -> List[str]: +def fraction_list(digit_len: int) -> list[str]: """ >>> fraction_list(2) ['16/64', '19/95', '26/65', '49/98'] diff --git a/project_euler/problem_036/sol1.py b/project_euler/problem_036/sol1.py index 13a749862e5f..425c41221395 100644 --- a/project_euler/problem_036/sol1.py +++ b/project_euler/problem_036/sol1.py @@ -14,11 +14,10 @@ (Please note that the palindromic number, in either base, may not include leading zeros.) """ +from __future__ import annotations -from typing import Union - -def is_palindrome(n: Union[int, str]) -> bool: +def is_palindrome(n: int | str) -> bool: """ Return true if the input n is a palindrome. Otherwise return false. n can be an integer or a string. diff --git a/project_euler/problem_038/sol1.py b/project_euler/problem_038/sol1.py index 6d54f6df7ff8..e4a6d09f8f7d 100644 --- a/project_euler/problem_038/sol1.py +++ b/project_euler/problem_038/sol1.py @@ -37,8 +37,7 @@ => 100 <= a < 334, candidate = a * 10^6 + 2a * 10^3 + 3a = 1002003 * a """ - -from typing import Union +from __future__ import annotations def is_9_pandigital(n: int) -> bool: @@ -55,7 +54,7 @@ def is_9_pandigital(n: int) -> bool: return len(s) == 9 and set(s) == set("123456789") -def solution() -> Union[int, None]: +def solution() -> int | None: """ Return the largest 1 to 9 pandigital 9-digital number that can be formed as the concatenated product of an integer with (1,2,...,n) where n > 1. diff --git a/project_euler/problem_049/sol1.py b/project_euler/problem_049/sol1.py index c0d0715be91c..dd2ef71a38a8 100644 --- a/project_euler/problem_049/sol1.py +++ b/project_euler/problem_049/sol1.py @@ -132,7 +132,7 @@ def solution(): for seq in passed: answer.add("".join([str(i) for i in seq])) - return max([int(x) for x in answer]) + return max(int(x) for x in answer) if __name__ == "__main__": diff --git a/project_euler/problem_050/sol1.py b/project_euler/problem_050/sol1.py index 7d142e5ffc91..cfb1911df5de 100644 --- a/project_euler/problem_050/sol1.py +++ b/project_euler/problem_050/sol1.py @@ -15,10 +15,10 @@ Which prime, below one-million, can be written as the sum of the most consecutive primes? """ -from typing import List +from __future__ import annotations -def prime_sieve(limit: int) -> List[int]: +def prime_sieve(limit: int) -> list[int]: """ Sieve of Erotosthenes Function to return all the prime numbers up to a number 'limit' diff --git a/project_euler/problem_051/sol1.py b/project_euler/problem_051/sol1.py index b160b5a2dbd4..5f607e3ffb42 100644 --- a/project_euler/problem_051/sol1.py +++ b/project_euler/problem_051/sol1.py @@ -15,12 +15,12 @@ Find the smallest prime which, by replacing part of the number (not necessarily adjacent digits) with the same digit, is part of an eight prime value family. """ +from __future__ import annotations from collections import Counter -from typing import List -def prime_sieve(n: int) -> List[int]: +def prime_sieve(n: int) -> list[int]: """ Sieve of Erotosthenes Function to return all the prime numbers up to a certain number @@ -52,7 +52,7 @@ def prime_sieve(n: int) -> List[int]: return primes -def digit_replacements(number: int) -> List[List[int]]: +def digit_replacements(number: int) -> list[list[int]]: """ Returns all the possible families of digit replacements in a number which contains at least one repeating digit diff --git a/project_euler/problem_054/sol1.py b/project_euler/problem_054/sol1.py index d2fd810d1b69..9af7aef5a716 100644 --- a/project_euler/problem_054/sol1.py +++ b/project_euler/problem_054/sol1.py @@ -135,7 +135,7 @@ def hand(self): """Returns the self hand""" return self._hand - def compare_with(self, other: "PokerHand") -> str: + def compare_with(self, other: PokerHand) -> str: """ Determines the outcome of comparing self hand with other hand. Returns the output as 'Win', 'Loss', 'Tie' according to the rules of @@ -220,7 +220,7 @@ def hand_name(self) -> str: else: return name + f", {high}" - def _compare_cards(self, other: "PokerHand") -> str: + def _compare_cards(self, other: PokerHand) -> str: # Enumerate gives us the index as well as the element of a list for index, card_value in enumerate(self._card_values): if card_value != other._card_values[index]: diff --git a/project_euler/problem_056/sol1.py b/project_euler/problem_056/sol1.py index 8eaa6e553342..f1ec03c497be 100644 --- a/project_euler/problem_056/sol1.py +++ b/project_euler/problem_056/sol1.py @@ -30,11 +30,9 @@ def solution(a: int = 100, b: int = 100) -> int: # RETURN the MAXIMUM from the list of SUMs of the list of INT converted from STR of # BASE raised to the POWER return max( - [ - sum([int(x) for x in str(base ** power)]) - for base in range(a) - for power in range(b) - ] + sum(int(x) for x in str(base ** power)) + for base in range(a) + for power in range(b) ) diff --git a/project_euler/problem_059/sol1.py b/project_euler/problem_059/sol1.py index 1f55029b2613..b795dd243b08 100644 --- a/project_euler/problem_059/sol1.py +++ b/project_euler/problem_059/sol1.py @@ -25,23 +25,22 @@ must contain common English words, decrypt the message and find the sum of the ASCII values in the original text. """ - +from __future__ import annotations import string from itertools import cycle, product from pathlib import Path -from typing import List, Optional, Set, Tuple VALID_CHARS: str = ( string.ascii_letters + string.digits + string.punctuation + string.whitespace ) -LOWERCASE_INTS: List[int] = [ord(letter) for letter in string.ascii_lowercase] -VALID_INTS: Set[int] = {ord(char) for char in VALID_CHARS} +LOWERCASE_INTS: list[int] = [ord(letter) for letter in string.ascii_lowercase] +VALID_INTS: set[int] = {ord(char) for char in VALID_CHARS} -COMMON_WORDS: List[str] = ["the", "be", "to", "of", "and", "in", "that", "have"] +COMMON_WORDS: list[str] = ["the", "be", "to", "of", "and", "in", "that", "have"] -def try_key(ciphertext: List[int], key: Tuple[int, ...]) -> Optional[str]: +def try_key(ciphertext: list[int], key: tuple[int, ...]) -> str | None: """ Given an encrypted message and a possible 3-character key, decrypt the message. If the decrypted message contains a invalid character, i.e. not an ASCII letter, @@ -66,7 +65,7 @@ def try_key(ciphertext: List[int], key: Tuple[int, ...]) -> Optional[str]: return decoded -def filter_valid_chars(ciphertext: List[int]) -> List[str]: +def filter_valid_chars(ciphertext: list[int]) -> list[str]: """ Given an encrypted message, test all 3-character strings to try and find the key. Return a list of the possible decrypted messages. @@ -77,7 +76,7 @@ def filter_valid_chars(ciphertext: List[int]) -> List[str]: >>> text in filter_valid_chars(encoded) True """ - possibles: List[str] = [] + possibles: list[str] = [] for key in product(LOWERCASE_INTS, repeat=3): encoded = try_key(ciphertext, key) if encoded is not None: @@ -85,7 +84,7 @@ def filter_valid_chars(ciphertext: List[int]) -> List[str]: return possibles -def filter_common_word(possibles: List[str], common_word: str) -> List[str]: +def filter_common_word(possibles: list[str], common_word: str) -> list[str]: """ Given a list of possible decoded messages, narrow down the possibilities for checking for the presence of a specified common word. Only decoded messages @@ -106,8 +105,8 @@ def solution(filename: str = "p059_cipher.txt") -> int: >>> solution("test_cipher.txt") 3000 """ - ciphertext: List[int] - possibles: List[str] + ciphertext: list[int] + possibles: list[str] common_word: str decoded_text: str data: str = Path(__file__).parent.joinpath(filename).read_text(encoding="utf-8") @@ -121,7 +120,7 @@ def solution(filename: str = "p059_cipher.txt") -> int: break decoded_text = possibles[0] - return sum([ord(char) for char in decoded_text]) + return sum(ord(char) for char in decoded_text) if __name__ == "__main__": diff --git a/project_euler/problem_070/sol1.py b/project_euler/problem_070/sol1.py index 9d27119ba95c..e106800d5716 100644 --- a/project_euler/problem_070/sol1.py +++ b/project_euler/problem_070/sol1.py @@ -28,10 +28,10 @@ Finding totients https://en.wikipedia.org/wiki/Euler's_totient_function#Euler's_product_formula """ -from typing import List +from __future__ import annotations -def get_totients(max_one: int) -> List[int]: +def get_totients(max_one: int) -> list[int]: """ Calculates a list of totients from 0 to max_one exclusive, using the definition of Euler's product formula. diff --git a/project_euler/problem_074/sol1.py b/project_euler/problem_074/sol1.py index 38d4e1439307..a40a629033fa 100644 --- a/project_euler/problem_074/sol1.py +++ b/project_euler/problem_074/sol1.py @@ -66,7 +66,7 @@ def sum_digit_factorials(n: int) -> int: """ if n in CACHE_SUM_DIGIT_FACTORIALS: return CACHE_SUM_DIGIT_FACTORIALS[n] - ret = sum([DIGIT_FACTORIALS[let] for let in str(n)]) + ret = sum(DIGIT_FACTORIALS[let] for let in str(n)) CACHE_SUM_DIGIT_FACTORIALS[n] = ret return ret diff --git a/project_euler/problem_077/sol1.py b/project_euler/problem_077/sol1.py index e92992a90ab3..214e258793f6 100644 --- a/project_euler/problem_077/sol1.py +++ b/project_euler/problem_077/sol1.py @@ -12,10 +12,10 @@ What is the first value which can be written as the sum of primes in over five thousand different ways? """ +from __future__ import annotations from functools import lru_cache from math import ceil -from typing import Optional, Set NUM_PRIMES = 100 @@ -30,7 +30,7 @@ @lru_cache(maxsize=100) -def partition(number_to_partition: int) -> Set[int]: +def partition(number_to_partition: int) -> set[int]: """ Return a set of integers corresponding to unique prime partitions of n. The unique prime partitions can be represented as unique prime decompositions, @@ -47,7 +47,7 @@ def partition(number_to_partition: int) -> Set[int]: elif number_to_partition == 0: return {1} - ret: Set[int] = set() + ret: set[int] = set() prime: int sub: int @@ -60,7 +60,7 @@ def partition(number_to_partition: int) -> Set[int]: return ret -def solution(number_unique_partitions: int = 5000) -> Optional[int]: +def solution(number_unique_partitions: int = 5000) -> int | None: """ Return the smallest integer that can be written as the sum of primes in over m unique ways. diff --git a/project_euler/problem_080/sol1.py b/project_euler/problem_080/sol1.py index db69d7e8451c..517be3fc0ba8 100644 --- a/project_euler/problem_080/sol1.py +++ b/project_euler/problem_080/sol1.py @@ -27,7 +27,7 @@ def solution() -> int: if len(str(sqrt_number)) > 1: answer += int(str(sqrt_number)[0]) sqrt_number = str(sqrt_number)[2:101] - answer += sum([int(x) for x in sqrt_number]) + answer += sum(int(x) for x in sqrt_number) return answer diff --git a/project_euler/problem_081/sol1.py b/project_euler/problem_081/sol1.py index afa143f23b33..aef6106b54df 100644 --- a/project_euler/problem_081/sol1.py +++ b/project_euler/problem_081/sol1.py @@ -22,7 +22,7 @@ def solution(filename: str = "matrix.txt") -> int: >>> solution() 427337 """ - with open(os.path.join(os.path.dirname(__file__), filename), "r") as in_file: + with open(os.path.join(os.path.dirname(__file__), filename)) as in_file: data = in_file.read() grid = [[int(cell) for cell in row.split(",")] for row in data.strip().splitlines()] diff --git a/project_euler/problem_085/sol1.py b/project_euler/problem_085/sol1.py index 74e36b1301a4..d0f29796498c 100644 --- a/project_euler/problem_085/sol1.py +++ b/project_euler/problem_085/sol1.py @@ -44,10 +44,9 @@ Reference: https://en.wikipedia.org/wiki/Triangular_number https://en.wikipedia.org/wiki/Quadratic_formula """ - +from __future__ import annotations from math import ceil, floor, sqrt -from typing import List def solution(target: int = 2000000) -> int: @@ -61,7 +60,7 @@ def solution(target: int = 2000000) -> int: >>> solution(2000000000) 86595 """ - triangle_numbers: List[int] = [0] + triangle_numbers: list[int] = [0] idx: int for idx in range(1, ceil(sqrt(target * 2) * 1.1)): diff --git a/project_euler/problem_089/sol1.py b/project_euler/problem_089/sol1.py index 11582aa4ab1a..1c4e2600f847 100644 --- a/project_euler/problem_089/sol1.py +++ b/project_euler/problem_089/sol1.py @@ -125,7 +125,7 @@ def solution(roman_numerals_filename: str = "/p089_roman.txt") -> int: savings = 0 - file1 = open(os.path.dirname(__file__) + roman_numerals_filename, "r") + file1 = open(os.path.dirname(__file__) + roman_numerals_filename) lines = file1.readlines() for line in lines: original = line.strip() diff --git a/project_euler/problem_101/sol1.py b/project_euler/problem_101/sol1.py index e66316090fb2..553f8f442bb8 100644 --- a/project_euler/problem_101/sol1.py +++ b/project_euler/problem_101/sol1.py @@ -41,11 +41,11 @@ Find the sum of FITs for the BOPs. """ +from __future__ import annotations +from typing import Callable, Union -from typing import Callable, List, Union - -Matrix = List[List[Union[float, int]]] +Matrix = list[list[Union[float, int]]] def solve(matrix: Matrix, vector: Matrix) -> Matrix: @@ -78,9 +78,9 @@ def solve(matrix: Matrix, vector: Matrix) -> Matrix: col = 0 while row < size and col < size: # pivoting - pivot_row = max( - [(abs(augmented[row2][col]), row2) for row2 in range(col, size)] - )[1] + pivot_row = max((abs(augmented[row2][col]), row2) for row2 in range(col, size))[ + 1 + ] if augmented[pivot_row][col] == 0: col += 1 continue @@ -109,7 +109,7 @@ def solve(matrix: Matrix, vector: Matrix) -> Matrix: ] -def interpolate(y_list: List[int]) -> Callable[[int], int]: +def interpolate(y_list: list[int]) -> Callable[[int], int]: """ Given a list of data points (1,y0),(2,y1), ..., return a function that interpolates the data points. We find the coefficients of the interpolating @@ -195,9 +195,9 @@ def solution(func: Callable[[int], int] = question_function, order: int = 10) -> >>> solution(lambda n: n ** 3, 3) 74 """ - data_points: List[int] = [func(x_val) for x_val in range(1, order + 1)] + data_points: list[int] = [func(x_val) for x_val in range(1, order + 1)] - polynomials: List[Callable[[int], int]] = [ + polynomials: list[Callable[[int], int]] = [ interpolate(data_points[:max_coeff]) for max_coeff in range(1, order + 1) ] diff --git a/project_euler/problem_102/sol1.py b/project_euler/problem_102/sol1.py index 00af726656ce..4f6e6361e3e8 100644 --- a/project_euler/problem_102/sol1.py +++ b/project_euler/problem_102/sol1.py @@ -18,12 +18,12 @@ NOTE: The first two examples in the file represent the triangles in the example given above. """ +from __future__ import annotations from pathlib import Path -from typing import List, Tuple -def vector_product(point1: Tuple[int, int], point2: Tuple[int, int]) -> int: +def vector_product(point1: tuple[int, int], point2: tuple[int, int]) -> int: """ Return the 2-d vector product of two vectors. >>> vector_product((1, 2), (-5, 0)) @@ -43,9 +43,9 @@ def contains_origin(x1: int, y1: int, x2: int, y2: int, x3: int, y3: int) -> boo >>> contains_origin(-175, 41, -421, -714, 574, -645) False """ - point_a: Tuple[int, int] = (x1, y1) - point_a_to_b: Tuple[int, int] = (x2 - x1, y2 - y1) - point_a_to_c: Tuple[int, int] = (x3 - x1, y3 - y1) + point_a: tuple[int, int] = (x1, y1) + point_a_to_b: tuple[int, int] = (x2 - x1, y2 - y1) + point_a_to_c: tuple[int, int] = (x3 - x1, y3 - y1) a: float = -vector_product(point_a, point_a_to_b) / vector_product( point_a_to_c, point_a_to_b ) @@ -64,12 +64,12 @@ def solution(filename: str = "p102_triangles.txt") -> int: """ data: str = Path(__file__).parent.joinpath(filename).read_text(encoding="utf-8") - triangles: List[List[int]] = [] + triangles: list[list[int]] = [] for line in data.strip().split("\n"): triangles.append([int(number) for number in line.split(",")]) ret: int = 0 - triangle: List[int] + triangle: list[int] for triangle in triangles: ret += contains_origin(*triangle) diff --git a/project_euler/problem_107/sol1.py b/project_euler/problem_107/sol1.py index 80a10e499f76..6a411a11473d 100644 --- a/project_euler/problem_107/sol1.py +++ b/project_euler/problem_107/sol1.py @@ -27,11 +27,12 @@ We use Prim's algorithm to find a Minimum Spanning Tree. Reference: https://en.wikipedia.org/wiki/Prim%27s_algorithm """ +from __future__ import annotations import os -from typing import Dict, List, Mapping, Set, Tuple +from typing import Mapping -EdgeT = Tuple[int, int] +EdgeT = tuple[int, int] class Graph: @@ -39,9 +40,9 @@ class Graph: A class representing an undirected weighted graph. """ - def __init__(self, vertices: Set[int], edges: Mapping[EdgeT, int]) -> None: - self.vertices: Set[int] = vertices - self.edges: Dict[EdgeT, int] = { + def __init__(self, vertices: set[int], edges: Mapping[EdgeT, int]) -> None: + self.vertices: set[int] = vertices + self.edges: dict[EdgeT, int] = { (min(edge), max(edge)): weight for edge, weight in edges.items() } @@ -59,7 +60,7 @@ def add_edge(self, edge: EdgeT, weight: int) -> None: self.vertices.add(edge[1]) self.edges[(min(edge), max(edge))] = weight - def prims_algorithm(self) -> "Graph": + def prims_algorithm(self) -> Graph: """ Run Prim's algorithm to find the minimum spanning tree. Reference: https://en.wikipedia.org/wiki/Prim%27s_algorithm @@ -98,13 +99,13 @@ def solution(filename: str = "p107_network.txt") -> int: """ script_dir: str = os.path.abspath(os.path.dirname(__file__)) network_file: str = os.path.join(script_dir, filename) - adjacency_matrix: List[List[str]] - edges: Dict[EdgeT, int] = dict() - data: List[str] + adjacency_matrix: list[list[str]] + edges: dict[EdgeT, int] = dict() + data: list[str] edge1: int edge2: int - with open(network_file, "r") as f: + with open(network_file) as f: data = f.read().strip().split("\n") adjaceny_matrix = [line.split(",") for line in data] diff --git a/project_euler/problem_119/sol1.py b/project_euler/problem_119/sol1.py index 7f343ac242e9..60ec16cda1aa 100644 --- a/project_euler/problem_119/sol1.py +++ b/project_euler/problem_119/sol1.py @@ -23,7 +23,7 @@ def digit_sum(n: int) -> int: >>> digit_sum(78910) 25 """ - return sum([int(digit) for digit in str(n)]) + return sum(int(digit) for digit in str(n)) def solution(n: int = 30) -> int: diff --git a/project_euler/problem_123/sol1.py b/project_euler/problem_123/sol1.py index 85350c8bae49..91913222759b 100644 --- a/project_euler/problem_123/sol1.py +++ b/project_euler/problem_123/sol1.py @@ -37,8 +37,9 @@ r = 2pn when n is odd r = 2 when n is even. """ +from __future__ import annotations -from typing import Dict, Generator +from typing import Generator def sieve() -> Generator[int, None, None]: @@ -60,7 +61,7 @@ def sieve() -> Generator[int, None, None]: >>> next(primes) 13 """ - factor_map: Dict[int, int] = {} + factor_map: dict[int, int] = {} prime = 2 while True: factor = factor_map.pop(prime, None) diff --git a/project_euler/problem_180/sol1.py b/project_euler/problem_180/sol1.py index 6112db2ea370..f7c097323c62 100644 --- a/project_euler/problem_180/sol1.py +++ b/project_euler/problem_180/sol1.py @@ -44,11 +44,10 @@ Reference: https://en.wikipedia.org/wiki/Fermat%27s_Last_Theorem """ - +from __future__ import annotations from fractions import Fraction from math import gcd, sqrt -from typing import Tuple def is_sq(number: int) -> bool: @@ -68,7 +67,7 @@ def is_sq(number: int) -> bool: def add_three( x_num: int, x_den: int, y_num: int, y_den: int, z_num: int, z_den: int -) -> Tuple[int, int]: +) -> tuple[int, int]: """ Given the numerators and denominators of three fractions, return the numerator and denominator of their sum in lowest form. @@ -100,7 +99,7 @@ def solution(order: int = 35) -> int: unique_s: set = set() hcf: int total: Fraction = Fraction(0) - fraction_sum: Tuple[int, int] + fraction_sum: tuple[int, int] for x_num in range(1, order + 1): for x_den in range(x_num + 1, order + 1): diff --git a/project_euler/problem_203/sol1.py b/project_euler/problem_203/sol1.py index 227b476da131..030cf12f2a85 100644 --- a/project_euler/problem_203/sol1.py +++ b/project_euler/problem_203/sol1.py @@ -27,12 +27,12 @@ References: - https://en.wikipedia.org/wiki/Pascal%27s_triangle """ +from __future__ import annotations import math -from typing import List, Set -def get_pascal_triangle_unique_coefficients(depth: int) -> Set[int]: +def get_pascal_triangle_unique_coefficients(depth: int) -> set[int]: """ Returns the unique coefficients of a Pascal's triangle of depth "depth". @@ -61,7 +61,7 @@ def get_pascal_triangle_unique_coefficients(depth: int) -> Set[int]: return coefficients -def get_primes_squared(max_number: int) -> List[int]: +def get_primes_squared(max_number: int) -> list[int]: """ Calculates all primes between 2 and round(sqrt(max_number)) and returns them squared up. @@ -92,7 +92,7 @@ def get_primes_squared(max_number: int) -> List[int]: def get_squared_primes_to_use( - num_to_look: int, squared_primes: List[int], previous_index: int + num_to_look: int, squared_primes: list[int], previous_index: int ) -> int: """ Returns an int indicating the last index on which squares of primes @@ -128,8 +128,8 @@ def get_squared_primes_to_use( def get_squarefree( - unique_coefficients: Set[int], squared_primes: List[int] -) -> Set[int]: + unique_coefficients: set[int], squared_primes: list[int] +) -> set[int]: """ Calculates the squarefree numbers inside unique_coefficients given a list of square of primes. diff --git a/scheduling/first_come_first_served.py b/scheduling/first_come_first_served.py index b51fc9fe0c04..c5f61720f97e 100644 --- a/scheduling/first_come_first_served.py +++ b/scheduling/first_come_first_served.py @@ -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. diff --git a/scheduling/round_robin.py b/scheduling/round_robin.py index 4a79301c1816..e8d54dd9a553 100644 --- a/scheduling/round_robin.py +++ b/scheduling/round_robin.py @@ -3,11 +3,12 @@ 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] diff --git a/scheduling/shortest_job_first.py b/scheduling/shortest_job_first.py index a49d037d6a23..17409108a34e 100644 --- a/scheduling/shortest_job_first.py +++ b/scheduling/shortest_job_first.py @@ -3,14 +3,14 @@ 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 ) -> None: """ This function calculates the average of the waiting & turnaround times diff --git a/searches/binary_search.py b/searches/binary_search.py index 35e0dd0596d2..0966cd8de857 100644 --- a/searches/binary_search.py +++ b/searches/binary_search.py @@ -9,12 +9,13 @@ For manual testing run: python3 binary_search.py """ +from __future__ import annotations + import bisect -from typing import List, Optional def bisect_left( - sorted_collection: List[int], item: int, lo: int = 0, hi: int = -1 + sorted_collection: list[int], item: int, lo: int = 0, hi: int = -1 ) -> int: """ Locates the first element in a sorted array that is larger or equal to a given @@ -60,7 +61,7 @@ def bisect_left( def bisect_right( - sorted_collection: List[int], item: int, lo: int = 0, hi: int = -1 + sorted_collection: list[int], item: int, lo: int = 0, hi: int = -1 ) -> int: """ Locates the first element in a sorted array that is larger than a given value. @@ -105,7 +106,7 @@ def bisect_right( def insort_left( - sorted_collection: List[int], item: int, lo: int = 0, hi: int = -1 + sorted_collection: list[int], item: int, lo: int = 0, hi: int = -1 ) -> None: """ Inserts a given value into a sorted array before other values with the same value. @@ -148,7 +149,7 @@ def insort_left( def insort_right( - sorted_collection: List[int], item: int, lo: int = 0, hi: int = -1 + sorted_collection: list[int], item: int, lo: int = 0, hi: int = -1 ) -> None: """ Inserts a given value into a sorted array after other values with the same value. @@ -190,7 +191,7 @@ def insort_right( sorted_collection.insert(bisect_right(sorted_collection, item, lo, hi), item) -def binary_search(sorted_collection: List[int], item: int) -> Optional[int]: +def binary_search(sorted_collection: list[int], item: int) -> int | None: """Pure implementation of binary search algorithm in Python Be careful collection must be ascending sorted, otherwise result will be @@ -228,7 +229,7 @@ def binary_search(sorted_collection: List[int], item: int) -> Optional[int]: return None -def binary_search_std_lib(sorted_collection: List[int], item: int) -> Optional[int]: +def binary_search_std_lib(sorted_collection: list[int], item: int) -> int | None: """Pure implementation of binary search algorithm in Python using stdlib Be careful collection must be ascending sorted, otherwise result will be @@ -258,8 +259,8 @@ def binary_search_std_lib(sorted_collection: List[int], item: int) -> Optional[i def binary_search_by_recursion( - sorted_collection: List[int], item: int, left: int, right: int -) -> Optional[int]: + sorted_collection: list[int], item: int, left: int, right: int +) -> int | None: """Pure implementation of binary search algorithm in Python by recursion diff --git a/searches/fibonacci_search.py b/searches/fibonacci_search.py index ac8ecc99a187..55fc05d39eeb 100644 --- a/searches/fibonacci_search.py +++ b/searches/fibonacci_search.py @@ -13,7 +13,7 @@ from functools import lru_cache -@lru_cache() +@lru_cache def fibonacci(k: int) -> int: """Finds fibonacci number in index k. diff --git a/searches/ternary_search.py b/searches/ternary_search.py index 9422a4ccb966..01e437723473 100644 --- a/searches/ternary_search.py +++ b/searches/ternary_search.py @@ -6,7 +6,7 @@ Time Complexity : O(log3 N) Space Complexity : O(1) """ -from typing import List +from __future__ import annotations # This is the precision for this function which can be altered. # It is recommended for users to keep this number greater than or equal to 10. @@ -16,7 +16,7 @@ # This is the linear search that will occur after the search space has become smaller. -def lin_search(left: int, right: int, array: List[int], target: int) -> int: +def lin_search(left: int, right: int, array: list[int], target: int) -> int: """Perform linear search in list. Returns -1 if element is not found. Parameters @@ -58,7 +58,7 @@ def lin_search(left: int, right: int, array: List[int], target: int) -> int: return -1 -def ite_ternary_search(array: List[int], target: int) -> int: +def ite_ternary_search(array: list[int], target: int) -> int: """Iterative method of the ternary search algorithm. >>> test_list = [0, 1, 2, 8, 13, 17, 19, 32, 42] >>> ite_ternary_search(test_list, 3) @@ -110,7 +110,7 @@ def ite_ternary_search(array: List[int], target: int) -> int: return -1 -def rec_ternary_search(left: int, right: int, array: List[int], target: int) -> int: +def rec_ternary_search(left: int, right: int, array: list[int], target: int) -> int: """Recursive method of the ternary search algorithm. >>> test_list = [0, 1, 2, 8, 13, 17, 19, 32, 42] diff --git a/sorts/bitonic_sort.py b/sorts/bitonic_sort.py index c718973e5ecb..201fecd2ce86 100644 --- a/sorts/bitonic_sort.py +++ b/sorts/bitonic_sort.py @@ -3,10 +3,10 @@ Note that this program works only when size of input is a power of 2. """ -from typing import List +from __future__ import annotations -def comp_and_swap(array: List[int], index1: int, index2: int, direction: int) -> None: +def comp_and_swap(array: list[int], index1: int, index2: int, direction: int) -> None: """Compare the value at given index1 and index2 of the array and swap them as per the given direction. @@ -37,7 +37,7 @@ def comp_and_swap(array: List[int], index1: int, index2: int, direction: int) -> array[index1], array[index2] = array[index2], array[index1] -def bitonic_merge(array: List[int], low: int, length: int, direction: int) -> None: +def bitonic_merge(array: list[int], low: int, length: int, direction: int) -> None: """ It recursively sorts a bitonic sequence in ascending order, if direction = 1, and in descending if direction = 0. @@ -61,7 +61,7 @@ def bitonic_merge(array: List[int], low: int, length: int, direction: int) -> No bitonic_merge(array, low + middle, middle, direction) -def bitonic_sort(array: List[int], low: int, length: int, direction: int) -> None: +def bitonic_sort(array: list[int], low: int, length: int, direction: int) -> None: """ This function first produces a bitonic sequence by recursively sorting its two halves in opposite sorting orders, and then calls bitonic_merge to make them in the diff --git a/sorts/bucket_sort.py b/sorts/bucket_sort.py index 1ac76774f4ba..58242a1cb1f8 100644 --- a/sorts/bucket_sort.py +++ b/sorts/bucket_sort.py @@ -27,7 +27,7 @@ Source: https://en.wikipedia.org/wiki/Bucket_sort """ -from typing import List +from __future__ import annotations def bucket_sort(my_list: list) -> list: @@ -52,7 +52,7 @@ def bucket_sort(my_list: list) -> list: return [] min_value, max_value = min(my_list), max(my_list) bucket_count = int(max_value - min_value) + 1 - buckets: List[list] = [[] for _ in range(bucket_count)] + buckets: list[list] = [[] for _ in range(bucket_count)] for i in range(len(my_list)): buckets[(int(my_list[i] - min_value) // bucket_count)].append(my_list[i]) diff --git a/sorts/msd_radix_sort.py b/sorts/msd_radix_sort.py index 4c3cea30ef68..3cdec4bd0711 100644 --- a/sorts/msd_radix_sort.py +++ b/sorts/msd_radix_sort.py @@ -4,10 +4,10 @@ them. https://en.wikipedia.org/wiki/Radix_sort """ -from typing import List +from __future__ import annotations -def msd_radix_sort(list_of_ints: List[int]) -> List[int]: +def msd_radix_sort(list_of_ints: list[int]) -> list[int]: """ Implementation of the MSD radix sort algorithm. Only works with positive integers @@ -36,7 +36,7 @@ def msd_radix_sort(list_of_ints: List[int]) -> List[int]: return _msd_radix_sort(list_of_ints, most_bits) -def _msd_radix_sort(list_of_ints: List[int], bit_position: int) -> List[int]: +def _msd_radix_sort(list_of_ints: list[int], bit_position: int) -> list[int]: """ Sort the given list based on the bit at bit_position. Numbers with a 0 at that position will be at the start of the list, numbers with a @@ -74,7 +74,7 @@ def _msd_radix_sort(list_of_ints: List[int], bit_position: int) -> List[int]: return res -def msd_radix_sort_inplace(list_of_ints: List[int]): +def msd_radix_sort_inplace(list_of_ints: list[int]): """ Inplace implementation of the MSD radix sort algorithm. Sorts based on the binary representation of the integers. @@ -109,7 +109,7 @@ def msd_radix_sort_inplace(list_of_ints: List[int]): def _msd_radix_sort_inplace( - list_of_ints: List[int], bit_position: int, begin_index: int, end_index: int + list_of_ints: list[int], bit_position: int, begin_index: int, end_index: int ): """ Sort the given list based on the bit at bit_position. Numbers with a diff --git a/sorts/patience_sort.py b/sorts/patience_sort.py index 87f5a4078612..845db517420b 100644 --- a/sorts/patience_sort.py +++ b/sorts/patience_sort.py @@ -1,7 +1,8 @@ +from __future__ import annotations + from bisect import bisect_left from functools import total_ordering from heapq import merge -from typing import List """ A pure Python implementation of the patience sort algorithm @@ -44,7 +45,7 @@ def patience_sort(collection: list) -> list: >>> patience_sort([-3, -17, -48]) [-48, -17, -3] """ - stacks: List[Stack] = [] + stacks: list[Stack] = [] # sort into stacks for element in collection: new_stacks = Stack([element]) @@ -55,7 +56,7 @@ def patience_sort(collection: list) -> list: stacks.append(new_stacks) # use a heap-based merge to merge stack efficiently - collection[:] = merge(*[reversed(stack) for stack in stacks]) + collection[:] = merge(*(reversed(stack) for stack in stacks)) return collection diff --git a/sorts/pigeon_sort.py b/sorts/pigeon_sort.py index 3d81f0643865..3e6d4c09c46f 100644 --- a/sorts/pigeon_sort.py +++ b/sorts/pigeon_sort.py @@ -9,10 +9,10 @@ For manual testing run: python pigeon_sort.py """ -from typing import List +from __future__ import annotations -def pigeon_sort(array: List[int]) -> List[int]: +def pigeon_sort(array: list[int]) -> list[int]: """ Implementation of pigeon hole sort algorithm :param array: Collection of comparable items diff --git a/sorts/quick_sort.py b/sorts/quick_sort.py index 6f51f6eca7db..b099c78861ba 100644 --- a/sorts/quick_sort.py +++ b/sorts/quick_sort.py @@ -7,7 +7,7 @@ For manual testing run: python3 quick_sort.py """ -from typing import List +from __future__ import annotations def quick_sort(collection: list) -> list: @@ -27,8 +27,8 @@ def quick_sort(collection: list) -> list: if len(collection) < 2: return collection pivot = collection.pop() # Use the last element as the first pivot - greater: List[int] = [] # All elements greater than pivot - lesser: List[int] = [] # All elements less than or equal to pivot + greater: list[int] = [] # All elements greater than pivot + lesser: list[int] = [] # All elements less than or equal to pivot for element in collection: (greater if element > pivot else lesser).append(element) return quick_sort(lesser) + [pivot] + quick_sort(greater) diff --git a/sorts/radix_sort.py b/sorts/radix_sort.py index b802b5278119..e433bc507a1e 100644 --- a/sorts/radix_sort.py +++ b/sorts/radix_sort.py @@ -9,10 +9,8 @@ """ from __future__ import annotations -from typing import List - -def radix_sort(list_of_ints: List[int]) -> List[int]: +def radix_sort(list_of_ints: list[int]) -> list[int]: """ Examples: >>> radix_sort([0, 5, 3, 2, 2]) @@ -30,7 +28,7 @@ def radix_sort(list_of_ints: List[int]) -> List[int]: max_digit = max(list_of_ints) while placement <= max_digit: # declare and initialize empty buckets - buckets: List[list] = [list() for _ in range(RADIX)] + buckets: list[list] = [list() for _ in range(RADIX)] # split list_of_ints between the buckets for i in list_of_ints: tmp = int((i / placement) % RADIX) diff --git a/sorts/recursive_insertion_sort.py b/sorts/recursive_insertion_sort.py index 89f88b4a961b..ab2716f8eae5 100644 --- a/sorts/recursive_insertion_sort.py +++ b/sorts/recursive_insertion_sort.py @@ -1,11 +1,8 @@ """ A recursive implementation of the insertion sort algorithm """ - from __future__ import annotations -from typing import List - def rec_insertion_sort(collection: list, n: int): """ @@ -72,6 +69,6 @@ def insert_next(collection: list, index: int): if __name__ == "__main__": numbers = input("Enter integers separated by spaces: ") - number_list: List[int] = [int(num) for num in numbers.split()] + number_list: list[int] = [int(num) for num in numbers.split()] rec_insertion_sort(number_list, len(number_list)) print(number_list) diff --git a/sorts/slowsort.py b/sorts/slowsort.py index 53bb14554ee2..a5f4e873ebb2 100644 --- a/sorts/slowsort.py +++ b/sorts/slowsort.py @@ -8,13 +8,10 @@ Source: https://en.wikipedia.org/wiki/Slowsort """ +from __future__ import annotations -from typing import Optional - -def slowsort( - sequence: list, start: Optional[int] = None, end: Optional[int] = None -) -> None: +def slowsort(sequence: list, start: int | None = None, end: int | None = None) -> None: """ Sorts sequence[start..end] (both inclusive) in-place. start defaults to 0 if not given. diff --git a/strings/aho_corasick.py b/strings/aho_corasick.py index 712cb338aa7e..b9a6a80728f6 100644 --- a/strings/aho_corasick.py +++ b/strings/aho_corasick.py @@ -1,5 +1,6 @@ +from __future__ import annotations + from collections import deque -from typing import Dict, List, Union class Automaton: @@ -13,7 +14,7 @@ def __init__(self, keywords: list[str]): self.add_keyword(keyword) self.set_fail_transitions() - def find_next_state(self, current_state: int, char: str) -> Union[int, None]: + def find_next_state(self, current_state: int, char: str) -> int | None: for state in self.adlist[current_state]["next_states"]: if char == self.adlist[state]["value"]: return state @@ -63,7 +64,7 @@ def set_fail_transitions(self) -> None: + self.adlist[self.adlist[child]["fail_state"]]["output"] ) - def search_in(self, string: str) -> Dict[str, List[int]]: + def search_in(self, string: str) -> dict[str, list[int]]: """ >>> A = Automaton(["what", "hat", "ver", "er"]) >>> A.search_in("whatever, err ... , wherever") diff --git a/strings/boyer_moore_search.py b/strings/boyer_moore_search.py index a3e6cf614eab..8d8ff22f67bd 100644 --- a/strings/boyer_moore_search.py +++ b/strings/boyer_moore_search.py @@ -17,7 +17,7 @@ n=length of main string m=length of pattern string """ -from typing import List +from __future__ import annotations class BoyerMooreSearch: @@ -59,7 +59,7 @@ def mismatch_in_text(self, currentPos: int) -> int: return currentPos + i return -1 - def bad_character_heuristic(self) -> List[int]: + def bad_character_heuristic(self) -> list[int]: # searches pattern in text and returns index positions positions = [] for i in range(self.textLen - self.patLen + 1): diff --git a/strings/knuth_morris_pratt.py b/strings/knuth_morris_pratt.py index a205ce37e3e5..a488c171a93b 100644 --- a/strings/knuth_morris_pratt.py +++ b/strings/knuth_morris_pratt.py @@ -1,4 +1,4 @@ -from typing import List +from __future__ import annotations def kmp(pattern: str, text: str) -> bool: @@ -36,7 +36,7 @@ def kmp(pattern: str, text: str) -> bool: return False -def get_failure_array(pattern: str) -> List[int]: +def get_failure_array(pattern: str) -> list[int]: """ Calculates the new index we should go to if we fail a comparison :param pattern: diff --git a/web_programming/emails_from_url.py b/web_programming/emails_from_url.py index 0571ac3313a3..afaee5bbe854 100644 --- a/web_programming/emails_from_url.py +++ b/web_programming/emails_from_url.py @@ -1,4 +1,6 @@ """Get the site emails from URL.""" +from __future__ import annotations + __author__ = "Muhammad Umer Farooq" __license__ = "MIT" __version__ = "1.0.0" @@ -8,7 +10,6 @@ import re from html.parser import HTMLParser -from typing import Optional from urllib import parse import requests @@ -20,7 +21,7 @@ def __init__(self, domain: str) -> None: self.urls: list[str] = [] self.domain = domain - def handle_starttag(self, tag: str, attrs: list[tuple[str, Optional[str]]]) -> None: + def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None: """ This function parse html to take takes url from tags """ diff --git a/web_programming/fetch_github_info.py b/web_programming/fetch_github_info.py index c9198460f211..aa4e1d7b1963 100644 --- a/web_programming/fetch_github_info.py +++ b/web_programming/fetch_github_info.py @@ -17,8 +17,10 @@ #!/usr/bin/env bash export USER_TOKEN="" """ +from __future__ import annotations + import os -from typing import Any, Dict +from typing import Any import requests @@ -31,7 +33,7 @@ USER_TOKEN = os.environ.get("USER_TOKEN", "") -def fetch_github_info(auth_token: str) -> Dict[Any, Any]: +def fetch_github_info(auth_token: str) -> dict[Any, Any]: """ Fetch GitHub info of a user using the requests module """