From d0c54acd75cedf14cff353869482a0487fea1697 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Fri, 6 Oct 2023 04:31:11 +0200 Subject: [PATCH] Use dataclasses in singly_linked_list.py (#9886) --- DIRECTORY.md | 7 + .../linked_list/singly_linked_list.py | 151 ++++++++++-------- 2 files changed, 93 insertions(+), 65 deletions(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index c199a4329..a975b9264 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -25,6 +25,7 @@ * [Combination Sum](backtracking/combination_sum.py) * [Hamiltonian Cycle](backtracking/hamiltonian_cycle.py) * [Knight Tour](backtracking/knight_tour.py) + * [Match Word Pattern](backtracking/match_word_pattern.py) * [Minimax](backtracking/minimax.py) * [N Queens](backtracking/n_queens.py) * [N Queens Math](backtracking/n_queens_math.py) @@ -199,6 +200,7 @@ * [Red Black Tree](data_structures/binary_tree/red_black_tree.py) * [Segment Tree](data_structures/binary_tree/segment_tree.py) * [Segment Tree Other](data_structures/binary_tree/segment_tree_other.py) + * [Symmetric Tree](data_structures/binary_tree/symmetric_tree.py) * [Treap](data_structures/binary_tree/treap.py) * [Wavelet Tree](data_structures/binary_tree/wavelet_tree.py) * Disjoint Set @@ -277,6 +279,7 @@ * [Convolve](digital_image_processing/filters/convolve.py) * [Gabor Filter](digital_image_processing/filters/gabor_filter.py) * [Gaussian Filter](digital_image_processing/filters/gaussian_filter.py) + * [Laplacian Filter](digital_image_processing/filters/laplacian_filter.py) * [Local Binary Pattern](digital_image_processing/filters/local_binary_pattern.py) * [Median Filter](digital_image_processing/filters/median_filter.py) * [Sobel Filter](digital_image_processing/filters/sobel_filter.py) @@ -365,8 +368,10 @@ * [Ind Reactance](electronics/ind_reactance.py) * [Ohms Law](electronics/ohms_law.py) * [Real And Reactive Power](electronics/real_and_reactive_power.py) + * [Resistor Color Code](electronics/resistor_color_code.py) * [Resistor Equivalence](electronics/resistor_equivalence.py) * [Resonant Frequency](electronics/resonant_frequency.py) + * [Wheatstone Bridge](electronics/wheatstone_bridge.py) ## File Transfer * [Receive File](file_transfer/receive_file.py) @@ -415,6 +420,7 @@ * [Check Bipartite Graph Dfs](graphs/check_bipartite_graph_dfs.py) * [Check Cycle](graphs/check_cycle.py) * [Connected Components](graphs/connected_components.py) + * [Deep Clone Graph](graphs/deep_clone_graph.py) * [Depth First Search](graphs/depth_first_search.py) * [Depth First Search 2](graphs/depth_first_search_2.py) * [Dijkstra](graphs/dijkstra.py) @@ -1159,6 +1165,7 @@ * [Autocomplete Using Trie](strings/autocomplete_using_trie.py) * [Barcode Validator](strings/barcode_validator.py) * [Boyer Moore Search](strings/boyer_moore_search.py) + * [Camel Case To Snake Case](strings/camel_case_to_snake_case.py) * [Can String Be Rearranged As Palindrome](strings/can_string_be_rearranged_as_palindrome.py) * [Capitalize](strings/capitalize.py) * [Check Anagrams](strings/check_anagrams.py) diff --git a/data_structures/linked_list/singly_linked_list.py b/data_structures/linked_list/singly_linked_list.py index f4b2ddce1..2c6713a47 100644 --- a/data_structures/linked_list/singly_linked_list.py +++ b/data_structures/linked_list/singly_linked_list.py @@ -1,27 +1,38 @@ +from __future__ import annotations + +from collections.abc import Iterator +from dataclasses import dataclass from typing import Any +@dataclass class Node: - def __init__(self, data: Any): - """ - Create and initialize Node class instance. - >>> Node(20) - Node(20) - >>> Node("Hello, world!") - Node(Hello, world!) - >>> Node(None) - Node(None) - >>> Node(True) - Node(True) - """ - self.data = data - self.next = None + """ + Create and initialize Node class instance. + >>> Node(20) + Node(20) + >>> Node("Hello, world!") + Node(Hello, world!) + >>> Node(None) + Node(None) + >>> Node(True) + Node(True) + """ + + data: Any + next_node: Node | None = None def __repr__(self) -> str: """ Get the string representation of this node. >>> Node(10).__repr__() 'Node(10)' + >>> repr(Node(10)) + 'Node(10)' + >>> str(Node(10)) + 'Node(10)' + >>> Node(10) + Node(10) """ return f"Node({self.data})" @@ -31,10 +42,12 @@ class LinkedList: """ Create and initialize LinkedList class instance. >>> linked_list = LinkedList() + >>> linked_list.head is None + True """ self.head = None - def __iter__(self) -> Any: + def __iter__(self) -> Iterator[Any]: """ This function is intended for iterators to access and iterate through data inside linked list. @@ -51,7 +64,7 @@ class LinkedList: node = self.head while node: yield node.data - node = node.next + node = node.next_node def __len__(self) -> int: """ @@ -81,9 +94,16 @@ class LinkedList: >>> linked_list.insert_tail(1) >>> linked_list.insert_tail(3) >>> linked_list.__repr__() - '1->3' + '1 -> 3' + >>> repr(linked_list) + '1 -> 3' + >>> str(linked_list) + '1 -> 3' + >>> linked_list.insert_tail(5) + >>> f"{linked_list}" + '1 -> 3 -> 5' """ - return "->".join([str(item) for item in self]) + return " -> ".join([str(item) for item in self]) def __getitem__(self, index: int) -> Any: """ @@ -134,7 +154,7 @@ class LinkedList: raise ValueError("list index out of range.") current = self.head for _ in range(index): - current = current.next + current = current.next_node current.data = data def insert_tail(self, data: Any) -> None: @@ -146,10 +166,10 @@ class LinkedList: tail >>> linked_list.insert_tail("tail_2") >>> linked_list - tail->tail_2 + tail -> tail_2 >>> linked_list.insert_tail("tail_3") >>> linked_list - tail->tail_2->tail_3 + tail -> tail_2 -> tail_3 """ self.insert_nth(len(self), data) @@ -162,10 +182,10 @@ class LinkedList: head >>> linked_list.insert_head("head_2") >>> linked_list - head_2->head + head_2 -> head >>> linked_list.insert_head("head_3") >>> linked_list - head_3->head_2->head + head_3 -> head_2 -> head """ self.insert_nth(0, data) @@ -177,13 +197,13 @@ class LinkedList: >>> linked_list.insert_tail("second") >>> linked_list.insert_tail("third") >>> linked_list - first->second->third + first -> second -> third >>> linked_list.insert_nth(1, "fourth") >>> linked_list - first->fourth->second->third + first -> fourth -> second -> third >>> linked_list.insert_nth(3, "fifth") >>> linked_list - first->fourth->second->fifth->third + first -> fourth -> second -> fifth -> third """ if not 0 <= index <= len(self): raise IndexError("list index out of range") @@ -191,14 +211,14 @@ class LinkedList: if self.head is None: self.head = new_node elif index == 0: - new_node.next = self.head # link new_node to head + new_node.next_node = self.head # link new_node to head self.head = new_node else: temp = self.head for _ in range(index - 1): - temp = temp.next - new_node.next = temp.next - temp.next = new_node + temp = temp.next_node + new_node.next_node = temp.next_node + temp.next_node = new_node def print_list(self) -> None: # print every node data """ @@ -208,7 +228,7 @@ class LinkedList: >>> linked_list.insert_tail("second") >>> linked_list.insert_tail("third") >>> linked_list - first->second->third + first -> second -> third """ print(self) @@ -221,11 +241,11 @@ class LinkedList: >>> linked_list.insert_tail("second") >>> linked_list.insert_tail("third") >>> linked_list - first->second->third + first -> second -> third >>> linked_list.delete_head() 'first' >>> linked_list - second->third + second -> third >>> linked_list.delete_head() 'second' >>> linked_list @@ -248,11 +268,11 @@ class LinkedList: >>> linked_list.insert_tail("second") >>> linked_list.insert_tail("third") >>> linked_list - first->second->third + first -> second -> third >>> linked_list.delete_tail() 'third' >>> linked_list - first->second + first -> second >>> linked_list.delete_tail() 'second' >>> linked_list @@ -275,11 +295,11 @@ class LinkedList: >>> linked_list.insert_tail("second") >>> linked_list.insert_tail("third") >>> linked_list - first->second->third + first -> second -> third >>> linked_list.delete_nth(1) # delete middle 'second' >>> linked_list - first->third + first -> third >>> linked_list.delete_nth(5) # this raises error Traceback (most recent call last): ... @@ -293,13 +313,13 @@ class LinkedList: raise IndexError("List index out of range.") delete_node = self.head # default first node if index == 0: - self.head = self.head.next + self.head = self.head.next_node else: temp = self.head for _ in range(index - 1): - temp = temp.next - delete_node = temp.next - temp.next = temp.next.next + temp = temp.next_node + delete_node = temp.next_node + temp.next_node = temp.next_node.next_node return delete_node.data def is_empty(self) -> bool: @@ -322,22 +342,22 @@ class LinkedList: >>> linked_list.insert_tail("second") >>> linked_list.insert_tail("third") >>> linked_list - first->second->third + first -> second -> third >>> linked_list.reverse() >>> linked_list - third->second->first + third -> second -> first """ prev = None current = self.head while current: # Store the current node's next node. - next_node = current.next - # Make the current node's next point backwards - current.next = prev + next_node = current.next_node + # Make the current node's next_node point backwards + current.next_node = prev # Make the previous node be the current node prev = current - # Make the current node the next node (to progress iteration) + # Make the current node the next_node node (to progress iteration) current = next_node # Return prev in order to put the head at the end self.head = prev @@ -366,17 +386,17 @@ def test_singly_linked_list() -> None: for i in range(10): assert len(linked_list) == i linked_list.insert_nth(i, i + 1) - assert str(linked_list) == "->".join(str(i) for i in range(1, 11)) + assert str(linked_list) == " -> ".join(str(i) for i in range(1, 11)) linked_list.insert_head(0) linked_list.insert_tail(11) - assert str(linked_list) == "->".join(str(i) for i in range(12)) + assert str(linked_list) == " -> ".join(str(i) for i in range(12)) assert linked_list.delete_head() == 0 assert linked_list.delete_nth(9) == 10 assert linked_list.delete_tail() == 11 assert len(linked_list) == 9 - assert str(linked_list) == "->".join(str(i) for i in range(1, 10)) + assert str(linked_list) == " -> ".join(str(i) for i in range(1, 10)) assert all(linked_list[i] == i + 1 for i in range(9)) is True @@ -385,7 +405,7 @@ def test_singly_linked_list() -> None: assert all(linked_list[i] == -i for i in range(9)) is True linked_list.reverse() - assert str(linked_list) == "->".join(str(i) for i in range(-8, 1)) + assert str(linked_list) == " -> ".join(str(i) for i in range(-8, 1)) def test_singly_linked_list_2() -> None: @@ -417,56 +437,57 @@ def test_singly_linked_list_2() -> None: # Check if it's empty or not assert linked_list.is_empty() is False assert ( - str(linked_list) == "-9->100->Node(77345112)->dlrow olleH->7->5555->0->" - "-192.55555->Hello, world!->77.9->Node(10)->None->None->12.2" + str(linked_list) + == "-9 -> 100 -> Node(77345112) -> dlrow olleH -> 7 -> 5555 -> " + "0 -> -192.55555 -> Hello, world! -> 77.9 -> Node(10) -> None -> None -> 12.2" ) # Delete the head result = linked_list.delete_head() assert result == -9 assert ( - str(linked_list) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->" - "Hello, world!->77.9->Node(10)->None->None->12.2" + str(linked_list) == "100 -> Node(77345112) -> dlrow olleH -> 7 -> 5555 -> 0 -> " + "-192.55555 -> Hello, world! -> 77.9 -> Node(10) -> None -> None -> 12.2" ) # Delete the tail result = linked_list.delete_tail() assert result == 12.2 assert ( - str(linked_list) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->" - "Hello, world!->77.9->Node(10)->None->None" + str(linked_list) == "100 -> Node(77345112) -> dlrow olleH -> 7 -> 5555 -> 0 -> " + "-192.55555 -> Hello, world! -> 77.9 -> Node(10) -> None -> None" ) # Delete a node in specific location in linked list result = linked_list.delete_nth(10) assert result is None assert ( - str(linked_list) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->" - "Hello, world!->77.9->Node(10)->None" + str(linked_list) == "100 -> Node(77345112) -> dlrow olleH -> 7 -> 5555 -> 0 -> " + "-192.55555 -> Hello, world! -> 77.9 -> Node(10) -> None" ) # Add a Node instance to its head linked_list.insert_head(Node("Hello again, world!")) assert ( str(linked_list) - == "Node(Hello again, world!)->100->Node(77345112)->dlrow olleH->" - "7->5555->0->-192.55555->Hello, world!->77.9->Node(10)->None" + == "Node(Hello again, world!) -> 100 -> Node(77345112) -> dlrow olleH -> " + "7 -> 5555 -> 0 -> -192.55555 -> Hello, world! -> 77.9 -> Node(10) -> None" ) # Add None to its tail linked_list.insert_tail(None) assert ( str(linked_list) - == "Node(Hello again, world!)->100->Node(77345112)->dlrow olleH->" - "7->5555->0->-192.55555->Hello, world!->77.9->Node(10)->None->None" + == "Node(Hello again, world!) -> 100 -> Node(77345112) -> dlrow olleH -> 7 -> " + "5555 -> 0 -> -192.55555 -> Hello, world! -> 77.9 -> Node(10) -> None -> None" ) # Reverse the linked list linked_list.reverse() assert ( str(linked_list) - == "None->None->Node(10)->77.9->Hello, world!->-192.55555->0->5555->" - "7->dlrow olleH->Node(77345112)->100->Node(Hello again, world!)" + == "None -> None -> Node(10) -> 77.9 -> Hello, world! -> -192.55555 -> 0 -> " + "5555 -> 7 -> dlrow olleH -> Node(77345112) -> 100 -> Node(Hello again, world!)" )