Skip to content

Conversation

@visz11
Copy link

@visz11 visz11 commented Jul 31, 2025

Summary by CodeRabbit

  • New Features
    • Introduced a singly linked list with options to insert, update, and remove nodes at various positions.
    • Added the ability to print the entire list and retrieve its size.
    • Enhanced error handling for invalid operations, such as out-of-bounds indices or actions on empty lists.
    • Provided example usage demonstrating the linked list operations.

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link

coderabbitai bot commented Jul 31, 2025

Walkthrough

A new file, linked_list.py, introduces a singly linked list data structure. It defines a Node class and a LinkedList class with methods for inserting, updating, removing, and printing nodes, as well as retrieving the list size. The implementation includes example usage and handles various edge cases.

Changes

Cohort / File(s) Change Summary
Singly Linked List Implementation
linked_list.py
Added Node and LinkedList classes with methods for insertion, removal, update, size, and print. Includes example usage and boundary checks.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant LinkedList
    participant Node

    User->>LinkedList: insertAtBegin(data)
    LinkedList->>Node: create Node(data)
    LinkedList-->>User: (insertion complete)

    User->>LinkedList: insertAtIndex(data, index)
    LinkedList->>Node: create Node(data)
    LinkedList-->>User: (insertion complete or error)

    User->>LinkedList: insertAtEnd(data)
    LinkedList->>Node: create Node(data)
    LinkedList-->>User: (insertion complete)

    User->>LinkedList: updateNode(val, index)
    LinkedList-->>User: (update or error)

    User->>LinkedList: remove_first_node()
    LinkedList-->>User: (removal or error)

    User->>LinkedList: remove_last_node()
    LinkedList-->>User: (removal or error)

    User->>LinkedList: remove_at_index(index)
    LinkedList-->>User: (removal or error)

    User->>LinkedList: remove_node(data)
    LinkedList-->>User: (removal or error)

    User->>LinkedList: sizeOfLL()
    LinkedList-->>User: size

    User->>LinkedList: printLL()
    LinkedList-->>User: (prints list)
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

In a garden of code where data hops free,
A linked list now blooms, as neat as can be.
Nodes join in a line, each holding a tale,
Insert, update, or remove—none will fail!
Rabbits rejoice, for the list is complete—
Hopping through memory, nimble and fleet.
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch creating-linked-list

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @visz11, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a complete implementation of a singly linked list data structure in Python. It provides core functionalities for managing nodes, including various insertion, deletion, and update operations, along with methods to print the list and get its size.

Highlights

  • Node Class: A Node class is defined to represent individual elements within the linked list, holding data and a reference to the next node.
  • LinkedList Class: A LinkedList class is implemented to manage the collection of nodes, starting with a head pointer.
  • Insertion Operations: Methods insertAtBegin, insertAtIndex, and insertAtEnd are provided to add new nodes at the beginning, a specific index, or the end of the list, respectively.
  • Update Operation: The updateNode method allows modifying the data of a node at a given index.
  • Deletion Operations: Comprehensive methods for removing nodes are included: remove_first_node, remove_last_node, remove_at_index, and remove_node (by data value).
  • Utility Methods: sizeOfLL returns the number of nodes in the list, and printLL iterates through and prints the data of each node.
  • Example Usage: The file includes an example script demonstrating the usage of all implemented linked list operations.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@visz11
Copy link
Author

visz11 commented Jul 31, 2025

/refacto-test

@refacto-test
Copy link

refacto-test bot commented Jul 31, 2025

🤖 Refacto.AI: PR Summary & Reviewer Guide

🎯 1. The Goal (Why was this PR raised?)

This PR adds a new linked list data structure implementation to the codebase. The implementation includes a complete LinkedList class with various methods for manipulating linked lists.

🗺️ 2. The Changes (What was implemented?)

File Name Implementation Details Goal / Requirement Addressed
linked_list.py (Added) Created a complete linked list implementation with:
- Node class for individual list elements
- LinkedList class with methods for insertion, deletion, updating, and traversal
- Example usage code demonstrating the implementation
Add linked list data structure

🤔 3. Key Areas for Human Review

Area of Concern: Edge Case Handling in Removal Methods

  • File: linked_list.py (Lines 63-110)
  • Why: The removal methods contain multiple edge cases (empty list, removing first/last node, removing by index/value) that need careful review to ensure correctness.
  • Testing Instruction: Test removal operations on empty lists, single-element lists, and lists with multiple elements. Verify that edge cases like removing the first node, last node, and nodes at invalid indices are handled properly.

Area of Concern: Index Validation

  • File: linked_list.py (Lines 19-36, 51-61, 87-104)
  • Why: Several methods that accept an index parameter (insertAtIndex, updateNode, remove_at_index) have different approaches to index validation and error handling.
  • Testing Instruction: Test these methods with invalid indices (negative indices, indices beyond list length) and verify that they handle these cases consistently and provide appropriate error messages.

Area of Concern: Method Consistency

  • File: linked_list.py (All methods)
  • Why: The implementation uses inconsistent naming conventions (e.g., insertAtBegin vs remove_first_node) and different error handling approaches (some print errors, others return silently).
  • Testing Instruction: Review the API design for consistency in naming, error handling, and return values. Consider if a more consistent approach would improve usability.

@refacto-test
Copy link

refacto-test bot commented Jul 31, 2025

Refacto is reviewing this PR. Please wait for the review comments to be posted.

@refacto-test
Copy link

refacto-test bot commented Jul 31, 2025

⚠️ Subscription Expired

Your subscription expired on 30/7/2025.

To continue using Refacto code reviews, please renew or upgrade your subscription.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
linked_list.py (2)

137-141: Consider improving print formatting for better readability.

The current implementation prints each element on a separate line. Consider formatting the output to show the linked list structure more clearly.

 def printLL(self):
     current_node = self.head
+    elements = []
     while current_node:
-        print(current_node.data)
+        elements.append(str(current_node.data))
         current_node = current_node.next
+    print(" -> ".join(elements) + " -> None")

1-179: Well-implemented linked list with comprehensive functionality.

This is a solid implementation of a singly linked list data structure. The code demonstrates:

  • Proper handling of all basic operations (insert, remove, update)
  • Good edge case management (empty lists, invalid indices)
  • Clear method organization and naming conventions
  • Comprehensive example usage

Consider adding docstrings to methods for better documentation and API clarity.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 78a3159 and 56aba20.

📒 Files selected for processing (1)
  • linked_list.py (1 hunks)
🔇 Additional comments (11)
linked_list.py (11)

2-5: LGTM! Clean Node class implementation.

The Node class is correctly implemented with proper initialization of data and next pointer.


8-10: LGTM! Proper LinkedList initialization.

The LinkedList constructor correctly initializes an empty list with head set to None.


13-16: LGTM! Correct insertion at beginning.

The method properly creates a new node and updates the head pointer to maintain the linked list structure.


20-36: LGTM! Well-handled insertion at index with proper edge case management.

The method correctly:

  • Handles index 0 by delegating to insertAtBegin
  • Traverses to find the correct position
  • Handles invalid indices with appropriate error messaging

39-49: LGTM! Proper insertion at end with empty list handling.

The method correctly handles both empty list initialization and traversal to the end for insertion.


52-62: LGTM! Correct node update implementation.

The method properly traverses to the target index and updates the node's data with appropriate error handling for invalid indices.


65-69: LGTM! Proper first node removal.

The method correctly handles empty list case and updates the head pointer appropriately.


72-86: LGTM! Comprehensive last node removal handling.

The method properly handles all cases:

  • Empty list
  • Single node list
  • Multiple nodes with correct traversal to second-to-last node

89-106: LGTM! Well-implemented removal at index.

The method correctly:

  • Handles empty list and index 0 cases
  • Traverses to find the node before the target index
  • Properly updates pointers to remove the target node
  • Provides error messaging for invalid indices

109-125: LGTM! Thorough node removal by data value.

The method correctly handles:

  • Head node removal case
  • Traversal to find matching data
  • Proper pointer updates to remove the node
  • Error messaging when data is not found

128-134: LGTM! Correct size calculation.

The method properly traverses the entire list and returns the accurate count of nodes.

Comment on lines +144 to +179
# create a new linked list
llist = LinkedList()

# add nodes to the linked list
llist.insertAtEnd('a')
llist.insertAtEnd('b')
llist.insertAtBegin('c')
llist.insertAtEnd('d')
llist.insertAtIndex('g', 2)

# print the linked list
print("Node Data:")
llist.printLL()

# remove nodes from the linked list
print("\nRemove First Node:")
llist.remove_first_node()
llist.printLL()

print("\nRemove Last Node:")
llist.remove_last_node()
llist.printLL()

print("\nRemove Node at Index 1:")
llist.remove_at_index(1)
llist.printLL()

# print the linked list after all removals
print("\nLinked list after removing a node:")
llist.printLL()

print("\nUpdate node Value at Index 0:")
llist.updateNode('z', 0)
llist.printLL()

print("\nSize of linked list:", llist.sizeOfLL())
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Move example usage behind main guard for better modularity.

The example code demonstrates the functionality well, but executing at module level prevents clean imports. Consider wrapping in a main guard.

-# create a new linked list
-llist = LinkedList()
-
-# add nodes to the linked list
-llist.insertAtEnd('a')
-llist.insertAtEnd('b')
-llist.insertAtBegin('c')
-llist.insertAtEnd('d')
-llist.insertAtIndex('g', 2)
-
-# print the linked list
-print("Node Data:")
-llist.printLL()
-
-# remove nodes from the linked list
-print("\nRemove First Node:")
-llist.remove_first_node()
-llist.printLL()
-
-print("\nRemove Last Node:")
-llist.remove_last_node()
-llist.printLL()
-
-print("\nRemove Node at Index 1:")
-llist.remove_at_index(1)
-llist.printLL()
-
-# print the linked list after all removals
-print("\nLinked list after removing a node:")
-llist.printLL()
-
-print("\nUpdate node Value at Index 0:")
-llist.updateNode('z', 0)
-llist.printLL()
-
-print("\nSize of linked list:", llist.sizeOfLL())
+if __name__ == "__main__":
+    # create a new linked list
+    llist = LinkedList()
+    
+    # add nodes to the linked list
+    llist.insertAtEnd('a')
+    llist.insertAtEnd('b')
+    llist.insertAtBegin('c')
+    llist.insertAtEnd('d')
+    llist.insertAtIndex('g', 2)
+    
+    # print the linked list
+    print("Node Data:")
+    llist.printLL()
+    
+    # remove nodes from the linked list
+    print("\nRemove First Node:")
+    llist.remove_first_node()
+    llist.printLL()
+    
+    print("\nRemove Last Node:")
+    llist.remove_last_node()
+    llist.printLL()
+    
+    print("\nRemove Node at Index 1:")
+    llist.remove_at_index(1)
+    llist.printLL()
+    
+    # print the linked list after all removals
+    print("\nLinked list after removing a node:")
+    llist.printLL()
+    
+    print("\nUpdate node Value at Index 0:")
+    llist.updateNode('z', 0)
+    llist.printLL()
+    
+    print("\nSize of linked list:", llist.sizeOfLL())
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# create a new linked list
llist = LinkedList()
# add nodes to the linked list
llist.insertAtEnd('a')
llist.insertAtEnd('b')
llist.insertAtBegin('c')
llist.insertAtEnd('d')
llist.insertAtIndex('g', 2)
# print the linked list
print("Node Data:")
llist.printLL()
# remove nodes from the linked list
print("\nRemove First Node:")
llist.remove_first_node()
llist.printLL()
print("\nRemove Last Node:")
llist.remove_last_node()
llist.printLL()
print("\nRemove Node at Index 1:")
llist.remove_at_index(1)
llist.printLL()
# print the linked list after all removals
print("\nLinked list after removing a node:")
llist.printLL()
print("\nUpdate node Value at Index 0:")
llist.updateNode('z', 0)
llist.printLL()
print("\nSize of linked list:", llist.sizeOfLL())
if __name__ == "__main__":
# create a new linked list
llist = LinkedList()
# add nodes to the linked list
llist.insertAtEnd('a')
llist.insertAtEnd('b')
llist.insertAtBegin('c')
llist.insertAtEnd('d')
llist.insertAtIndex('g', 2)
# print the linked list
print("Node Data:")
llist.printLL()
# remove nodes from the linked list
print("\nRemove First Node:")
llist.remove_first_node()
llist.printLL()
print("\nRemove Last Node:")
llist.remove_last_node()
llist.printLL()
print("\nRemove Node at Index 1:")
llist.remove_at_index(1)
llist.printLL()
# print the linked list after all removals
print("\nLinked list after removing a node:")
llist.printLL()
print("\nUpdate node Value at Index 0:")
llist.updateNode('z', 0)
llist.printLL()
print("\nSize of linked list:", llist.sizeOfLL())
🤖 Prompt for AI Agents
In linked_list.py around lines 144 to 179, the example usage code runs at the
module level, which can cause unwanted execution when importing this file. To
fix this, wrap all the example usage code inside a main guard by placing it
under if __name__ == "__main__":. This ensures the code only runs when the
script is executed directly, improving modularity and import safety.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new Python file with a LinkedList implementation. The implementation is a good start, but it has several areas for improvement. My review focuses on making the code more robust, maintainable, and idiomatic to Python. Key suggestions include using proper exception handling instead of printing to the console, adhering to PEP 8 naming conventions, using dunder methods like __len__ and __str__, adding docstrings, and protecting the script's entry point. These changes will make the LinkedList class more reusable and easier to work with.

Comment on lines +144 to +179
# create a new linked list
llist = LinkedList()

# add nodes to the linked list
llist.insertAtEnd('a')
llist.insertAtEnd('b')
llist.insertAtBegin('c')
llist.insertAtEnd('d')
llist.insertAtIndex('g', 2)

# print the linked list
print("Node Data:")
llist.printLL()

# remove nodes from the linked list
print("\nRemove First Node:")
llist.remove_first_node()
llist.printLL()

print("\nRemove Last Node:")
llist.remove_last_node()
llist.printLL()

print("\nRemove Node at Index 1:")
llist.remove_at_index(1)
llist.printLL()

# print the linked list after all removals
print("\nLinked list after removing a node:")
llist.printLL()

print("\nUpdate node Value at Index 0:")
llist.updateNode('z', 0)
llist.printLL()

print("\nSize of linked list:", llist.sizeOfLL())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The script includes test and demonstration code at the module level. This code will execute whenever the file is imported as a module into another script, which is usually undesirable. To make this file reusable as a module, you should place this code inside an if __name__ == "__main__": block.

if __name__ == "__main__":
    # create a new linked list
    llist = LinkedList()

    # add nodes to the linked list
    llist.insertAtEnd('a')
    llist.insertAtEnd('b')
    llist.insertAtBegin('c')
    llist.insertAtEnd('d')
    llist.insertAtIndex('g', 2)

    # print the linked list
    print("Node Data:")
    llist.printLL()

    # remove nodes from the linked list
    print("\nRemove First Node:")
    llist.remove_first_node()
    llist.printLL()

    print("\nRemove Last Node:")
    llist.remove_last_node()
    llist.printLL()

    print("\nRemove Node at Index 1:")
    llist.remove_at_index(1)
    llist.printLL()

    # print the linked list after all removals
    print("\nLinked list after removing a node:")
    llist.printLL()

    print("\nUpdate node Value at Index 0:")
    llist.updateNode('z', 0)
    llist.printLL()

    print("\nSize of linked list:", llist.sizeOfLL())

Comment on lines +20 to +36
def insertAtIndex(self, data, index):
if index == 0:
self.insertAtBegin(data)
return

position = 0
current_node = self.head
while current_node is not None and position + 1 != index:
position += 1
current_node = current_node.next

if current_node is not None:
new_node = Node(data)
new_node.next = current_node.next
current_node.next = new_node
else:
print("Index not present")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This method should raise an IndexError for invalid indices (out of bounds or negative) instead of printing to the console. This is more idiomatic for Python data structures and allows callers to handle errors gracefully.

Suggested change
def insertAtIndex(self, data, index):
if index == 0:
self.insertAtBegin(data)
return
position = 0
current_node = self.head
while current_node is not None and position + 1 != index:
position += 1
current_node = current_node.next
if current_node is not None:
new_node = Node(data)
new_node.next = current_node.next
current_node.next = new_node
else:
print("Index not present")
def insertAtIndex(self, data, index):
if index < 0:
raise IndexError("Index cannot be negative")
if index == 0:
self.insertAtBegin(data)
return
position = 0
current_node = self.head
while current_node is not None and position + 1 != index:
position += 1
current_node = current_node.next
if current_node is not None:
new_node = Node(data)
new_node.next = current_node.next
current_node.next = new_node
else:
raise IndexError("Index out of bounds")

Comment on lines +52 to +62
def updateNode(self, val, index):
current_node = self.head
position = 0
while current_node is not None and position != index:
position += 1
current_node = current_node.next

if current_node is not None:
current_node.data = val
else:
print("Index not present")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This method should raise an IndexError for invalid indices (out of bounds or negative) instead of printing to the console. This allows callers to handle errors programmatically.

Suggested change
def updateNode(self, val, index):
current_node = self.head
position = 0
while current_node is not None and position != index:
position += 1
current_node = current_node.next
if current_node is not None:
current_node.data = val
else:
print("Index not present")
def updateNode(self, val, index):
if index < 0:
raise IndexError("Index cannot be negative")
current_node = self.head
position = 0
while current_node is not None and position != index:
position += 1
current_node = current_node.next
if current_node is not None:
current_node.data = val
else:
raise IndexError("Index out of bounds")

Comment on lines +89 to +106
def remove_at_index(self, index):
if self.head is None:
return

if index == 0:
self.remove_first_node()
return

current_node = self.head
position = 0
while current_node is not None and current_node.next is not None and position + 1 != index:
position += 1
current_node = current_node.next

if current_node is not None and current_node.next is not None:
current_node.next = current_node.next.next
else:
print("Index not present")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This method should raise an IndexError for invalid indices (out of bounds or negative) instead of printing to the console or silently returning. This makes the behavior explicit and allows callers to handle errors.

    def remove_at_index(self, index):
        if index < 0:
            raise IndexError("Index cannot be negative")

        if self.head is None:
            raise IndexError("Remove from an empty list")

        if index == 0:
            self.remove_first_node()
            return

        current_node = self.head
        position = 0
        # Find predecessor of the node to be deleted
        while current_node.next is not None and position + 1 != index:
            position += 1
            current_node = current_node.next

        if current_node.next is not None:
            current_node.next = current_node.next.next
        else:
            raise IndexError("Index out of bounds")


# Traverse to the second last node
current_node = self.head
while current_node.next and current_node.next.next:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The while loop condition can be simplified. The check for current_node.next is redundant. If current_node.next.next can be accessed without an error, it implies that current_node.next is not None.

Suggested change
while current_node.next and current_node.next.next:
while current_node.next.next:

Comment on lines +109 to +125
def remove_node(self, data):
current_node = self.head

# If the node to be removed is the head node
if current_node is not None and current_node.data == data:
self.remove_first_node()
return

# Traverse and find the node with the matching data
while current_node is not None and current_node.next is not None:
if current_node.next.data == data:
current_node.next = current_node.next.next
return
current_node = current_node.next

# If the data was not found
print("Node with the given data not found")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This method removes the first node that matches the given data. The name and comment could be more specific about this behavior. Also, instead of printing a message when the data is not found, it would be more idiomatic to return a boolean indicating whether the removal was successful. This makes the method more versatile.

Suggested change
def remove_node(self, data):
current_node = self.head
# If the node to be removed is the head node
if current_node is not None and current_node.data == data:
self.remove_first_node()
return
# Traverse and find the node with the matching data
while current_node is not None and current_node.next is not None:
if current_node.next.data == data:
current_node.next = current_node.next.next
return
current_node = current_node.next
# If the data was not found
print("Node with the given data not found")
# Method to remove the first node from the linked list by its data
def remove_node(self, data):
current_node = self.head
# If the node to be removed is the head node
if current_node is not None and current_node.data == data:
self.remove_first_node()
return True
# Traverse and find the node with the matching data
while current_node is not None and current_node.next is not None:
if current_node.next.data == data:
current_node.next = current_node.next.next
return True
current_node = current_node.next
# If the data was not found
return False

Comment on lines +128 to +134
def sizeOfLL(self):
size = 0
current_node = self.head
while current_node:
size += 1
current_node = current_node.next
return size

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Instead of a custom method sizeOfLL, it's more Pythonic to implement the __len__ dunder method. This allows you to get the size of the list using the built-in len() function (e.g., len(llist)), which is more idiomatic and expected for collection-like objects in Python.

Suggested change
def sizeOfLL(self):
size = 0
current_node = self.head
while current_node:
size += 1
current_node = current_node.next
return size
def __len__(self):
size = 0
current_node = self.head
while current_node:
size += 1
current_node = current_node.next
return size

Comment on lines +137 to +141
def printLL(self):
current_node = self.head
while current_node:
print(current_node.data)
current_node = current_node.next

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The printLL method directly prints to the console. A more flexible and Pythonic approach is to implement the __str__ dunder method. This method should return a string representation of the list, which can then be printed or used in other ways (e.g., print(llist)).

Suggested change
def printLL(self):
current_node = self.head
while current_node:
print(current_node.data)
current_node = current_node.next
def __str__(self):
nodes = []
current_node = self.head
while current_node:
nodes.append(str(current_node.data))
current_node = current_node.next
return " -> ".join(nodes)

@visz11
Copy link
Author

visz11 commented Jul 31, 2025

/refacto-test

@refacto-test
Copy link

refacto-test bot commented Jul 31, 2025

Refacto is reviewing this PR. Please wait for the review comments to be posted.

@visz11 visz11 closed this Jul 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant