Update app.py
Browse files
app.py
CHANGED
@@ -954,12 +954,103 @@ def get_theme_story_starter(theme_id: str, level: str) -> Dict[str, str]:
|
|
954 |
"""Get a dynamically generated story starter for the selected theme and level."""
|
955 |
return generate_dynamic_story_starter(theme_id, level)
|
956 |
|
957 |
-
def get_theme_vocabulary(theme_id: str, level: str) -> List[str]:
|
958 |
-
"""
|
959 |
-
theme
|
960 |
-
|
961 |
-
|
962 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
963 |
|
964 |
# Add to session state initialization
|
965 |
def init_theme_state():
|
@@ -1693,13 +1784,16 @@ with col1:
|
|
1693 |
on_click=submit_story
|
1694 |
)
|
1695 |
|
|
|
1696 |
with col2:
|
1697 |
-
|
1698 |
if st.session_state.feedback:
|
1699 |
st.markdown("""
|
1700 |
-
<div class="
|
1701 |
-
<div class="thai"
|
1702 |
-
|
|
|
|
|
1703 |
</div>
|
1704 |
""", unsafe_allow_html=True)
|
1705 |
|
@@ -1750,74 +1844,76 @@ with col2:
|
|
1750 |
</p>
|
1751 |
</div>
|
1752 |
""", unsafe_allow_html=True)
|
1753 |
-
|
1754 |
-
# Help and Suggestions Box
|
1755 |
-
st.markdown("""
|
1756 |
-
<div class="thai-eng">
|
1757 |
-
<div class="thai">✨ เครื่องมือช่วยเขียน</div>
|
1758 |
-
<div class="eng">Writing Tools</div>
|
1759 |
-
</div>
|
1760 |
-
""", unsafe_allow_html=True)
|
1761 |
-
|
1762 |
-
if st.button("ดูคำศัพท์แนะนำ | Get Vocabulary Ideas"):
|
1763 |
-
vocab_suggestions = get_vocabulary_suggestions()
|
1764 |
-
st.markdown("#### 📚 คำศัพท์น่ารู้ | Useful Words")
|
1765 |
-
for word in vocab_suggestions:
|
1766 |
-
st.markdown(f"• {word}")
|
1767 |
-
|
1768 |
-
if st.button("ขอคำใบ้ | Get Creative Prompt"):
|
1769 |
-
prompt = get_creative_prompt()
|
1770 |
-
st.markdown(f"""
|
1771 |
-
<div class="thai-eng">
|
1772 |
-
<div class="thai">💭 {prompt['thai']}</div>
|
1773 |
-
<div class="eng">💭 {prompt['eng']}</div>
|
1774 |
-
</div>
|
1775 |
-
""", unsafe_allow_html=True)
|
1776 |
|
1777 |
-
|
1778 |
-
|
1779 |
-
|
1780 |
-
|
1781 |
-
|
1782 |
-
|
1783 |
-
|
1784 |
-
|
1785 |
-
|
1786 |
-
|
1787 |
-
|
1788 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1789 |
if st.session_state.story:
|
1790 |
-
st.markdown("### 💾 บันทึกเรื่องราว")
|
1791 |
col1, col2 = st.columns(2)
|
1792 |
|
1793 |
with col1:
|
1794 |
# บันทึกเป็น PDF
|
1795 |
pdf = create_story_pdf()
|
1796 |
st.download_button(
|
1797 |
-
label="📑
|
1798 |
data=pdf,
|
1799 |
file_name=f"my_story_{datetime.now().strftime('%Y%m%d')}.pdf",
|
1800 |
mime="application/pdf"
|
1801 |
)
|
1802 |
|
1803 |
with col2:
|
1804 |
-
#
|
1805 |
story_data = {
|
1806 |
'level': st.session_state.level,
|
1807 |
'date': datetime.now().isoformat(),
|
1808 |
'story': st.session_state.story,
|
1809 |
'achievements': st.session_state.achievements,
|
1810 |
'points': st.session_state.points,
|
1811 |
-
'stats':
|
1812 |
-
'total_sentences': st.session_state.stats['total_sentences'],
|
1813 |
-
'correct_first_try': st.session_state.stats['correct_first_try'],
|
1814 |
-
'accuracy_rate': st.session_state.stats['accuracy_rate'],
|
1815 |
-
'vocabulary_used': list(st.session_state.stats['vocabulary_used'])
|
1816 |
-
}
|
1817 |
}
|
1818 |
st.download_button(
|
1819 |
-
label="💾
|
1820 |
data=json.dumps(story_data, indent=2),
|
1821 |
file_name=f"story_progress_{datetime.now().strftime('%Y%m%d')}.json",
|
1822 |
mime="application/json"
|
1823 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
954 |
"""Get a dynamically generated story starter for the selected theme and level."""
|
955 |
return generate_dynamic_story_starter(theme_id, level)
|
956 |
|
957 |
+
def get_theme_vocabulary(theme_id: str, level: str) -> List[Dict[str, str]]:
|
958 |
+
"""
|
959 |
+
Get theme-specific vocabulary with Thai translations and example sentences.
|
960 |
+
Returns list of dictionaries containing word, type, thai meaning, and example.
|
961 |
+
"""
|
962 |
+
vocab_data = {
|
963 |
+
'fantasy': {
|
964 |
+
'Beginner': [
|
965 |
+
{
|
966 |
+
'word': 'magic',
|
967 |
+
'type': 'noun',
|
968 |
+
'thai': 'เวทมนตร์',
|
969 |
+
'example_en': 'The magic made flowers appear.',
|
970 |
+
'example_th': 'เวทมนตร์ทำให้ดอกไม้ปรากฏขึ้น'
|
971 |
+
},
|
972 |
+
{
|
973 |
+
'word': 'wizard',
|
974 |
+
'type': 'noun',
|
975 |
+
'thai': 'พ่อมด',
|
976 |
+
'example_en': 'The wizard waved his wand.',
|
977 |
+
'example_th': 'พ่อมดโบกไม้กายสิทธิ์'
|
978 |
+
}
|
979 |
+
],
|
980 |
+
'Intermediate': [
|
981 |
+
{
|
982 |
+
'word': 'enchanted',
|
983 |
+
'type': 'adjective',
|
984 |
+
'thai': 'ที่ถูกสะกดด้วยเวทมนตร์',
|
985 |
+
'example_en': 'They found an enchanted forest.',
|
986 |
+
'example_th': 'พวกเขาพบป่าที่ถูกสะกดด้วยเวทมนตร์'
|
987 |
+
}
|
988 |
+
]
|
989 |
+
},
|
990 |
+
'mystery': {
|
991 |
+
'Beginner': [
|
992 |
+
{
|
993 |
+
'word': 'clue',
|
994 |
+
'type': 'noun',
|
995 |
+
'thai': 'เบาะแส',
|
996 |
+
'example_en': 'The detective found an important clue.',
|
997 |
+
'example_th': 'นักสืบพบเบาะแสสำคัญ'
|
998 |
+
}
|
999 |
+
]
|
1000 |
+
}
|
1001 |
+
}
|
1002 |
+
|
1003 |
+
# แสดงคำศัพท์พร้อมตัวอย่างประโยคในหน้า UI
|
1004 |
+
def show_vocabulary(word_list: List[Dict[str, str]]):
|
1005 |
+
st.markdown("### 📚 คำศัพท์น่ารู้ประจำธีม")
|
1006 |
+
for word_data in word_list:
|
1007 |
+
st.markdown(f"""
|
1008 |
+
<div style="background-color: #f5f5f5; padding: 10px; border-radius: 5px; margin: 5px 0;">
|
1009 |
+
<strong>{word_data['word']}</strong> ({word_data['type']}) - {word_data['thai']}
|
1010 |
+
<br/>
|
1011 |
+
<span style="color: #666;">
|
1012 |
+
🇬🇧 {word_data['example_en']}<br/>
|
1013 |
+
🇹🇭 {word_data['example_th']}
|
1014 |
+
</span>
|
1015 |
+
</div>
|
1016 |
+
""", unsafe_allow_html=True)
|
1017 |
+
|
1018 |
+
# ปรับปรุงฟังก์ชัน show_theme_vocabulary
|
1019 |
+
def show_theme_vocabulary():
|
1020 |
+
if st.session_state.current_theme:
|
1021 |
+
vocab_list = vocab_data.get(st.session_state.current_theme, {}).get(st.session_state.level, [])
|
1022 |
+
if vocab_list:
|
1023 |
+
show_vocabulary(vocab_list)
|
1024 |
+
|
1025 |
+
# เพิ่มปุ่มสำหรับฝึกคำศัพท์
|
1026 |
+
if st.button("🎯 ฝึกคำศัพท์"):
|
1027 |
+
practice_vocabulary(vocab_list)
|
1028 |
+
|
1029 |
+
# เพิ่มฟังก์ชันฝึกคำศัพท์
|
1030 |
+
def practice_vocabulary(vocab_list: List[Dict[str, str]]):
|
1031 |
+
st.markdown("### 🎮 ฝึกคำศัพท์")
|
1032 |
+
|
1033 |
+
# สุ่มคำศัพท์มาทำแบบฝึกหัด
|
1034 |
+
word = random.choice(vocab_list)
|
1035 |
+
|
1036 |
+
# สร้างตัวเลือก
|
1037 |
+
choices = [word['thai']] # คำตอบที่ถูก
|
1038 |
+
other_words = [w['thai'] for w in vocab_list if w['thai'] != word['thai']]
|
1039 |
+
choices.extend(random.sample(other_words, min(3, len(other_words))))
|
1040 |
+
random.shuffle(choices)
|
1041 |
+
|
1042 |
+
st.write(f"คำว่า '{word['word']}' แปลว่าอะไร?")
|
1043 |
+
|
1044 |
+
for choice in choices:
|
1045 |
+
if st.button(choice):
|
1046 |
+
if choice == word['thai']:
|
1047 |
+
st.success("🎉 ถูกต้อง!")
|
1048 |
+
st.write(f"ตัวอย่างประโยค: {word['example_en']}")
|
1049 |
+
st.write(f"แปล: {word['example_th']}")
|
1050 |
+
else:
|
1051 |
+
st.error("❌ ลองใหม่อีกครั้ง")
|
1052 |
+
|
1053 |
+
return vocab_data.get(theme_id, {}).get(level, [])
|
1054 |
|
1055 |
# Add to session state initialization
|
1056 |
def init_theme_state():
|
|
|
1784 |
on_click=submit_story
|
1785 |
)
|
1786 |
|
1787 |
+
|
1788 |
with col2:
|
1789 |
+
# 1. Feedback Section (Most Important)
|
1790 |
if st.session_state.feedback:
|
1791 |
st.markdown("""
|
1792 |
+
<div class="feedback-box">
|
1793 |
+
<div class="thai-eng">
|
1794 |
+
<div class="thai">📝 คำแนะนำจากครู</div>
|
1795 |
+
<div class="eng">Writing Feedback</div>
|
1796 |
+
</div>
|
1797 |
</div>
|
1798 |
""", unsafe_allow_html=True)
|
1799 |
|
|
|
1844 |
</p>
|
1845 |
</div>
|
1846 |
""", unsafe_allow_html=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1847 |
|
1848 |
+
# 2. Writing Tools (Expandable)
|
1849 |
+
with st.expander("✨ เครื่องมือช่วยเขียน | Writing Tools"):
|
1850 |
+
if st.button("🎯 ขอคำใบ้ | Get Creative Prompt"):
|
1851 |
+
prompt = get_creative_prompt()
|
1852 |
+
st.markdown(f"""
|
1853 |
+
<div class="thai-eng">
|
1854 |
+
<div class="thai">💭 {prompt['thai']}</div>
|
1855 |
+
<div class="eng">💭 {prompt['eng']}</div>
|
1856 |
+
</div>
|
1857 |
+
""", unsafe_allow_html=True)
|
1858 |
+
|
1859 |
+
# Vocabulary ย้ายมาอยู่ในนี้
|
1860 |
+
if st.button("📚 คำศัพท์แนะนำ | Vocabulary Tips"):
|
1861 |
+
vocab_suggestions = get_vocabulary_suggestions()
|
1862 |
+
st.markdown("#### 📚 คำศัพท์น่ารู้ | Useful Words")
|
1863 |
+
for word in vocab_suggestions:
|
1864 |
+
st.markdown(f"• {word}")
|
1865 |
+
|
1866 |
+
# 3. Achievements (Expandable)
|
1867 |
+
with st.expander("🏆 ความสำเร็จ | Achievements"):
|
1868 |
+
show_achievements()
|
1869 |
+
|
1870 |
+
# 4. Save Options (At the bottom)
|
1871 |
+
st.markdown("### 💾 บันทึกเรื่องราว")
|
1872 |
if st.session_state.story:
|
|
|
1873 |
col1, col2 = st.columns(2)
|
1874 |
|
1875 |
with col1:
|
1876 |
# บันทึกเป็น PDF
|
1877 |
pdf = create_story_pdf()
|
1878 |
st.download_button(
|
1879 |
+
label="📑 PDF",
|
1880 |
data=pdf,
|
1881 |
file_name=f"my_story_{datetime.now().strftime('%Y%m%d')}.pdf",
|
1882 |
mime="application/pdf"
|
1883 |
)
|
1884 |
|
1885 |
with col2:
|
1886 |
+
# บันทึกความก้าวหน้า
|
1887 |
story_data = {
|
1888 |
'level': st.session_state.level,
|
1889 |
'date': datetime.now().isoformat(),
|
1890 |
'story': st.session_state.story,
|
1891 |
'achievements': st.session_state.achievements,
|
1892 |
'points': st.session_state.points,
|
1893 |
+
'stats': st.session_state.stats
|
|
|
|
|
|
|
|
|
|
|
1894 |
}
|
1895 |
st.download_button(
|
1896 |
+
label="💾 Save",
|
1897 |
data=json.dumps(story_data, indent=2),
|
1898 |
file_name=f"story_progress_{datetime.now().strftime('%Y%m%d')}.json",
|
1899 |
mime="application/json"
|
1900 |
+
)
|
1901 |
+
|
1902 |
+
# Add new CSS for improved layout
|
1903 |
+
st.markdown("""
|
1904 |
+
<style>
|
1905 |
+
.feedback-box {
|
1906 |
+
margin-bottom: 20px;
|
1907 |
+
}
|
1908 |
+
.expander-box {
|
1909 |
+
margin-top: 10px;
|
1910 |
+
}
|
1911 |
+
.save-options {
|
1912 |
+
position: sticky;
|
1913 |
+
bottom: 0;
|
1914 |
+
background: white;
|
1915 |
+
padding: 10px 0;
|
1916 |
+
border-top: 1px solid #eee;
|
1917 |
+
}
|
1918 |
+
</style>
|
1919 |
+
""", unsafe_allow_html=True)
|