Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -586,6 +586,65 @@ print("=" * 50)
|
|
| 586 |
print("STARTING MCQ GENERATOR APP")
|
| 587 |
print("=" * 50)
|
| 588 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 589 |
# ------------------------------
|
| 590 |
# Initialize Groq API Client
|
| 591 |
# ------------------------------
|
|
@@ -716,33 +775,77 @@ def rag_search(query, subject, k=5):
|
|
| 716 |
return "\n\n".join(results)
|
| 717 |
|
| 718 |
# ------------------------------
|
| 719 |
-
# Chapter Detection
|
| 720 |
# ------------------------------
|
| 721 |
-
def
|
| 722 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 723 |
if not groq_client:
|
| 724 |
return "Unknown Chapter"
|
| 725 |
|
| 726 |
-
|
|
|
|
|
|
|
| 727 |
|
| 728 |
-
|
| 729 |
-
{context[:800]}
|
| 730 |
|
| 731 |
-
|
|
|
|
| 732 |
|
| 733 |
-
|
| 734 |
-
|
| 735 |
-
- "Chemical Bonding"
|
| 736 |
-
- "Laws of Motion"
|
| 737 |
|
| 738 |
-
|
|
|
|
|
|
|
| 739 |
|
| 740 |
try:
|
| 741 |
response = groq_client.chat.completions.create(
|
| 742 |
messages=[
|
| 743 |
{
|
| 744 |
"role": "system",
|
| 745 |
-
"content": "You are an expert at identifying chapter
|
| 746 |
},
|
| 747 |
{
|
| 748 |
"role": "user",
|
|
@@ -754,12 +857,19 @@ Chapter name:"""
|
|
| 754 |
max_tokens=50
|
| 755 |
)
|
| 756 |
|
| 757 |
-
|
| 758 |
-
|
| 759 |
-
|
|
|
|
| 760 |
|
| 761 |
-
|
| 762 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 763 |
|
| 764 |
except Exception as e:
|
| 765 |
print(f"⚠️ Chapter detection failed: {e}")
|
|
@@ -789,8 +899,8 @@ Current status: API key not found or invalid."""
|
|
| 789 |
|
| 790 |
print(f"🤖 Generating MCQs for {subject} - {topic}")
|
| 791 |
|
| 792 |
-
#
|
| 793 |
-
chapter =
|
| 794 |
|
| 795 |
prompt = f"""You are a Class-12 {subject.title()} teacher creating MCQs.
|
| 796 |
Topic: "{topic}"
|
|
@@ -860,7 +970,7 @@ Possible causes:
|
|
| 860 |
3. Network issue
|
| 861 |
Please try again in a few seconds."""
|
| 862 |
print(f"❌ Groq API Error: {e}")
|
| 863 |
-
return error_msg,
|
| 864 |
|
| 865 |
def clean_mcq_output(text):
|
| 866 |
lines = text.split('\n')
|
|
@@ -1072,7 +1182,7 @@ HTML_TEMPLATE = """
|
|
| 1072 |
<div class="loading" id="loading">
|
| 1073 |
<div class="spinner"></div>
|
| 1074 |
<p style="color: #666; font-size: 16px;">Generating MCQs with AI...</p>
|
| 1075 |
-
<p style="color: #999; font-size: 13px; margin-top: 10px;">⚡ Detecting chapter
|
| 1076 |
</div>
|
| 1077 |
|
| 1078 |
<div class="result" id="result">
|
|
@@ -1212,4 +1322,4 @@ def health():
|
|
| 1212 |
if __name__ == "__main__":
|
| 1213 |
port = int(os.environ.get("PORT", 7860))
|
| 1214 |
print(f"\n🚀 Starting server on port {port}...\n")
|
| 1215 |
-
app.run(host="0.0.0.0", port=port, debug=False)
|
|
|
|
| 586 |
print("STARTING MCQ GENERATOR APP")
|
| 587 |
print("=" * 50)
|
| 588 |
|
| 589 |
+
# ------------------------------
|
| 590 |
+
# Chapter Names (Actual Textbook Chapters)
|
| 591 |
+
# ------------------------------
|
| 592 |
+
CHAPTER_NAMES = {
|
| 593 |
+
"biology": [
|
| 594 |
+
"Reproduction in Lower and Higher Plants",
|
| 595 |
+
"Reproduction in Lower and Higher Animals",
|
| 596 |
+
"Inheritance and Variation",
|
| 597 |
+
"Molecular Basis of Inheritance",
|
| 598 |
+
"Origin and Evolution of Life",
|
| 599 |
+
"Plant Water Relation",
|
| 600 |
+
"Plant Growth and Mineral Nutrition",
|
| 601 |
+
"Respiration and Circulation",
|
| 602 |
+
"Control and Co-ordination",
|
| 603 |
+
"Human Health and Diseases",
|
| 604 |
+
"Enhancement of Food Production",
|
| 605 |
+
"Biotechnology",
|
| 606 |
+
"Organisms and Populations",
|
| 607 |
+
"Ecosystems and Energy Flow",
|
| 608 |
+
"Biodiversity, Conservation and Environmental Issues"
|
| 609 |
+
],
|
| 610 |
+
"chemistry": [
|
| 611 |
+
"Solid State",
|
| 612 |
+
"Solutions",
|
| 613 |
+
"Ionic Equilibria",
|
| 614 |
+
"Chemical Thermodynamics",
|
| 615 |
+
"Electrochemistry",
|
| 616 |
+
"Chemical Kinetics",
|
| 617 |
+
"Elements of Groups 16, 17 and 18",
|
| 618 |
+
"Transition and Inner transition Elements",
|
| 619 |
+
"Coordination Compounds",
|
| 620 |
+
"Halogen Derivatives",
|
| 621 |
+
"Alcohols, Phenols and Ethers",
|
| 622 |
+
"Aldehydes, Ketones and Carboxylic acids",
|
| 623 |
+
"Amines",
|
| 624 |
+
"Biomolecules",
|
| 625 |
+
"Introduction to Polymer Chemistry",
|
| 626 |
+
"Green Chemistry and Nanochemistry"
|
| 627 |
+
],
|
| 628 |
+
"physics": [
|
| 629 |
+
"Rotational Dynamics",
|
| 630 |
+
"Mechanical Properties of Fluids",
|
| 631 |
+
"Kinetic Theory of Gases and Radiation",
|
| 632 |
+
"Thermodynamics",
|
| 633 |
+
"Oscillations",
|
| 634 |
+
"Superposition of Waves",
|
| 635 |
+
"Wave Optics",
|
| 636 |
+
"Electrostatics",
|
| 637 |
+
"Current Electricity",
|
| 638 |
+
"Magnetic Fields due to Electric Current",
|
| 639 |
+
"Magnetic Materials",
|
| 640 |
+
"Electromagnetic induction",
|
| 641 |
+
"AC Circuits",
|
| 642 |
+
"Dual Nature of Radiation and Matter",
|
| 643 |
+
"Structure of Atoms and Nuclei",
|
| 644 |
+
"Semiconductor Devices"
|
| 645 |
+
]
|
| 646 |
+
}
|
| 647 |
+
|
| 648 |
# ------------------------------
|
| 649 |
# Initialize Groq API Client
|
| 650 |
# ------------------------------
|
|
|
|
| 775 |
return "\n\n".join(results)
|
| 776 |
|
| 777 |
# ------------------------------
|
| 778 |
+
# Chapter Detection (Using Actual Chapter Names)
|
| 779 |
# ------------------------------
|
| 780 |
+
def detect_chapter_from_list(context, topic, subject):
|
| 781 |
+
"""
|
| 782 |
+
Detect chapter using the actual chapter list by matching keywords
|
| 783 |
+
"""
|
| 784 |
+
if subject not in CHAPTER_NAMES:
|
| 785 |
+
return "Unknown Chapter"
|
| 786 |
+
|
| 787 |
+
chapters = CHAPTER_NAMES[subject]
|
| 788 |
+
combined_text = (topic + " " + context[:1000]).lower()
|
| 789 |
+
|
| 790 |
+
# Score each chapter based on keyword matching
|
| 791 |
+
scores = {}
|
| 792 |
+
for chapter in chapters:
|
| 793 |
+
score = 0
|
| 794 |
+
chapter_words = chapter.lower().split()
|
| 795 |
+
|
| 796 |
+
# Check if chapter words appear in the content
|
| 797 |
+
for word in chapter_words:
|
| 798 |
+
if len(word) > 3: # Ignore small words like "and", "the"
|
| 799 |
+
if word in combined_text:
|
| 800 |
+
score += 1
|
| 801 |
+
|
| 802 |
+
# Bonus if topic is similar to chapter name
|
| 803 |
+
topic_words = topic.lower().split()
|
| 804 |
+
for t_word in topic_words:
|
| 805 |
+
if len(t_word) > 3 and t_word in chapter.lower():
|
| 806 |
+
score += 2
|
| 807 |
+
|
| 808 |
+
if score > 0:
|
| 809 |
+
scores[chapter] = score
|
| 810 |
+
|
| 811 |
+
# Return chapter with highest score
|
| 812 |
+
if scores:
|
| 813 |
+
best_chapter = max(scores.items(), key=lambda x: x[1])[0]
|
| 814 |
+
print(f"✓ Matched chapter: {best_chapter} (score: {scores[best_chapter]})")
|
| 815 |
+
return best_chapter
|
| 816 |
+
|
| 817 |
+
# Fallback: Use LLM to choose from the list
|
| 818 |
+
return detect_chapter_with_llm(context, topic, subject, chapters)
|
| 819 |
+
|
| 820 |
+
def detect_chapter_with_llm(context, topic, subject, chapters):
|
| 821 |
+
"""
|
| 822 |
+
Use LLM to pick the correct chapter from the provided list
|
| 823 |
+
"""
|
| 824 |
if not groq_client:
|
| 825 |
return "Unknown Chapter"
|
| 826 |
|
| 827 |
+
chapter_list = "\n".join([f"{i+1}. {ch}" for i, ch in enumerate(chapters)])
|
| 828 |
+
|
| 829 |
+
detection_prompt = f"""Based on the following textbook content and topic, identify which chapter from the list below this content belongs to.
|
| 830 |
|
| 831 |
+
Topic: {topic}
|
|
|
|
| 832 |
|
| 833 |
+
Content snippet:
|
| 834 |
+
{context[:600]}
|
| 835 |
|
| 836 |
+
Available chapters:
|
| 837 |
+
{chapter_list}
|
|
|
|
|
|
|
| 838 |
|
| 839 |
+
Respond with ONLY the chapter number and name exactly as listed (e.g., "5. Origin and Evolution of Life"). Choose the most relevant chapter.
|
| 840 |
+
|
| 841 |
+
Chapter:"""
|
| 842 |
|
| 843 |
try:
|
| 844 |
response = groq_client.chat.completions.create(
|
| 845 |
messages=[
|
| 846 |
{
|
| 847 |
"role": "system",
|
| 848 |
+
"content": "You are an expert at identifying which chapter textbook content belongs to. Respond with only the chapter number and name from the provided list."
|
| 849 |
},
|
| 850 |
{
|
| 851 |
"role": "user",
|
|
|
|
| 857 |
max_tokens=50
|
| 858 |
)
|
| 859 |
|
| 860 |
+
result = response.choices[0].message.content.strip()
|
| 861 |
+
|
| 862 |
+
# Extract chapter name from response (remove number prefix if present)
|
| 863 |
+
chapter = re.sub(r'^\d+\.\s*', '', result).strip()
|
| 864 |
|
| 865 |
+
# Verify it's in our list
|
| 866 |
+
for ch in chapters:
|
| 867 |
+
if ch.lower() in chapter.lower() or chapter.lower() in ch.lower():
|
| 868 |
+
print(f"✓ LLM detected chapter: {ch}")
|
| 869 |
+
return ch
|
| 870 |
+
|
| 871 |
+
print(f"⚠️ LLM response not in list: {result}")
|
| 872 |
+
return chapters[0] # Default to first chapter
|
| 873 |
|
| 874 |
except Exception as e:
|
| 875 |
print(f"⚠️ Chapter detection failed: {e}")
|
|
|
|
| 899 |
|
| 900 |
print(f"🤖 Generating MCQs for {subject} - {topic}")
|
| 901 |
|
| 902 |
+
# Detect the chapter from our actual chapter list
|
| 903 |
+
chapter = detect_chapter_from_list(context, topic, subject)
|
| 904 |
|
| 905 |
prompt = f"""You are a Class-12 {subject.title()} teacher creating MCQs.
|
| 906 |
Topic: "{topic}"
|
|
|
|
| 970 |
3. Network issue
|
| 971 |
Please try again in a few seconds."""
|
| 972 |
print(f"❌ Groq API Error: {e}")
|
| 973 |
+
return error_msg, chapter
|
| 974 |
|
| 975 |
def clean_mcq_output(text):
|
| 976 |
lines = text.split('\n')
|
|
|
|
| 1182 |
<div class="loading" id="loading">
|
| 1183 |
<div class="spinner"></div>
|
| 1184 |
<p style="color: #666; font-size: 16px;">Generating MCQs with AI...</p>
|
| 1185 |
+
<p style="color: #999; font-size: 13px; margin-top: 10px;">⚡ Detecting chapter from textbook...</p>
|
| 1186 |
</div>
|
| 1187 |
|
| 1188 |
<div class="result" id="result">
|
|
|
|
| 1322 |
if __name__ == "__main__":
|
| 1323 |
port = int(os.environ.get("PORT", 7860))
|
| 1324 |
print(f"\n🚀 Starting server on port {port}...\n")
|
| 1325 |
+
app.run(host="0.0.0.0", port=port, debug=False)
|