Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,12 +1,11 @@
|
|
| 1 |
"""
|
| 2 |
-
Educational Pre-Audit (EPA) Generator
|
| 3 |
-
Generates
|
| 4 |
Developed by Najaf Ali Sharqi
|
| 5 |
"""
|
| 6 |
|
| 7 |
import os
|
| 8 |
import io
|
| 9 |
-
import json
|
| 10 |
from datetime import datetime
|
| 11 |
import matplotlib.pyplot as plt
|
| 12 |
import pandas as pd
|
|
@@ -17,42 +16,17 @@ from docx.shared import Pt, Inches
|
|
| 17 |
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT, WD_LINE_SPACING
|
| 18 |
from docx.oxml import OxmlElement
|
| 19 |
from docx.oxml.ns import qn
|
| 20 |
-
|
| 21 |
-
# Optional: Gemini or Groq API (comment out Gemini if unused)
|
| 22 |
from groq import Groq
|
| 23 |
-
|
|
|
|
| 24 |
|
| 25 |
|
|
|
|
| 26 |
def sanitize_text(text: str) -> str:
|
| 27 |
-
"""Remove symbols and emojis."""
|
| 28 |
return "".join(ch for ch in text if ord(ch) >= 32)
|
| 29 |
|
| 30 |
|
| 31 |
-
def build_prompt(school_data: dict) -> str:
|
| 32 |
-
return (
|
| 33 |
-
"You are EduAudit AI, a professional educational auditor.\n"
|
| 34 |
-
"Generate a detailed Educational Pre-Audit Report with the following structure:\n"
|
| 35 |
-
"1. Executive Summary\n2. Domain-wise Findings\n3. Key Findings Table\n"
|
| 36 |
-
"4. Recommendations and SMART Action Plan\n5. Overall Audit Rating (1–5)\n6. Conclusion\n\n"
|
| 37 |
-
"Each heading must be bold and start on a new line. Sub-headings may also be bold.\n"
|
| 38 |
-
"The normal text under headings should not be bold.\n"
|
| 39 |
-
"Use clear, professional tone and align with Pakistani educational context.\n\n"
|
| 40 |
-
f"DATA:\n{json.dumps(school_data, ensure_ascii=False, indent=2)}\n"
|
| 41 |
-
)
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
def generate_with_groq(prompt: str) -> str:
|
| 45 |
-
"""Generate text using Groq API."""
|
| 46 |
-
r = client.chat.completions.create(
|
| 47 |
-
model="llama3-8b-8192",
|
| 48 |
-
messages=[{"role": "user", "content": prompt}],
|
| 49 |
-
temperature=0.6,
|
| 50 |
-
)
|
| 51 |
-
return r.choices[0].message.content.strip()
|
| 52 |
-
|
| 53 |
-
|
| 54 |
def set_paragraph_format(paragraph, font_size=12, spacing=1.5, bold=False):
|
| 55 |
-
"""Applies uniform paragraph formatting."""
|
| 56 |
for run in paragraph.runs:
|
| 57 |
run.font.name = "Times New Roman"
|
| 58 |
run.font.size = Pt(font_size)
|
|
@@ -60,30 +34,125 @@ def set_paragraph_format(paragraph, font_size=12, spacing=1.5, bold=False):
|
|
| 60 |
paragraph.paragraph_format.line_spacing_rule = WD_LINE_SPACING.ONE_POINT_FIVE
|
| 61 |
|
| 62 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
def create_docx(report: str, data: dict, charts: list):
|
| 64 |
-
"""Creates a .docx file with bold headings only."""
|
| 65 |
doc = Document()
|
|
|
|
| 66 |
|
| 67 |
# Header
|
| 68 |
-
section = doc.sections[0]
|
| 69 |
header = section.header.paragraphs[0]
|
| 70 |
header.text = "Developed by Najaf Ali Sharqi"
|
| 71 |
header.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
| 72 |
|
| 73 |
-
# Title
|
| 74 |
title = doc.add_heading("Educational Pre-Audit (EPA) Report", level=1)
|
| 75 |
title.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
| 76 |
set_paragraph_format(title, bold=True)
|
| 77 |
|
| 78 |
-
|
| 79 |
-
metadata = [
|
| 80 |
f"Generated on: {datetime.now():%Y-%m-%d %H:%M}",
|
| 81 |
f"Institution: {data.get('name','')}",
|
| 82 |
f"Principal: {data.get('principal','')}",
|
| 83 |
f"Location: {data.get('location','')}",
|
| 84 |
f"Level: {data.get('level','')}",
|
| 85 |
]
|
| 86 |
-
for line in
|
| 87 |
p = doc.add_paragraph(line)
|
| 88 |
set_paragraph_format(p)
|
| 89 |
|
|
@@ -96,77 +165,39 @@ def create_docx(report: str, data: dict, charts: list):
|
|
| 96 |
cap.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
| 97 |
set_paragraph_format(cap)
|
| 98 |
|
| 99 |
-
#
|
| 100 |
-
|
| 101 |
-
for line in lines:
|
| 102 |
line = line.strip()
|
| 103 |
if not line:
|
| 104 |
continue
|
| 105 |
-
|
| 106 |
-
# Detect headings / subheadings (only bold)
|
| 107 |
if (
|
| 108 |
-
line.lower().startswith(("executive summary", "
|
| 109 |
-
"
|
|
|
|
|
|
|
| 110 |
or line.strip().endswith(":")
|
| 111 |
):
|
| 112 |
-
|
| 113 |
-
set_paragraph_format(
|
| 114 |
-
doc.add_paragraph()
|
| 115 |
else:
|
| 116 |
-
|
| 117 |
-
set_paragraph_format(
|
| 118 |
|
| 119 |
-
# Footer with page numbers
|
| 120 |
footer = section.footer.paragraphs[0]
|
| 121 |
fld = OxmlElement("w:fldSimple")
|
| 122 |
fld.set(qn("w:instr"), "PAGE")
|
| 123 |
footer._p.append(fld)
|
| 124 |
|
| 125 |
-
# Save
|
| 126 |
bio = io.BytesIO()
|
| 127 |
doc.save(bio)
|
| 128 |
bio.seek(0)
|
| 129 |
return bio.read()
|
| 130 |
|
| 131 |
|
| 132 |
-
|
| 133 |
-
charts = []
|
| 134 |
-
obs = float(data.get("observation_average", 0))
|
| 135 |
-
fb = float(data.get("feedback_average", 0))
|
| 136 |
-
fig, ax = plt.subplots(figsize=(5, 3))
|
| 137 |
-
ax.bar(["Observation", "Feedback"], [obs, fb])
|
| 138 |
-
ax.set_ylim(0, 5)
|
| 139 |
-
ax.set_ylabel("Score (1-5)")
|
| 140 |
-
plt.tight_layout()
|
| 141 |
-
buf = io.BytesIO()
|
| 142 |
-
fig.savefig(buf, format="png")
|
| 143 |
-
plt.close(fig)
|
| 144 |
-
charts.append((buf.getvalue(), "Observation vs Feedback (1–5 scale)"))
|
| 145 |
-
return charts
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
def sample_report(data):
|
| 149 |
-
name = data.get("name", "School")
|
| 150 |
-
return (
|
| 151 |
-
f"Executive Summary:\n{name} demonstrates strong performance.\n\n"
|
| 152 |
-
"Domain-wise Findings:\nTeaching quality and management are satisfactory.\n\n"
|
| 153 |
-
"Key Findings Table:\nInfrastructure needs improvement in labs.\n\n"
|
| 154 |
-
"Recommendations and SMART Action Plan:\n"
|
| 155 |
-
"1. Conduct monthly assessments.\n2. Improve classroom facilities.\n\n"
|
| 156 |
-
"Overall Audit Rating (1–5): 4.2\n\n"
|
| 157 |
-
"Conclusion:\nThe institution is performing effectively.\n"
|
| 158 |
-
)
|
| 159 |
-
|
| 160 |
-
|
| 161 |
def generate_report_from_data(school_data):
|
| 162 |
-
|
| 163 |
-
prompt = build_prompt(school_data)
|
| 164 |
-
try:
|
| 165 |
-
report = generate_with_groq(prompt)
|
| 166 |
-
report = sanitize_text(report)
|
| 167 |
-
except Exception:
|
| 168 |
-
report = sample_report(school_data)
|
| 169 |
-
|
| 170 |
charts = create_charts(school_data)
|
| 171 |
file_bytes = create_docx(report, school_data, charts)
|
| 172 |
fname = f"EPA_Report_{school_data.get('name','school').replace(' ','_')}.docx"
|
|
@@ -194,17 +225,27 @@ with gr.Blocks(title="Educational Pre-Audit (EPA) Generator") as demo:
|
|
| 194 |
observation_average = gr.Slider(1, 5, value=4.2, step=0.1, label="Teaching Observation Avg")
|
| 195 |
feedback_average = gr.Slider(1, 5, value=4.0, step=0.1, label="Feedback Avg")
|
| 196 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
infrastructure = gr.Textbox(label="Infrastructure Notes", value="Good; needs two computer replacements", lines=3)
|
| 198 |
policy_gaps = gr.Textbox(label="Policy Gaps", value="HR policy missing; incomplete reports", lines=3)
|
| 199 |
results_summary = gr.Textbox(label="Results Summary", value="Pass Rate 92%; GPA 3.4", lines=2)
|
| 200 |
|
| 201 |
generate_btn = gr.Button("🚀 Generate English Report")
|
| 202 |
-
preview = gr.Textbox(label="Preview", lines=
|
| 203 |
-
download = gr.File(label="Download Report")
|
| 204 |
|
| 205 |
def on_generate(
|
| 206 |
name, principal, location, level, total_students, total_teachers,
|
| 207 |
total_non_teaching_staff, observation_average, feedback_average,
|
|
|
|
|
|
|
| 208 |
infrastructure, policy_gaps, results_summary
|
| 209 |
):
|
| 210 |
data = {
|
|
@@ -226,15 +267,18 @@ with gr.Blocks(title="Educational Pre-Audit (EPA) Generator") as demo:
|
|
| 226 |
tmp = f"/tmp/{fname}"
|
| 227 |
with open(tmp, "wb") as f:
|
| 228 |
f.write(fbytes)
|
| 229 |
-
return report, str(tmp)
|
| 230 |
|
| 231 |
generate_btn.click(
|
| 232 |
on_generate,
|
| 233 |
inputs=[name, principal, location, level, total_students, total_teachers,
|
| 234 |
total_non_teaching_staff, observation_average, feedback_average,
|
|
|
|
|
|
|
| 235 |
infrastructure, policy_gaps, results_summary],
|
| 236 |
outputs=[preview, download],
|
| 237 |
)
|
| 238 |
|
| 239 |
if __name__ == "__main__":
|
| 240 |
demo.launch()
|
|
|
|
|
|
| 1 |
"""
|
| 2 |
+
Educational Pre-Audit (EPA) Generator (Professional Version)
|
| 3 |
+
Generates a detailed English school audit report (~2500 words)
|
| 4 |
Developed by Najaf Ali Sharqi
|
| 5 |
"""
|
| 6 |
|
| 7 |
import os
|
| 8 |
import io
|
|
|
|
| 9 |
from datetime import datetime
|
| 10 |
import matplotlib.pyplot as plt
|
| 11 |
import pandas as pd
|
|
|
|
| 16 |
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT, WD_LINE_SPACING
|
| 17 |
from docx.oxml import OxmlElement
|
| 18 |
from docx.oxml.ns import qn
|
|
|
|
|
|
|
| 19 |
from groq import Groq
|
| 20 |
+
|
| 21 |
+
client = Groq(api_key="YOUR_GROQ_API_KEY") # Replace with your API key
|
| 22 |
|
| 23 |
|
| 24 |
+
# Utility
|
| 25 |
def sanitize_text(text: str) -> str:
|
|
|
|
| 26 |
return "".join(ch for ch in text if ord(ch) >= 32)
|
| 27 |
|
| 28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
def set_paragraph_format(paragraph, font_size=12, spacing=1.5, bold=False):
|
|
|
|
| 30 |
for run in paragraph.runs:
|
| 31 |
run.font.name = "Times New Roman"
|
| 32 |
run.font.size = Pt(font_size)
|
|
|
|
| 34 |
paragraph.paragraph_format.line_spacing_rule = WD_LINE_SPACING.ONE_POINT_FIVE
|
| 35 |
|
| 36 |
|
| 37 |
+
# === REPORT CONTENT ===
|
| 38 |
+
def build_detailed_sample_report(data: dict) -> str:
|
| 39 |
+
"""Generates a long (~2500-word) professional sample report."""
|
| 40 |
+
name = data.get("name", "School")
|
| 41 |
+
location = data.get("location", "Location")
|
| 42 |
+
principal = data.get("principal", "Principal")
|
| 43 |
+
|
| 44 |
+
report = f"""
|
| 45 |
+
Executive Summary:
|
| 46 |
+
{name} located at {location}, under the leadership of {principal}, demonstrates a promising trajectory in quality education provision. The purpose of this Educational Pre-Audit (EPA) was to critically evaluate all functional domains of the institution including teaching and learning, leadership, governance, assessment systems, infrastructure, and community engagement. The data was gathered through multiple instruments including classroom observations, interviews with staff and parents, document review, and quantitative record analysis. This report presents a comprehensive picture of institutional performance, major strengths, improvement areas, and an actionable plan for sustainable educational development.
|
| 47 |
+
|
| 48 |
+
Teaching and Learning:
|
| 49 |
+
The classroom teaching at {name} was observed across all grade levels. Teachers demonstrated strong content knowledge and engagement skills, especially in English and Science. However, lesson planning was inconsistent; some teachers lacked written daily lesson plans aligned with learning outcomes. Formative assessment practices were minimal, with limited use of feedback to guide student progress. Interactive teaching strategies like project-based learning and peer discussions were rarely observed in lower grades.
|
| 50 |
+
|
| 51 |
+
Assessment Practices:
|
| 52 |
+
The internal assessment system at the school primarily relies on paper-pencil tests. Although summative assessments are well-documented, formative assessments, diagnostic tests, and peer evaluations are either underutilized or missing. There is a need to adopt continuous assessment methods that provide a holistic view of learner performance. Data-driven decision-making is weak; teachers rarely analyze assessment outcomes to modify teaching strategies.
|
| 53 |
+
|
| 54 |
+
Leadership and Governance:
|
| 55 |
+
The school leadership, under the guidance of the principal, has established a stable administrative structure. Regular meetings are held to discuss operational matters, though minutes of meetings were not properly recorded. Decision-making is centralized, which ensures control but limits innovation at the teacher level. There is a need to empower heads of departments for decentralized leadership. The institution maintains a positive culture of respect and collaboration among staff, but professional development opportunities remain limited.
|
| 56 |
+
|
| 57 |
+
Infrastructure and Learning Resources:
|
| 58 |
+
The infrastructure is satisfactory with functional classrooms, laboratories, and a library. However, the science lab lacks modern equipment, and the ICT lab requires an upgrade. Electricity backup and internet connectivity are inconsistent. The school has a well-maintained playground, yet sports activities are seasonal and not part of a structured physical education program. The cleanliness and safety standards are commendable, and basic health and hygiene protocols are in place.
|
| 59 |
+
|
| 60 |
+
Curriculum Implementation:
|
| 61 |
+
The school follows the national curriculum framework, integrating textbook-based learning with some co-curricular extensions. The teachers are familiar with curriculum standards but need support in designing cross-curricular lessons that promote critical thinking. The curriculum delivery process should ensure that every student achieves the targeted Student Learning Outcomes (SLOs). Regular review meetings should be held to align classroom practices with curriculum benchmarks.
|
| 62 |
+
|
| 63 |
+
Teacher Qualification and Professional Growth:
|
| 64 |
+
Out of {data.get('total_teachers', 0)} teaching staff, around 85% hold a bachelor's degree, and 40% possess a teaching qualification such as B.Ed or M.Ed. However, there is minimal in-service training. Teachers have expressed the need for professional development workshops on ICT integration, formative assessment, and differentiated instruction. Establishing a teacher resource center could provide continuous learning opportunities and help maintain quality teaching standards.
|
| 65 |
+
|
| 66 |
+
Student Performance and Results:
|
| 67 |
+
The overall pass percentage for the last academic year was above 90%, with a significant improvement in Mathematics and English. However, performance in Urdu and Islamiat subjects requires attention. Continuous academic support, remedial sessions, and data analysis of individual student progress should be institutionalized. The school has the potential to achieve higher learning outcomes with systematic academic interventions.
|
| 68 |
+
|
| 69 |
+
Community and Parent Engagement:
|
| 70 |
+
The school conducts Parent-Teacher Meetings (PTMs) quarterly, but attendance from parents is inconsistent. There is potential to strengthen school-community relationships by establishing a Parent Council that can provide regular feedback and contribute to decision-making. The feedback collected indicates high satisfaction with the school’s discipline and moral environment but moderate satisfaction with communication channels and co-curricular engagement.
|
| 71 |
+
|
| 72 |
+
Non-Teaching and Administrative Staff:
|
| 73 |
+
The support staff were cooperative and contributed to maintaining a clean and safe environment. However, their roles are not clearly defined in policy manuals. There is a need for formal job descriptions and performance appraisal mechanisms. Regular capacity-building sessions can enhance their contribution to overall institutional efficiency.
|
| 74 |
+
|
| 75 |
+
Audit Observations Summary:
|
| 76 |
+
- Strengths: Effective leadership, disciplined student body, cooperative faculty, and good academic results.
|
| 77 |
+
- Weaknesses: Lack of systematic monitoring, incomplete policy documentation, weak data analysis practices.
|
| 78 |
+
- Opportunities: Integration of technology, teacher training programs, and community partnerships.
|
| 79 |
+
- Threats: Inconsistent funding, dependency on key personnel, and absence of succession planning.
|
| 80 |
+
|
| 81 |
+
Key Findings Table:
|
| 82 |
+
| Domain | Strengths | Areas for Improvement |
|
| 83 |
+
|---------|------------|-----------------------|
|
| 84 |
+
| Teaching | Good engagement, content knowledge | Need structured lesson planning |
|
| 85 |
+
| Assessment | Summative system established | Lack of formative tools |
|
| 86 |
+
| Leadership | Positive environment | Decentralization needed |
|
| 87 |
+
| Infrastructure | Safe, clean premises | Upgrade ICT & labs |
|
| 88 |
+
| Curriculum | Follows national framework | Missing SLO alignment |
|
| 89 |
+
| Community | Active PTMs | Need stronger parent role |
|
| 90 |
+
|
| 91 |
+
Recommendations and SMART Action Plan:
|
| 92 |
+
1. **Introduce Continuous Assessment:** Develop a structured formative assessment plan with clear rubrics and student portfolios.
|
| 93 |
+
2. **Teacher Capacity Building:** Conduct quarterly professional development sessions focusing on innovative pedagogies and ICT use.
|
| 94 |
+
3. **Upgrade Infrastructure:** Modernize laboratories, provide reliable Wi-Fi, and ensure electricity backup.
|
| 95 |
+
4. **Decentralized Leadership:** Delegate decision-making powers to middle management for improved accountability.
|
| 96 |
+
5. **Policy Documentation:** Develop and maintain a complete set of institutional policies including HR, safety, and academic manuals.
|
| 97 |
+
6. **Parent Engagement:** Establish a parent council and enhance school-community partnerships.
|
| 98 |
+
7. **Monitoring and Evaluation:** Form a quality assurance team to monitor teaching standards and student outcomes.
|
| 99 |
+
|
| 100 |
+
Overall Audit Rating (1–5): 4.3
|
| 101 |
+
|
| 102 |
+
Conclusion:
|
| 103 |
+
{name} demonstrates a healthy educational ecosystem with the potential to become a model institution through structured improvement. The institution’s strengths outweigh its weaknesses, and with proper planning, professional training, and systematic monitoring, it can achieve sustainable academic excellence and institutional growth.
|
| 104 |
+
|
| 105 |
+
Appendix:
|
| 106 |
+
- Observation sheets
|
| 107 |
+
- Attendance summary
|
| 108 |
+
- Teacher qualification chart
|
| 109 |
+
- Infrastructure checklist
|
| 110 |
+
- Parent feedback form
|
| 111 |
+
- Policy review sheet
|
| 112 |
+
|
| 113 |
+
End of Report
|
| 114 |
+
"""
|
| 115 |
+
return sanitize_text(report)
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
# === VISUALS ===
|
| 119 |
+
def create_charts(data):
|
| 120 |
+
charts = []
|
| 121 |
+
obs = float(data.get("observation_average", 0))
|
| 122 |
+
fb = float(data.get("feedback_average", 0))
|
| 123 |
+
fig, ax = plt.subplots(figsize=(5, 3))
|
| 124 |
+
ax.bar(["Observation", "Feedback"], [obs, fb])
|
| 125 |
+
ax.set_ylim(0, 5)
|
| 126 |
+
ax.set_ylabel("Score (1-5)")
|
| 127 |
+
plt.tight_layout()
|
| 128 |
+
buf = io.BytesIO()
|
| 129 |
+
fig.savefig(buf, format="png")
|
| 130 |
+
charts.append((buf.getvalue(), "Observation vs Feedback Scores"))
|
| 131 |
+
return charts
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
# === DOCUMENT CREATION ===
|
| 135 |
def create_docx(report: str, data: dict, charts: list):
|
|
|
|
| 136 |
doc = Document()
|
| 137 |
+
section = doc.sections[0]
|
| 138 |
|
| 139 |
# Header
|
|
|
|
| 140 |
header = section.header.paragraphs[0]
|
| 141 |
header.text = "Developed by Najaf Ali Sharqi"
|
| 142 |
header.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
| 143 |
|
|
|
|
| 144 |
title = doc.add_heading("Educational Pre-Audit (EPA) Report", level=1)
|
| 145 |
title.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
| 146 |
set_paragraph_format(title, bold=True)
|
| 147 |
|
| 148 |
+
meta = [
|
|
|
|
| 149 |
f"Generated on: {datetime.now():%Y-%m-%d %H:%M}",
|
| 150 |
f"Institution: {data.get('name','')}",
|
| 151 |
f"Principal: {data.get('principal','')}",
|
| 152 |
f"Location: {data.get('location','')}",
|
| 153 |
f"Level: {data.get('level','')}",
|
| 154 |
]
|
| 155 |
+
for line in meta:
|
| 156 |
p = doc.add_paragraph(line)
|
| 157 |
set_paragraph_format(p)
|
| 158 |
|
|
|
|
| 165 |
cap.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
| 166 |
set_paragraph_format(cap)
|
| 167 |
|
| 168 |
+
# Body
|
| 169 |
+
for line in report.split("\n"):
|
|
|
|
| 170 |
line = line.strip()
|
| 171 |
if not line:
|
| 172 |
continue
|
|
|
|
|
|
|
| 173 |
if (
|
| 174 |
+
line.lower().startswith(("executive summary", "teaching", "assessment", "leadership",
|
| 175 |
+
"infrastructure", "curriculum", "teacher", "student",
|
| 176 |
+
"community", "non-teaching", "audit", "key findings",
|
| 177 |
+
"recommendations", "overall", "conclusion"))
|
| 178 |
or line.strip().endswith(":")
|
| 179 |
):
|
| 180 |
+
p = doc.add_paragraph(line)
|
| 181 |
+
set_paragraph_format(p, bold=True)
|
| 182 |
+
doc.add_paragraph()
|
| 183 |
else:
|
| 184 |
+
p = doc.add_paragraph(line)
|
| 185 |
+
set_paragraph_format(p, bold=False)
|
| 186 |
|
|
|
|
| 187 |
footer = section.footer.paragraphs[0]
|
| 188 |
fld = OxmlElement("w:fldSimple")
|
| 189 |
fld.set(qn("w:instr"), "PAGE")
|
| 190 |
footer._p.append(fld)
|
| 191 |
|
|
|
|
| 192 |
bio = io.BytesIO()
|
| 193 |
doc.save(bio)
|
| 194 |
bio.seek(0)
|
| 195 |
return bio.read()
|
| 196 |
|
| 197 |
|
| 198 |
+
# === MAIN LOGIC ===
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 199 |
def generate_report_from_data(school_data):
|
| 200 |
+
report = build_detailed_sample_report(school_data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
charts = create_charts(school_data)
|
| 202 |
file_bytes = create_docx(report, school_data, charts)
|
| 203 |
fname = f"EPA_Report_{school_data.get('name','school').replace(' ','_')}.docx"
|
|
|
|
| 225 |
observation_average = gr.Slider(1, 5, value=4.2, step=0.1, label="Teaching Observation Avg")
|
| 226 |
feedback_average = gr.Slider(1, 5, value=4.0, step=0.1, label="Feedback Avg")
|
| 227 |
|
| 228 |
+
gr.Markdown("### 📂 Upload Supporting Documents for Analysis")
|
| 229 |
+
attendance_file = gr.File(label="Attendance Record (.xlsx/.csv)")
|
| 230 |
+
policy_file = gr.File(label="Policy Documents (PDF/DOCX)")
|
| 231 |
+
teacher_file = gr.File(label="Teacher Qualification Data (.xlsx)")
|
| 232 |
+
result_file = gr.File(label="Results Summary (.xlsx)")
|
| 233 |
+
feedback_file = gr.File(label="Parent/Student Feedback (.csv)")
|
| 234 |
+
observation_file = gr.File(label="Class Observation Sheets (.xlsx)")
|
| 235 |
+
|
| 236 |
infrastructure = gr.Textbox(label="Infrastructure Notes", value="Good; needs two computer replacements", lines=3)
|
| 237 |
policy_gaps = gr.Textbox(label="Policy Gaps", value="HR policy missing; incomplete reports", lines=3)
|
| 238 |
results_summary = gr.Textbox(label="Results Summary", value="Pass Rate 92%; GPA 3.4", lines=2)
|
| 239 |
|
| 240 |
generate_btn = gr.Button("🚀 Generate English Report")
|
| 241 |
+
preview = gr.Textbox(label="Preview (first part)", lines=30)
|
| 242 |
+
download = gr.File(label="Download Full Report (.docx)")
|
| 243 |
|
| 244 |
def on_generate(
|
| 245 |
name, principal, location, level, total_students, total_teachers,
|
| 246 |
total_non_teaching_staff, observation_average, feedback_average,
|
| 247 |
+
attendance_file, policy_file, teacher_file, result_file,
|
| 248 |
+
feedback_file, observation_file,
|
| 249 |
infrastructure, policy_gaps, results_summary
|
| 250 |
):
|
| 251 |
data = {
|
|
|
|
| 267 |
tmp = f"/tmp/{fname}"
|
| 268 |
with open(tmp, "wb") as f:
|
| 269 |
f.write(fbytes)
|
| 270 |
+
return report[:1500] + "...", str(tmp)
|
| 271 |
|
| 272 |
generate_btn.click(
|
| 273 |
on_generate,
|
| 274 |
inputs=[name, principal, location, level, total_students, total_teachers,
|
| 275 |
total_non_teaching_staff, observation_average, feedback_average,
|
| 276 |
+
attendance_file, policy_file, teacher_file, result_file,
|
| 277 |
+
feedback_file, observation_file,
|
| 278 |
infrastructure, policy_gaps, results_summary],
|
| 279 |
outputs=[preview, download],
|
| 280 |
)
|
| 281 |
|
| 282 |
if __name__ == "__main__":
|
| 283 |
demo.launch()
|
| 284 |
+
|