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)