Various ruff fixes (#12821)

This commit is contained in:
Christian Clauss
2025-07-06 00:35:29 +02:00
committed by GitHub
parent 7665ba5e25
commit cd3c3c3130
25 changed files with 69 additions and 70 deletions

View File

@ -443,6 +443,7 @@
* [Present Value](financial/present_value.py) * [Present Value](financial/present_value.py)
* [Price Plus Tax](financial/price_plus_tax.py) * [Price Plus Tax](financial/price_plus_tax.py)
* [Simple Moving Average](financial/simple_moving_average.py) * [Simple Moving Average](financial/simple_moving_average.py)
* [Straight Line Depreciation](financial/straight_line_depreciation.py)
* [Time And Half Pay](financial/time_and_half_pay.py) * [Time And Half Pay](financial/time_and_half_pay.py)
## Fractals ## Fractals
@ -790,6 +791,7 @@
* [Sumset](maths/sumset.py) * [Sumset](maths/sumset.py)
* [Sylvester Sequence](maths/sylvester_sequence.py) * [Sylvester Sequence](maths/sylvester_sequence.py)
* [Tanh](maths/tanh.py) * [Tanh](maths/tanh.py)
* [Test Factorial](maths/test_factorial.py)
* [Test Prime Check](maths/test_prime_check.py) * [Test Prime Check](maths/test_prime_check.py)
* [Three Sum](maths/three_sum.py) * [Three Sum](maths/three_sum.py)
* [Trapezoidal Rule](maths/trapezoidal_rule.py) * [Trapezoidal Rule](maths/trapezoidal_rule.py)

View File

@ -79,7 +79,7 @@ class HillCipher:
>>> hill_cipher.replace_digits(26) >>> hill_cipher.replace_digits(26)
'0' '0'
""" """
return self.key_string[round(num)] return self.key_string[(num)]
def check_determinant(self) -> None: def check_determinant(self) -> None:
""" """

View File

@ -39,12 +39,12 @@ https://www.geeksforgeeks.org/segment-tree-efficient-implementation/
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from typing import Any, Generic, TypeVar from typing import Any, TypeVar
T = TypeVar("T") T = TypeVar("T")
class SegmentTree(Generic[T]): class SegmentTree[T]:
def __init__(self, arr: list[T], fnc: Callable[[T, T], T]) -> None: def __init__(self, arr: list[T], fnc: Callable[[T, T], T]) -> None:
""" """
Segment Tree constructor, it works just with commutative combiner. Segment Tree constructor, it works just with commutative combiner.

View File

@ -10,14 +10,14 @@ https://www.youtube.com/watch?v=p33CVV29OG8
from collections.abc import Iterator, MutableMapping from collections.abc import Iterator, MutableMapping
from dataclasses import dataclass from dataclasses import dataclass
from typing import Generic, TypeVar from typing import TypeVar
KEY = TypeVar("KEY") KEY = TypeVar("KEY")
VAL = TypeVar("VAL") VAL = TypeVar("VAL")
@dataclass(slots=True) @dataclass(slots=True)
class _Item(Generic[KEY, VAL]): class _Item[KEY, VAL]:
key: KEY key: KEY
val: VAL val: VAL

View File

@ -2,7 +2,7 @@ from __future__ import annotations
from abc import abstractmethod from abc import abstractmethod
from collections.abc import Iterable from collections.abc import Iterable
from typing import Generic, Protocol, TypeVar from typing import Protocol, TypeVar
class Comparable(Protocol): class Comparable(Protocol):
@ -22,7 +22,7 @@ class Comparable(Protocol):
T = TypeVar("T", bound=Comparable) T = TypeVar("T", bound=Comparable)
class Heap(Generic[T]): class Heap[T: Comparable]:
"""A Max Heap Implementation """A Max Heap Implementation
>>> unsorted = [103, 9, 1, 7, 11, 15, 25, 201, 209, 107, 5] >>> unsorted = [103, 9, 1, 7, 11, 15, 25, 201, 209, 107, 5]

View File

@ -4,12 +4,12 @@ from __future__ import annotations
import random import random
from collections.abc import Iterable from collections.abc import Iterable
from typing import Any, Generic, TypeVar from typing import Any, TypeVar
T = TypeVar("T", bound=bool) T = TypeVar("T", bound=bool)
class RandomizedHeapNode(Generic[T]): class RandomizedHeapNode[T: bool]:
""" """
One node of the randomized heap. Contains the value and references to One node of the randomized heap. Contains the value and references to
two children. two children.
@ -73,7 +73,7 @@ class RandomizedHeapNode(Generic[T]):
return root1 return root1
class RandomizedHeap(Generic[T]): class RandomizedHeap[T: bool]:
""" """
A data structure that allows inserting a new value and to pop the smallest A data structure that allows inserting a new value and to pop the smallest
values. Both operations take O(logN) time where N is the size of the values. Both operations take O(logN) time where N is the size of the

View File

@ -3,12 +3,12 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Iterable, Iterator from collections.abc import Iterable, Iterator
from typing import Any, Generic, TypeVar from typing import Any, TypeVar
T = TypeVar("T", bound=bool) T = TypeVar("T", bound=bool)
class SkewNode(Generic[T]): class SkewNode[T: bool]:
""" """
One node of the skew heap. Contains the value and references to One node of the skew heap. Contains the value and references to
two children. two children.
@ -87,7 +87,7 @@ class SkewNode(Generic[T]):
return result return result
class SkewHeap(Generic[T]): class SkewHeap[T: bool]:
""" """
A data structure that allows inserting a new value and to pop the smallest A data structure that allows inserting a new value and to pop the smallest
values. Both operations take O(logN) time where N is the size of the values. Both operations take O(logN) time where N is the size of the

View File

@ -7,13 +7,13 @@ from __future__ import annotations
from itertools import pairwise from itertools import pairwise
from random import random from random import random
from typing import Generic, TypeVar from typing import TypeVar
KT = TypeVar("KT") KT = TypeVar("KT")
VT = TypeVar("VT") VT = TypeVar("VT")
class Node(Generic[KT, VT]): class Node[KT, VT]:
def __init__(self, key: KT | str = "root", value: VT | None = None): def __init__(self, key: KT | str = "root", value: VT | None = None):
self.key = key self.key = key
self.value = value self.value = value
@ -49,7 +49,7 @@ class Node(Generic[KT, VT]):
return len(self.forward) return len(self.forward)
class SkipList(Generic[KT, VT]): class SkipList[KT, VT]:
def __init__(self, p: float = 0.5, max_level: int = 16): def __init__(self, p: float = 0.5, max_level: int = 16):
self.head: Node[KT, VT] = Node[KT, VT]() self.head: Node[KT, VT] = Node[KT, VT]()
self.level = 0 self.level = 0

View File

@ -1,13 +1,10 @@
"""Queue represented by a Python list""" """Queue represented by a Python list"""
from collections.abc import Iterable from collections.abc import Iterable
from typing import Generic, TypeVar
_T = TypeVar("_T")
class QueueByList(Generic[_T]): class QueueByList[T]:
def __init__(self, iterable: Iterable[_T] | None = None) -> None: def __init__(self, iterable: Iterable[T] | None = None) -> None:
""" """
>>> QueueByList() >>> QueueByList()
Queue(()) Queue(())
@ -16,7 +13,7 @@ class QueueByList(Generic[_T]):
>>> QueueByList((i**2 for i in range(1, 4))) >>> QueueByList((i**2 for i in range(1, 4)))
Queue((1, 4, 9)) Queue((1, 4, 9))
""" """
self.entries: list[_T] = list(iterable or []) self.entries: list[T] = list(iterable or [])
def __len__(self) -> int: def __len__(self) -> int:
""" """
@ -58,7 +55,7 @@ class QueueByList(Generic[_T]):
return f"Queue({tuple(self.entries)})" return f"Queue({tuple(self.entries)})"
def put(self, item: _T) -> None: def put(self, item: T) -> None:
"""Put `item` to the Queue """Put `item` to the Queue
>>> queue = QueueByList() >>> queue = QueueByList()
@ -72,7 +69,7 @@ class QueueByList(Generic[_T]):
self.entries.append(item) self.entries.append(item)
def get(self) -> _T: def get(self) -> T:
""" """
Get `item` from the Queue Get `item` from the Queue
@ -118,7 +115,7 @@ class QueueByList(Generic[_T]):
for _ in range(rotation): for _ in range(rotation):
put(get(0)) put(get(0))
def get_front(self) -> _T: def get_front(self) -> T:
"""Get the front item from the Queue """Get the front item from the Queue
>>> queue = QueueByList((10, 20, 30)) >>> queue = QueueByList((10, 20, 30))

View File

@ -1,13 +1,10 @@
"""Queue implementation using two stacks""" """Queue implementation using two stacks"""
from collections.abc import Iterable from collections.abc import Iterable
from typing import Generic, TypeVar
_T = TypeVar("_T")
class QueueByTwoStacks(Generic[_T]): class QueueByTwoStacks[T]:
def __init__(self, iterable: Iterable[_T] | None = None) -> None: def __init__(self, iterable: Iterable[T] | None = None) -> None:
""" """
>>> QueueByTwoStacks() >>> QueueByTwoStacks()
Queue(()) Queue(())
@ -16,8 +13,8 @@ class QueueByTwoStacks(Generic[_T]):
>>> QueueByTwoStacks((i**2 for i in range(1, 4))) >>> QueueByTwoStacks((i**2 for i in range(1, 4)))
Queue((1, 4, 9)) Queue((1, 4, 9))
""" """
self._stack1: list[_T] = list(iterable or []) self._stack1: list[T] = list(iterable or [])
self._stack2: list[_T] = [] self._stack2: list[T] = []
def __len__(self) -> int: def __len__(self) -> int:
""" """
@ -59,7 +56,7 @@ class QueueByTwoStacks(Generic[_T]):
""" """
return f"Queue({tuple(self._stack2[::-1] + self._stack1)})" return f"Queue({tuple(self._stack2[::-1] + self._stack1)})"
def put(self, item: _T) -> None: def put(self, item: T) -> None:
""" """
Put `item` into the Queue Put `item` into the Queue
@ -74,7 +71,7 @@ class QueueByTwoStacks(Generic[_T]):
self._stack1.append(item) self._stack1.append(item)
def get(self) -> _T: def get(self) -> T:
""" """
Get `item` from the Queue Get `item` from the Queue

View File

@ -1,6 +1,6 @@
from __future__ import annotations from __future__ import annotations
from typing import Generic, TypeVar from typing import TypeVar
T = TypeVar("T") T = TypeVar("T")
@ -13,7 +13,7 @@ class StackUnderflowError(BaseException):
pass pass
class Stack(Generic[T]): class Stack[T]:
"""A stack is an abstract data type that serves as a collection of """A stack is an abstract data type that serves as a collection of
elements with two principal operations: push() and pop(). push() adds an elements with two principal operations: push() and pop(). push() adds an
element to the top of the stack, and pop() removes an element from the top element to the top of the stack, and pop() removes an element from the top

View File

@ -3,19 +3,19 @@
from __future__ import annotations from __future__ import annotations
from typing import Generic, TypeVar from typing import TypeVar
T = TypeVar("T") T = TypeVar("T")
class Node(Generic[T]): class Node[T]:
def __init__(self, data: T): def __init__(self, data: T):
self.data = data # Assign data self.data = data # Assign data
self.next: Node[T] | None = None # Initialize next as null self.next: Node[T] | None = None # Initialize next as null
self.prev: Node[T] | None = None # Initialize prev as null self.prev: Node[T] | None = None # Initialize prev as null
class Stack(Generic[T]): class Stack[T]:
""" """
>>> stack = Stack() >>> stack = Stack()
>>> stack.is_empty() >>> stack.is_empty()

View File

@ -3,12 +3,12 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Iterator from collections.abc import Iterator
from typing import Generic, TypeVar from typing import TypeVar
T = TypeVar("T") T = TypeVar("T")
class Node(Generic[T]): class Node[T]:
def __init__(self, data: T): def __init__(self, data: T):
self.data = data self.data = data
self.next: Node[T] | None = None self.next: Node[T] | None = None
@ -17,7 +17,7 @@ class Node(Generic[T]):
return f"{self.data}" return f"{self.data}"
class LinkedStack(Generic[T]): class LinkedStack[T]:
""" """
Linked List Stack implementing push (to top), Linked List Stack implementing push (to top),
pop (from top) and is_empty pop (from top) and is_empty

View File

@ -21,14 +21,14 @@ from __future__ import annotations
import random import random
import unittest import unittest
from pprint import pformat from pprint import pformat
from typing import Generic, TypeVar from typing import TypeVar
import pytest import pytest
T = TypeVar("T") T = TypeVar("T")
class GraphAdjacencyList(Generic[T]): class GraphAdjacencyList[T]:
def __init__( def __init__(
self, vertices: list[T], edges: list[list[T]], directed: bool = True self, vertices: list[T], edges: list[list[T]], directed: bool = True
) -> None: ) -> None:

View File

@ -21,14 +21,14 @@ from __future__ import annotations
import random import random
import unittest import unittest
from pprint import pformat from pprint import pformat
from typing import Generic, TypeVar from typing import TypeVar
import pytest import pytest
T = TypeVar("T") T = TypeVar("T")
class GraphAdjacencyMatrix(Generic[T]): class GraphAdjacencyMatrix[T]:
def __init__( def __init__(
self, vertices: list[T], edges: list[list[T]], directed: bool = True self, vertices: list[T], edges: list[list[T]], directed: bool = True
) -> None: ) -> None:

View File

@ -6,12 +6,12 @@
from __future__ import annotations from __future__ import annotations
from pprint import pformat from pprint import pformat
from typing import Generic, TypeVar from typing import TypeVar
T = TypeVar("T") T = TypeVar("T")
class GraphAdjacencyList(Generic[T]): class GraphAdjacencyList[T]:
""" """
Adjacency List type Graph Data Structure that accounts for directed and undirected Adjacency List type Graph Data Structure that accounts for directed and undirected
Graphs. Initialize graph object indicating whether it's directed or undirected. Graphs. Initialize graph object indicating whether it's directed or undirected.

View File

@ -1,11 +1,11 @@
from __future__ import annotations from __future__ import annotations
from typing import Generic, TypeVar from typing import TypeVar
T = TypeVar("T") T = TypeVar("T")
class DisjointSetTreeNode(Generic[T]): class DisjointSetTreeNode[T]:
# Disjoint Set Node to store the parent and rank # Disjoint Set Node to store the parent and rank
def __init__(self, data: T) -> None: def __init__(self, data: T) -> None:
self.data = data self.data = data
@ -13,7 +13,7 @@ class DisjointSetTreeNode(Generic[T]):
self.rank = 0 self.rank = 0
class DisjointSetTree(Generic[T]): class DisjointSetTree[T]:
# Disjoint Set DataStructure # Disjoint Set DataStructure
def __init__(self) -> None: def __init__(self) -> None:
# map from node name to the node object # map from node name to the node object
@ -46,7 +46,7 @@ class DisjointSetTree(Generic[T]):
self.link(self.find_set(data1), self.find_set(data2)) self.link(self.find_set(data1), self.find_set(data2))
class GraphUndirectedWeighted(Generic[T]): class GraphUndirectedWeighted[T]:
def __init__(self) -> None: def __init__(self) -> None:
# connections: map from the node to the neighbouring nodes (with weights) # connections: map from the node to the neighbouring nodes (with weights)
self.connections: dict[T, dict[T, int]] = {} self.connections: dict[T, dict[T, int]] = {}

View File

@ -10,7 +10,7 @@ connection from the tree to another vertex.
from __future__ import annotations from __future__ import annotations
from sys import maxsize from sys import maxsize
from typing import Generic, TypeVar from typing import TypeVar
T = TypeVar("T") T = TypeVar("T")
@ -47,7 +47,7 @@ def get_child_right_position(position: int) -> int:
return (2 * position) + 2 return (2 * position) + 2
class MinPriorityQueue(Generic[T]): class MinPriorityQueue[T]:
""" """
Minimum Priority Queue Class Minimum Priority Queue Class
@ -184,7 +184,7 @@ class MinPriorityQueue(Generic[T]):
self.position_map[node2_elem] = node1_pos self.position_map[node2_elem] = node1_pos
class GraphUndirectedWeighted(Generic[T]): class GraphUndirectedWeighted[T]:
""" """
Graph Undirected Weighted Class Graph Undirected Weighted Class
@ -217,7 +217,7 @@ class GraphUndirectedWeighted(Generic[T]):
self.connections[node2][node1] = weight self.connections[node2][node1] = weight
def prims_algo( def prims_algo[T](
graph: GraphUndirectedWeighted[T], graph: GraphUndirectedWeighted[T],
) -> tuple[dict[T, int], dict[T, T | None]]: ) -> tuple[dict[T, int], dict[T, T | None]]:
""" """

View File

@ -260,7 +260,7 @@ class Matrix:
if position is None: if position is None:
self.rows.append(row) self.rows.append(row)
else: else:
self.rows = self.rows[0:position] + [row] + self.rows[position:] self.rows = [*self.rows[0:position], row, *self.rows[position:]]
def add_column(self, column: list[int], position: int | None = None) -> None: def add_column(self, column: list[int], position: int | None = None) -> None:
type_error = TypeError( type_error = TypeError(
@ -279,7 +279,7 @@ class Matrix:
self.rows = [self.rows[i] + [column[i]] for i in range(self.num_rows)] self.rows = [self.rows[i] + [column[i]] for i in range(self.num_rows)]
else: else:
self.rows = [ self.rows = [
self.rows[i][0:position] + [column[i]] + self.rows[i][position:] [*self.rows[i][0:position], column[i], *self.rows[i][position:]]
for i in range(self.num_rows) for i in range(self.num_rows)
] ]

View File

@ -2,12 +2,12 @@ from __future__ import annotations
import sys import sys
from collections import deque from collections import deque
from typing import Generic, TypeVar from typing import TypeVar
T = TypeVar("T") T = TypeVar("T")
class LRUCache(Generic[T]): class LRUCache[T]:
""" """
Page Replacement Algorithm, Least Recently Used (LRU) Caching. Page Replacement Algorithm, Least Recently Used (LRU) Caching.

View File

@ -1,13 +1,13 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from typing import Generic, TypeVar from typing import TypeVar
T = TypeVar("T") T = TypeVar("T")
U = TypeVar("U") U = TypeVar("U")
class DoubleLinkedListNode(Generic[T, U]): class DoubleLinkedListNode[T, U]:
""" """
Double Linked List Node built specifically for LFU Cache Double Linked List Node built specifically for LFU Cache
@ -30,7 +30,7 @@ class DoubleLinkedListNode(Generic[T, U]):
) )
class DoubleLinkedList(Generic[T, U]): class DoubleLinkedList[T, U]:
""" """
Double Linked List built specifically for LFU Cache Double Linked List built specifically for LFU Cache
@ -161,7 +161,7 @@ class DoubleLinkedList(Generic[T, U]):
return node return node
class LFUCache(Generic[T, U]): class LFUCache[T, U]:
""" """
LFU Cache to store a given capacity of data. Can be used as a stand-alone object LFU Cache to store a given capacity of data. Can be used as a stand-alone object
or as a function decorator. or as a function decorator.

View File

@ -1,13 +1,13 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from typing import Generic, TypeVar from typing import TypeVar
T = TypeVar("T") T = TypeVar("T")
U = TypeVar("U") U = TypeVar("U")
class DoubleLinkedListNode(Generic[T, U]): class DoubleLinkedListNode[T, U]:
""" """
Double Linked List Node built specifically for LRU Cache Double Linked List Node built specifically for LRU Cache
@ -28,7 +28,7 @@ class DoubleLinkedListNode(Generic[T, U]):
) )
class DoubleLinkedList(Generic[T, U]): class DoubleLinkedList[T, U]:
""" """
Double Linked List built specifically for LRU Cache Double Linked List built specifically for LRU Cache
@ -143,7 +143,7 @@ class DoubleLinkedList(Generic[T, U]):
return node return node
class LRUCache(Generic[T, U]): class LRUCache[T, U]:
""" """
LRU Cache to store a given capacity of data. Can be used as a stand-alone object LRU Cache to store a given capacity of data. Can be used as a stand-alone object
or as a function decorator. or as a function decorator.

View File

@ -112,11 +112,14 @@ lint.ignore = [
"EXE001", # Shebang is present but file is not executable -- DO NOT FIX "EXE001", # Shebang is present but file is not executable -- DO NOT FIX
"G004", # Logging statement uses f-string "G004", # Logging statement uses f-string
"ISC001", # Conflicts with ruff format -- DO NOT FIX "ISC001", # Conflicts with ruff format -- DO NOT FIX
"PLC0415", # import-outside-top-level -- DO NOT FIX
"PLC1901", # `{}` can be simplified to `{}` as an empty string is falsey "PLC1901", # `{}` can be simplified to `{}` as an empty string is falsey
"PLW060", # Using global for `{name}` but no assignment is done -- DO NOT FIX "PLW060", # Using global for `{name}` but no assignment is done -- DO NOT FIX
"PLW1641", # eq-without-hash
"PLW2901", # PLW2901: Redefined loop variable -- FIX ME "PLW2901", # PLW2901: Redefined loop variable -- FIX ME
"PT011", # `pytest.raises(Exception)` is too broad, set the `match` parameter or use a more specific exception "PT011", # `pytest.raises(Exception)` is too broad, set the `match` parameter or use a more specific exception
"PT018", # Assertion should be broken down into multiple parts "PT018", # Assertion should be broken down into multiple parts
"PT028", # pytest-parameter-with-default-argument
"S101", # Use of `assert` detected -- DO NOT FIX "S101", # Use of `assert` detected -- DO NOT FIX
"S311", # Standard pseudo-random generators are not suitable for cryptographic purposes -- FIX ME "S311", # Standard pseudo-random generators are not suitable for cryptographic purposes -- FIX ME
"SIM905", # Consider using a list literal instead of `str.split` -- DO NOT FIX "SIM905", # Consider using a list literal instead of `str.split` -- DO NOT FIX

View File

@ -24,7 +24,7 @@ class Comparable(Protocol):
T = TypeVar("T", bound=Comparable) T = TypeVar("T", bound=Comparable)
def insertion_sort(collection: MutableSequence[T]) -> MutableSequence[T]: def insertion_sort[T: Comparable](collection: MutableSequence[T]) -> MutableSequence[T]:
"""A pure Python implementation of the insertion sort algorithm """A pure Python implementation of the insertion sort algorithm
:param collection: some mutable ordered collection with heterogeneous :param collection: some mutable ordered collection with heterogeneous

View File

@ -19,7 +19,7 @@ def insertion_sort(lst):
for index in range(1, length): for index in range(1, length):
value = lst[index] value = lst[index]
pos = binary_search(lst, value, 0, index - 1) pos = binary_search(lst, value, 0, index - 1)
lst = lst[:pos] + [value] + lst[pos:index] + lst[index + 1 :] lst = [*lst[:pos], value, *lst[pos:index], *lst[index + 1 :]]
return lst return lst