File size: 6,007 Bytes
7dc1531 7565dd4 7dc1531 f684b64 7dc1531 7565dd4 7dc1531 7565dd4 7dc1531 7565dd4 7dc1531 7565dd4 7dc1531 7565dd4 7dc1531 7565dd4 7dc1531 b55addf 7565dd4 b55addf 7565dd4 7dc1531 b55addf 7565dd4 7dc1531 b55addf 7dc1531 7565dd4 7dc1531 b55addf |
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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
import gradio as gr
from transformers import pipeline
import difflib
# --- Model Loading ---
# We use the 'text2text-generation' pipeline.
# device=-1 forces CPU usage, which is required for the free tier.
print("Initializing model...")
try:
corrector = pipeline(
"text2text-generation",
model="HamadML/grammer_correction",
device=-1
)
print("Model loaded successfully.")
except Exception as e:
print(f"Error loading model: {e}")
corrector = None
# --- Helper Functions for Scoring & Visuals ---
def diff_texts(text1, text2):
"""
Compares two strings and returns HTML highlighting differences.
Red strikethrough for deletions, Green bold for insertions.
"""
d = difflib.SequenceMatcher(None, text1, text2)
html = []
for tag, i1, i2, j1, j2 in d.get_opcodes():
if tag == 'delete':
# Mistake: Red strikethrough
html.append(f'<span style="color: #ef4444; text-decoration: line-through; background-color: #fee2e2; padding: 0 2px; border-radius: 2px;">{text1[i1:i2]}</span>')
elif tag == 'insert':
# Correction: Green bold
html.append(f'<span style="color: #16a34a; font-weight: bold; background-color: #dcfce7; padding: 0 2px; border-radius: 2px;">{text2[j1:j2]}</span>')
elif tag == 'replace':
# Mistake -> Correction
html.append(f'<span style="color: #ef4444; text-decoration: line-through; background-color: #fee2e2; padding: 0 2px; border-radius: 2px;">{text1[i1:i2]}</span>')
html.append(f'<span style="color: #16a34a; font-weight: bold; background-color: #dcfce7; padding: 0 2px; border-radius: 2px;">{text2[j1:j2]}</span>')
else:
# Unchanged text
html.append(text1[i1:i2])
return "".join(html)
def calculate_rubric_score(original, corrected):
"""
Generates a simple score and feedback based on text similarity.
"""
matcher = difflib.SequenceMatcher(None, original, corrected)
similarity = matcher.ratio() # 0.0 to 1.0
# Calculate score out of 100
score = int(similarity * 100)
if score == 100:
feedback = "Perfect! Your grammar is flawless."
color = "#16a34a" # Green
elif score >= 90:
feedback = "Excellent work! Just a few minor tweaks needed."
color = "#16a34a"
elif score >= 70:
feedback = "Good effort. You have some grammar errors to fix."
color = "#ca8a04" # Yellow/Orange
else:
feedback = "Needs improvement. Pay close attention to the corrections below."
color = "#dc2626" # Red
return score, feedback, color
# --- Core Logic ---
def evaluate_text(text):
if not text or not text.strip():
return ""
if corrector is None:
return "<p style='color:red;'>Error: The model failed to load.</p>"
try:
# 1. Get corrected text from AI
results = corrector(text, max_length=128)
corrected_text = results[0]['generated_text']
# 2. Generate Visual Diff
diff_html = diff_texts(text, corrected_text)
# 3. Calculate Score
score, feedback, color = calculate_rubric_score(text, corrected_text)
# 4. Construct HTML Report
report_html = f"""
<div style="font-family: sans-serif; padding: 24px; border: 1px solid #e5e7eb; border-radius: 12px; background: white; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; border-bottom: 2px solid #f3f4f6; padding-bottom: 15px;">
<h2 style="margin: 0; color: #1f2937; font-size: 1.5em;">Teacher's Report</h2>
<div style="background: {color}; color: white; padding: 8px 20px; border-radius: 99px; font-weight: bold; font-size: 1.2em;">
{score}/100
</div>
</div>
<div style="margin-bottom: 25px;">
<p style="color: #6b7280; margin: 0 0 8px 0; font-size: 0.85em; text-transform: uppercase; letter-spacing: 0.1em; font-weight: bold;">Feedback</p>
<p style="margin: 0; color: #374151; font-size: 1.1em; font-style: italic;">"{feedback}"</p>
</div>
<div>
<p style="color: #6b7280; margin: 0 0 12px 0; font-size: 0.85em; text-transform: uppercase; letter-spacing: 0.1em; font-weight: bold;">Correction View</p>
<div style="line-height: 1.8; font-size: 1.2em; color: #1f2937; background: #f9fafb; padding: 15px; border-radius: 8px; border: 1px solid #e5e7eb;">
{diff_html}
</div>
</div>
</div>
"""
return report_html
except Exception as e:
return f"<p style='color:red;'>Error during processing: {str(e)}</p>"
# --- User Interface ---
# CSS to hide footer and API links visually
css = """
footer {display: none !important;}
.api-link {display: none !important;}
"""
with gr.Blocks(title="Grammar Evaluator", theme=gr.themes.Soft(), css=css) as demo:
gr.Markdown(
"""
# 📝 AI Grammar Tool (Helper)
Type your sentence below. The AI will grade it, cross out mistakes in <span style='color: red; text-decoration: line-through;'>red</span>, and write corrections in <span style='color: green; font-weight: bold;'>green</span>.
"""
)
# Vertical Layout
input_box = gr.Textbox(
label="Student Writing",
placeholder="Example: I has went to the store yesterday...",
lines=5
)
submit_btn = gr.Button("Check My Text", variant="primary", size="lg")
output_html = gr.HTML(label="Evaluation Report")
submit_btn.click(fn=evaluate_text, inputs=input_box, outputs=output_html)
input_box.submit(fn=evaluate_text, inputs=input_box, outputs=output_html)
if __name__ == "__main__":
demo.launch() |