CoolFace
Apppublic

rgera/compiler_project

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
app.py349 linesDownload Raw Back to root
1import ast2import gradio as gr3from PIL import Image4import io5import networkx as nx6import matplotlib.pyplot as plt7import copy8import google.generativeai as genai9import os10from dotenv import load_dotenv11import speech_recognition as sr12import numpy as np13import wave14import tempfile15 16load_dotenv()17# Configure Gemini API18genai.configure(api_key=os.getenv('GEMINI_API_KEY'))19model = genai.GenerativeModel('gemini-1.5-flash')20 21def generate_code(prompt: str):22    try:23        response = model.generate_content(24            f"Write Python code for this requirement: {prompt}. "25            "Only return the code without any explanation."26        )27        generated_code = response.text.strip()28        # Try parsing the generated code to verify it's valid Python29        30        generated_code = generated_code[9:-3]31 32        ast.parse(generated_code) #temporarily 33        return "Code generated successfully!", generated_code34    except Exception as e:35        return f"Error: {str(e)}", ""36 37def transcribe_audio(audio):38    if audio is None:39        return "Error: No audio provided", ""40        41    recognizer = sr.Recognizer()42    try:43        # Handle different audio input formats44        if isinstance(audio, str):45            # Direct file path46            with sr.AudioFile(audio) as source:47                audio_data = recognizer.record(source)48        else:49            # Convert numpy array to WAV file50            sample_rate, y = audio51            with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as temp_audio:52                with wave.open(temp_audio.name, 'wb') as wf:53                    wf.setnchannels(1)54                    wf.setsampwidth(2)55                    wf.setframerate(sample_rate)56                    wf.writeframes((y * 32767).astype(np.int16).tobytes())57                58                with sr.AudioFile(temp_audio.name) as source:59                    audio_data = recognizer.record(source)60                    61        text = recognizer.recognize_google(audio_data)62        return "Transcription successful!", text63    except Exception as e:64        return f"Error in transcription: {str(e)}", ""65 66def process_voice_to_code(audio_path):67    status, transcribed_text = transcribe_audio(audio_path)68    if "Error" in status:69        return status, ""70    return generate_code(transcribed_text)71 72# Step 1: Convert AST to NetworkX73def visualize_ast(code: str):74    try:75        tree = ast.parse(code)76    except SyntaxError as e:77        return f"Syntax Error: {e}", None78 79    G = nx.DiGraph()80    81    def get_node_label(node):82        if isinstance(node, ast.Name):83            return f"{type(node).__name__}\nid: {node.id}"84        elif isinstance(node, ast.Constant):85            return f"{type(node).__name__}\nvalue: {node.value}"86        elif isinstance(node, ast.FunctionDef):87            return f"{type(node).__name__}\nname: {node.name}"88        elif isinstance(node, ast.ClassDef):89            return f"{type(node).__name__}\nname: {node.name}"90        elif isinstance(node, ast.Call):91            return f"{type(node).__name__}"92        else:93            return type(node).__name__94 95    def add_nodes_edges(node, parent_id=None, edge_label=""):96        node_id = id(node)97        G.add_node(node_id, label=get_node_label(node))98        if parent_id is not None:99            G.add_edge(parent_id, node_id, label=edge_label)100        101        for field, value in ast.iter_fields(node):102            if isinstance(value, ast.AST):103                add_nodes_edges(value, node_id, field)104            elif isinstance(value, list):105                for item in value:106                    if isinstance(item, ast.AST):107                        add_nodes_edges(item, node_id, field)108    109    add_nodes_edges(tree)110    111    plt.figure(figsize=(15, 10))112    pos = nx.kamada_kawai_layout(G)  # Better layout for hierarchical structures113    114    # Draw edges with labels115    nx.draw_networkx_edges(G, pos, edge_color='gray', arrows=True, arrowsize=20)116    edge_labels = nx.get_edge_attributes(G, 'label')117    nx.draw_networkx_edge_labels(G, pos, edge_labels, font_size=8)118    119    # Draw nodes with custom style120    nx.draw_networkx_nodes(G, pos, node_color='lightblue', 121                          node_size=2500, alpha=0.9)122    123    # Add node labels with better formatting124    labels = nx.get_node_attributes(G, 'label')125    nx.draw_networkx_labels(G, pos, labels, font_size=8)126    127    plt.title("Abstract Syntax Tree Visualization")128    129    # Save to buffer with higher DPI for better quality130    buf = io.BytesIO()131    plt.savefig(buf, format='png', bbox_inches='tight', dpi=200)132    plt.close()133    buf.seek(0)134    image = Image.open(buf)135    136    return "AST Generated Successfully", image137 138# Step 2: Data Flow Analysis139def analyze_dataflow(code: str):140    try:141        tree = ast.parse(code)142    except SyntaxError as e:143        return f"Syntax Error: {e}", None144    145    146    DFG = nx.DiGraph()147    variables = {}  # Track variable definitions and uses148    149    class DataFlowVisitor(ast.NodeVisitor):150        def visit_Assign(self, node):151            for target in node.targets:152                if isinstance(target, ast.Name):153                    var_name = target.id154                    def_id = f"def_{var_name}_{id(node)}"155                    DFG.add_node(def_id, label=f"Define\n{var_name}", type="def")156                    variables[var_name] = variables.get(var_name, []) + [def_id]157            self.generic_visit(node)158            159        def visit_Name(self, node):160            if isinstance(node.ctx, ast.Load):161                var_name = node.id162                use_id = f"use_{var_name}_{id(node)}"163                DFG.add_node(use_id, label=f"Use\n{var_name}", type="use")164                # Add edges from all previous definitions165                if var_name in variables:166                    for def_id in variables[var_name]:167                        DFG.add_edge(def_id, use_id)168    169    DataFlowVisitor().visit(tree)170    171    if not DFG.nodes():172        return "No data flow to analyze", None173    174    plt.figure(figsize=(15, 10))175    pos = nx.spring_layout(DFG, k=2)  # More spread out layout176    177    # Draw nodes with different colors for def/use178    def_nodes = [n for n, d in DFG.nodes(data=True) if d.get('type') == 'def']179    use_nodes = [n for n, d in DFG.nodes(data=True) if d.get('type') == 'use']180    181    nx.draw_networkx_nodes(DFG, pos, nodelist=def_nodes, node_color='lightgreen', 182                          node_size=3000, alpha=0.9)183    nx.draw_networkx_nodes(DFG, pos, nodelist=use_nodes, node_color='lightblue',184                          node_size=3000, alpha=0.9)185    186    # Draw edges and labels187    nx.draw_networkx_edges(DFG, pos, edge_color='gray', arrows=True, arrowsize=20)188    labels = nx.get_node_attributes(DFG, 'label')189    nx.draw_networkx_labels(DFG, pos, labels, font_size=10)190    191    plt.title("Data Flow Graph")192    193    buf = io.BytesIO()194    plt.savefig(buf, format='png', bbox_inches='tight', dpi=200)195    plt.close()196    buf.seek(0)197    image = Image.open(buf)198    199    return "Data Flow Analysis Complete", image200 201# Step 3: Optimization Analysis202def analyze_optimizations(code: str):203    try:204        tree = ast.parse(code)205    except SyntaxError as e:206        return f"Syntax Error: {e}", None207    208    CFG = nx.DiGraph()209    constants = {}210    dead_code = set()211    212    class OptimizationVisitor(ast.NodeVisitor):213        def __init__(self):214            self.current_block = 0215            self.last_block = 0216        217        def new_block(self):218            self.last_block = self.current_block219            self.current_block += 1220            return self.current_block221        222        def visit_Assign(self, node):223            if isinstance(node.value, ast.Constant):224                constants[id(node)] = node.value.value225            226            block_id = f"B{self.current_block}"227            label = ast.unparse(node)228            CFG.add_node(block_id, label=label, type='assign')229            230            if self.last_block >= 0:231                CFG.add_edge(f"B{self.last_block}", block_id)232            233            # Mark as dead code if value is never used234            if isinstance(node.targets[0], ast.Name):235                var_name = node.targets[0].id236                if not any(isinstance(n, ast.Name) and n.id == var_name 237                          for n in ast.walk(tree) if isinstance(n, ast.Name) 238                          and isinstance(n.ctx, ast.Load)):239                    dead_code.add(block_id)240            241            self.generic_visit(node)242    243    OptimizationVisitor().visit(tree)244    245    plt.figure(figsize=(15, 10))246    pos = nx.spring_layout(CFG, k=2)247    248    # Draw nodes with different colors based on optimization opportunities249    regular_nodes = [n for n in CFG.nodes() if n not in dead_code]250    dead_nodes = list(dead_code)251    252    # Draw regular nodes253    nx.draw_networkx_nodes(CFG, pos, nodelist=regular_nodes, 254                          node_color='lightblue', node_size=3000)255    # Draw dead code nodes256    nx.draw_networkx_nodes(CFG, pos, nodelist=dead_nodes,257                          node_color='salmon', node_size=3000)258    259    # Draw edges and labels260    nx.draw_networkx_edges(CFG, pos, edge_color='gray', arrows=True, arrowsize=20)261    labels = nx.get_node_attributes(CFG, 'label')262    nx.draw_networkx_labels(CFG, pos, labels, font_size=10)263    264    # Add legend265    plt.plot([], [], 'o', color='salmon', label='Dead Code')266    plt.plot([], [], 'o', color='lightblue', label='Active Code')267    plt.legend()268    269    plt.title("Control Flow Graph with Optimization Opportunities")270    271    buf = io.BytesIO()272    plt.savefig(buf, format='png', bbox_inches='tight', dpi=200)273    plt.close()274    buf.seek(0)275    image = Image.open(buf)276    277    # Prepare optimization summary278    summary = []279    if dead_code:280        summary.append(f"Found {len(dead_code)} dead code block(s)")281    if constants:282        summary.append(f"Found {len(constants)} constant propagation opportunities")283    284    return "\n".join(summary) if summary else "No optimization opportunities found", image285 286# Step 4: Gradio Interface287with gr.Blocks() as demo:288    gr.Markdown("## 🧠 Python Code Analysis Visualizer")289    290    with gr.Tabs():291        with gr.TabItem("AST Visualization"):292            with gr.Row():293                ast_code_input = gr.Code(label="Enter Python Code", language="python")294                ast_output = gr.Image(label="AST Visualization")295            ast_status = gr.Textbox(label="Status")296            ast_btn = gr.Button("Visualize AST")297            298        with gr.TabItem("Data Flow Analysis"):299            with gr.Row():300                dfg_code_input = gr.Code(label="Enter Python Code", language="python")301                dfg_output = gr.Image(label="Data Flow Graph")302            dfg_status = gr.Textbox(label="Status")303            dfg_btn = gr.Button("Analyze Data Flow")304        305        with gr.TabItem("Optimization Analysis"):306            with gr.Row():307                opt_code_input = gr.Code(label="Enter Python Code", language="python")308                opt_output = gr.Image(label="Optimization Visualization")309            opt_status = gr.Textbox(label="Optimization Opportunities")310            opt_btn = gr.Button("Analyze Optimizations")311        312        with gr.TabItem("Natural Language to Code"):313            with gr.Row():314                with gr.Column():315                    prompt_input = gr.Textbox(316                        label="Enter your requirement in natural language",317                        placeholder="e.g., write a function to calculate fibonacci series"318                    )319                    audio_input = gr.Audio(320                        sources=["microphone"],321                        type="numpy",322                        label="Or speak your requirement"323                    )324                with gr.Column():325                    code_output = gr.Code(326                        label="Generated Code",327                        language="python"328                    )329            gen_status = gr.Textbox(label="Status")330            with gr.Row():331                generate_btn = gr.Button("Generate from Text")332                voice_btn = gr.Button("Generate from Voice")333    334    ast_btn.click(visualize_ast, inputs=ast_code_input, outputs=[ast_status, ast_output])335    dfg_btn.click(analyze_dataflow, inputs=dfg_code_input, outputs=[dfg_status, dfg_output])336    opt_btn.click(analyze_optimizations, inputs=opt_code_input, outputs=[opt_status, opt_output])337    generate_btn.click(338        generate_code,339        inputs=prompt_input,340        outputs=[gen_status, code_output]341    )342    voice_btn.click(343        process_voice_to_code,344        inputs=audio_input,345        outputs=[gen_status, code_output]346    )347 348demo.launch()349