File size: 3,207 Bytes
38b27cd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | """
Code Explainer + Bug Checker (CLI version)
--------------------------------------------
Given a code snippet, this pipeline:
1. Explains what the code does (in plain English, via CodeT5)
2. Gives a line-by-line breakdown (via Python's ast module)
3. Checks for real bugs (via pyflakes static analysis)
4. Checks PEP8 style (via pycodestyle)
This uses the same underlying modules as streamlit_app.py, so both
interfaces give identical, consistent results.
Run:
pip install -r requirements.txt
python app.py
"""
from transformers import AutoTokenizer, T5ForConditionalGeneration
import torch
from line_explainer import explain_line_by_line
from bug_checker import detect_bugs, check_style
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
# ---------------------------------------------------------------------------
# CODE EXPLAINER (pretrained, no fine-tuning needed)
# ---------------------------------------------------------------------------
EXPLAIN_MODEL_NAME = "Salesforce/codet5-base-multi-sum"
print("Loading code explainer model...")
explain_tokenizer = AutoTokenizer.from_pretrained(EXPLAIN_MODEL_NAME, use_fast=False)
explain_model = T5ForConditionalGeneration.from_pretrained(EXPLAIN_MODEL_NAME).to(DEVICE)
def explain_code(code: str) -> str:
"""Returns a one-sentence, plain-English summary of what the code does."""
inputs = explain_tokenizer(code, return_tensors="pt", truncation=True, max_length=512).to(DEVICE)
output_ids = explain_model.generate(**inputs, max_length=64, num_beams=5, early_stopping=True)
return explain_tokenizer.decode(output_ids[0], skip_special_tokens=True)
# ---------------------------------------------------------------------------
# PIPELINE
# ---------------------------------------------------------------------------
def analyze_code(code: str):
print("\n--- EXPLANATION (summary) ---")
explanation = explain_code(code)
print(explanation)
print("\n--- EXPLANATION (line-by-line) ---")
ok, breakdown = explain_line_by_line(code)
if ok:
print("\n".join(breakdown))
else:
print(breakdown)
print("\n--- BUG CHECK (static analysis) ---")
bug_result = detect_bugs(code)
print(bug_result["summary"] if bug_result["syntax_valid"] else bug_result["syntax_error"])
if bug_result["has_bug"] and bug_result["static_issues"]:
for issue in bug_result["static_issues"]:
print(f" - {issue}")
print("\n--- STYLE CHECK (PEP8) ---")
if bug_result["syntax_valid"]:
style_issues = check_style(code)
if style_issues:
print(f"{len(style_issues)} style issue(s):")
for issue in style_issues:
print(f" - {issue}")
else:
print("No PEP8 style issues found.")
else:
style_issues = []
print("Skipped (code has a syntax error).")
return {
"explanation": explanation,
"line_by_line": breakdown if ok else None,
"bug_result": bug_result,
"style_issues": style_issues,
}
if __name__ == "__main__":
sample_code = """def add_numbers(a, b)
return a + b"""
analyze_code(sample_code)
|