From ebf2c54ce13aa9d09a452c8476408cfc4ade70a0 Mon Sep 17 00:00:00 2001 From: Sherman Hui Date: Sun, 4 Oct 2020 16:58:38 -0700 Subject: [PATCH 1/4] chore: update print_reverse helper method Use a generator expression instead of slicing `elements_list` to improve the space and time complexity of `make_linked_list` to O(1) space and O(n) time by avoiding the creation a shallow copy of `elements_list`. --- data_structures/linked_list/print_reverse.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/data_structures/linked_list/print_reverse.py b/data_structures/linked_list/print_reverse.py index c3a72b6b7a23..4a148c097ab5 100644 --- a/data_structures/linked_list/print_reverse.py +++ b/data_structures/linked_list/print_reverse.py @@ -28,8 +28,10 @@ def make_linked_list(elements_list): # Set first element as Head head = Node(elements_list[0]) current = head - # Loop through elements from position 1 - for data in elements_list[1:]: + list_length = len(elements_list) + + # Iterate over values from generator expression starting from position 1 + for data in (elements_list[i] for i in range(1, list_length)): current.next = Node(data) current = current.next return head From b23348ae9c7e6c2f6f74c53a030faaece1f70cbd Mon Sep 17 00:00:00 2001 From: Sherman Hui Date: Sun, 4 Oct 2020 20:05:35 -0700 Subject: [PATCH 2/4] fix: add type checking and argument typing Add argument typing to all methods in `print_reverse` Add doctest to helper function `make_linked_list` and basic edge case tests to `print_reverse` --- data_structures/linked_list/print_reverse.py | 29 ++++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/data_structures/linked_list/print_reverse.py b/data_structures/linked_list/print_reverse.py index 4a148c097ab5..28d701e46f77 100644 --- a/data_structures/linked_list/print_reverse.py +++ b/data_structures/linked_list/print_reverse.py @@ -1,5 +1,6 @@ # Program to print the elements of a linked list in reverse +from typing import List class Node: def __init__(self, data=None): @@ -17,9 +18,25 @@ def __repr__(self): return string_rep -def make_linked_list(elements_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() + Traceback (most recent call last): + ... + Exception: The Elements List is empty + >>> make_linked_list([]) + Traceback (most recent call last): + ... + Exception: The Elements List is empty + >>> make_linked_list([7]) + '<7> ---> ' + >>> make_linked_list(['abc']) + ' ---> ' + >>> make_linked_list([7, 25]) + '<7> ---> <25> ---> ' + """ # if elements_list is empty if not elements_list: @@ -37,11 +54,17 @@ def make_linked_list(elements_list): return head -def print_reverse(head_node): +def print_reverse(head_node: Node): """Prints the elements of the given Linked List in reverse order""" + """ + >>> print_reverse() + None + >>> print_reverse([]) + None + """ # If reached end of the List - if head_node is None: + if head_node is None or not isinstance(head_node, Node): return None else: # Recurse From 4b1e4f8399824f611fd15f54520079f6c0df300f Mon Sep 17 00:00:00 2001 From: Sherman Hui Date: Sun, 4 Oct 2020 21:31:29 -0700 Subject: [PATCH 3/4] test: add `print_reverse` test Fix doctest syntax and remove edge case tests that are covered by typed arguments. Add `print_reverse` test that expects the correct values are printed out by adding a `test_print_reverse_output` helper function. --- data_structures/linked_list/print_reverse.py | 52 ++++++++++++-------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/data_structures/linked_list/print_reverse.py b/data_structures/linked_list/print_reverse.py index 28d701e46f77..ffe790883d63 100644 --- a/data_structures/linked_list/print_reverse.py +++ b/data_structures/linked_list/print_reverse.py @@ -1,7 +1,7 @@ # Program to print the elements of a linked list in reverse - from typing import List + class Node: def __init__(self, data=None): self.data = data @@ -20,22 +20,18 @@ def __repr__(self): 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() - Traceback (most recent call last): - ... - Exception: The Elements List is empty + (list/tuple) and returns the head of the Linked List. + >>> make_linked_list([]) Traceback (most recent call last): ... Exception: The Elements List is empty >>> make_linked_list([7]) - '<7> ---> ' + <7> ---> >>> make_linked_list(['abc']) - ' ---> ' + ---> >>> make_linked_list([7, 25]) - '<7> ---> <25> ---> ' + <7> ---> <25> ---> """ # if elements_list is empty @@ -55,12 +51,8 @@ def make_linked_list(elements_list: List): def print_reverse(head_node: Node): - """Prints the elements of the given Linked List in reverse order""" - """ - >>> print_reverse() - None + """Prints the elements of the given Linked List in reverse order >>> print_reverse([]) - None """ # If reached end of the List @@ -72,9 +64,27 @@ def print_reverse(head_node: Node): print(head_node.data) -list_data = [14, 52, 14, 12, 43] -linked_list = make_linked_list(list_data) -print("Linked List:") -print(linked_list) -print("Elements in Reverse:") -print_reverse(linked_list) +def test_print_reverse_output(): + test_list_data = [69, 88, 73] + linked_list = make_linked_list(test_list_data) + + print_reverse(linked_list) + + +def main(): + """ + >>> test_print_reverse_output() + 73 + 88 + 69 + """ + list_data = [14, 52, 14, 12, 43] + linked_list = make_linked_list(list_data) + print("Linked List:") + print(linked_list) + print("Elements in Reverse:") + print_reverse(linked_list) + + +if __name__ == "__main__": + main() From 6b9748a9836d452a3fa200c056b097a7f66d1697 Mon Sep 17 00:00:00 2001 From: shellhub Date: Mon, 5 Oct 2020 18:53:32 +0800 Subject: [PATCH 4/4] format code --- data_structures/linked_list/print_reverse.py | 60 +++++++------------- 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/data_structures/linked_list/print_reverse.py b/data_structures/linked_list/print_reverse.py index ffe790883d63..c46f228e7260 100644 --- a/data_structures/linked_list/print_reverse.py +++ b/data_structures/linked_list/print_reverse.py @@ -1,4 +1,3 @@ -# Program to print the elements of a linked list in reverse from typing import List @@ -9,77 +8,58 @@ def __init__(self, data=None): def __repr__(self): """Returns a visual representation of the node and all its following nodes.""" - string_rep = "" + string_rep = [] temp = self while temp: - string_rep += f"<{temp.data}> ---> " + string_rep.append(f"{temp.data}") temp = temp.next - string_rep += "" - return string_rep + return "->".join(string_rep) 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([]) Traceback (most recent call last): ... Exception: The Elements List is empty >>> make_linked_list([7]) - <7> ---> + 7 >>> make_linked_list(['abc']) - ---> + abc >>> make_linked_list([7, 25]) - <7> ---> <25> ---> + 7->25 """ - - # if elements_list is empty if not elements_list: raise Exception("The Elements List is empty") - # Set first element as Head - head = Node(elements_list[0]) - current = head - list_length = len(elements_list) - - # Iterate over values from generator expression starting from position 1 - for data in (elements_list[i] for i in range(1, list_length)): - current.next = Node(data) + current = head = Node(elements_list[0]) + for i in range(1, len(elements_list)): + current.next = Node(elements_list[i]) current = current.next return head -def print_reverse(head_node: Node): +def print_reverse(head_node: Node) -> None: """Prints the elements of the given Linked List in reverse order >>> print_reverse([]) + >>> linked_list = make_linked_list([69, 88, 73]) + >>> print_reverse(linked_list) + 73 + 88 + 69 """ - - # If reached end of the List - if head_node is None or not isinstance(head_node, Node): - return None - else: - # Recurse + if head_node is not None and isinstance(head_node, Node): print_reverse(head_node.next) print(head_node.data) -def test_print_reverse_output(): - test_list_data = [69, 88, 73] - linked_list = make_linked_list(test_list_data) - - print_reverse(linked_list) +def main(): + from doctest import testmod + testmod() -def main(): - """ - >>> test_print_reverse_output() - 73 - 88 - 69 - """ - list_data = [14, 52, 14, 12, 43] - linked_list = make_linked_list(list_data) + linked_list = make_linked_list([14, 52, 14, 12, 43]) print("Linked List:") print(linked_list) print("Elements in Reverse:")