AI-powered Code Debugger Python

👤 Sharing: AI
```python
import traceback
import sys
import io
import contextlib

class AIDebugger:
    """
    AI-powered Code Debugger for Python.  This provides tools for
    identifying and correcting errors within Python code.  It leverages
    techniques like traceback analysis, static analysis (basic),
    and potential integration with LLMs (not implemented here) for
    more advanced debugging.
    """

    def __init__(self, code):
        """
        Initializes the debugger with the code to be debugged.

        Args:
            code: The Python code as a string.
        """
        self.code = code
        self.error = None
        self.traceback_info = None
        self.output = None  # Store stdout and stderr

    def run(self):
        """
        Executes the code and captures any errors or output.
        """
        try:
            # Capture stdout and stderr
            with io.StringIO() as captured_output, contextlib.redirect_stdout(captured_output), contextlib.redirect_stderr(captured_output):
                exec(self.code)
                self.output = captured_output.getvalue()
            return True  # Indicate successful execution

        except Exception as e:
            self.error = e
            self.traceback_info = traceback.format_exc()
            self.output = None
            return False # Indicate execution failure

    def analyze_traceback(self):
        """
        Analyzes the traceback information to identify the likely cause of the error.

        Returns:
            A string describing the error and its location, or None if no error occurred.
        """
        if not self.traceback_info:
            return None

        lines = self.traceback_info.splitlines()
        # Extract the relevant error message and file/line information
        error_line = lines[-1]  # Last line is typically the error message
        try:
            file_line = lines[-2] #One line before is usually the file/line info
            filename, line_number, _, offending_code = file_line.split(",")
            line_number = line_number.split("line ")[1]
            filename = filename.split('  File "')[1]
        except IndexError:
            filename = "Unknown"
            line_number = "Unknown"
            offending_code = "Unknown"


        return f"Error: {error_line} in file: {filename}, line: {line_number}. Offending code: {offending_code if "offending_code" in locals() else 'N/A'}" # Handle missing variables

    def suggest_fixes(self):
        """
        Provides suggestions for fixing the identified error.

        Currently, this is a placeholder for more advanced AI-powered suggestions.
        It provides very basic hints based on common error types.

        Returns:
            A list of strings, each representing a potential fix suggestion.
        """
        if not self.error:
            return ["No errors found!"]

        error_type = type(self.error).__name__
        suggestions = []

        if error_type == "NameError":
            suggestions.append("Check for typos in variable names.")
            suggestions.append("Ensure the variable is defined before being used.")
        elif error_type == "TypeError":
            suggestions.append("Check the data types being used in the operation.")
            suggestions.append("Make sure you're passing the correct number of arguments to the function.")
        elif error_type == "IndexError":
            suggestions.append("Check if the index is within the bounds of the list or tuple.")
        elif error_type == "KeyError":
            suggestions.append("Check if the key exists in the dictionary.")
        elif error_type == "SyntaxError":
            suggestions.append("Carefully review the syntax of your code.  Look for missing colons, parentheses, etc.")
        elif error_type == "ZeroDivisionError":
            suggestions.append("Check if you are dividing by zero. Add a conditional to prevent division by zero.")
        else:
            suggestions.append("Refer to the error message and traceback for more information.")
            suggestions.append("Search the internet for solutions related to the specific error type.")

        return suggestions


    def debug(self):
        """
        Runs the debugging process, analyzes the error, and provides suggestions.

        Returns:
            A dictionary containing debugging information:
            {
                "success": True/False,
                "error": The error message if any,
                "traceback": The traceback information if any,
                "analysis": A description of the error (from analyze_traceback),
                "suggestions": A list of potential fixes.
                "output": The output of the program (stdout and stderr).
            }
        """
        success = self.run()
        analysis = self.analyze_traceback()
        suggestions = self.suggest_fixes()


        return {
            "success": success,
            "error": str(self.error) if self.error else None,
            "traceback": self.traceback_info,
            "analysis": analysis,
            "suggestions": suggestions,
            "output": self.output
        }

if __name__ == '__main__':
    # Example usage
    faulty_code = """
def my_function(x, y):
    result = x + z # z is not defined
    return result

print(my_function(5, 10))
"""

    debugger = AIDebugger(faulty_code)
    debug_info = debugger.debug()

    print("Debugging Results:")
    print(f"Success: {debug_info['success']}")
    if not debug_info['success']:
        print(f"Error: {debug_info['error']}")
        print(f"Traceback:\n{debug_info['traceback']}")
        print(f"Analysis: {debug_info['analysis']}")
        print("Suggestions:")
        for suggestion in debug_info['suggestions']:
            print(f"- {suggestion}")
    else:
        print(f"Output: {debug_info['output']}")

    # Example 2: Demonstrating a different error
    faulty_code_2 = """
my_list = [1, 2, 3]
print(my_list[5])  # Index out of bounds
"""
    debugger2 = AIDebugger(faulty_code_2)
    debug_info_2 = debugger2.debug()

    print("\nDebugging Results (Example 2):")
    print(f"Success: {debug_info_2['success']}")
    if not debug_info_2['success']:
        print(f"Error: {debug_info_2['error']}")
        print(f"Traceback:\n{debug_info_2['traceback']}")
        print(f"Analysis: {debug_info_2['analysis']}")
        print("Suggestions:")
        for suggestion in debug_info_2['suggestions']:
            print(f"- {suggestion}")
    else:
        print(f"Output: {debug_info_2['output']}")


    # Example 3: Demonstrating a SyntaxError
    faulty_code_3 = """
def my_function(x, y) # Missing colon
    return x + y

print(my_function(5, 10))
"""
    debugger3 = AIDebugger(faulty_code_3)
    debug_info_3 = debugger3.debug()

    print("\nDebugging Results (Example 3):")
    print(f"Success: {debug_info_3['success']}")
    if not debug_info_3['success']:
        print(f"Error: {debug_info_3['error']}")
        print(f"Traceback:\n{debug_info_3['traceback']}")
        print(f"Analysis: {debug_info_3['analysis']}")
        print("Suggestions:")
        for suggestion in debug_info_3['suggestions']:
            print(f"- {suggestion}")
    else:
        print(f"Output: {debug_info_3['output']}")

    # Example 4: Code that runs successfully
    correct_code = """
def my_function(x, y):
    return x + y

print(my_function(5, 10))
"""
    debugger4 = AIDebugger(correct_code)
    debug_info_4 = debugger4.debug()

    print("\nDebugging Results (Example 4 - Correct Code):")
    print(f"Success: {debug_info_4['success']}")
    if not debug_info_4['success']:
        print(f"Error: {debug_info_4['error']}")
        print(f"Traceback:\n{debug_info_4['traceback']}")
        print(f"Analysis: {debug_info_4['analysis']}")
        print("Suggestions:")
        for suggestion in debug_info_4['suggestions']:
            print(f"- {suggestion}")
    else:
        print(f"Output: {debug_info_4['output']}")
```
👁️ Viewed: 9

Comments