quyk67uet commited on
Commit
4a93bef
·
1 Parent(s): a5da9eb
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ images/*.jpg filter=lfs diff=lfs merge=lfs -text
37
+ images/*.png filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ .env
2
+ __pycache__/
3
+ *.pyc
4
+ *.pyo
5
+ *.pyd
6
+ *.pyw
7
+ *.pyz
8
+ math/
README.md CHANGED
@@ -1,19 +1,129 @@
1
- ---
2
- title: Mmqa Chatbot
3
- emoji: 🚀
4
- colorFrom: red
5
- colorTo: red
6
- sdk: docker
7
- app_port: 8501
8
- tags:
9
- - streamlit
10
- pinned: false
11
- short_description: Streamlit template space
12
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
- # Welcome to Streamlit!
15
 
16
- Edit `/src/streamlit_app.py` to customize this app to your heart's desire. :heart:
 
 
 
17
 
18
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
19
- forums](https://discuss.streamlit.io).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🤖 Chatbot Gia sư Toán AI Đa Agent
2
+
3
+ Một ứng dụng chatbot thông minh sử dụng kiến trúc đa agent để hỗ trợ học sinh lớp 9 học Toán theo chương trình Việt Nam.
4
+
5
+ ## 🎯 Tính năng chính
6
+
7
+ ### 5 Agent thông minh:
8
+ 1. **Informer Agent**: Giải bài toán dựa trên sách giáo khoa (RAG)
9
+ 2. **Practice Agent**: Tạo bài tập và đề xuất video phù hợp
10
+ 3. **Insight Agent**: Phân tích điểm yếu và cảm xúc học sinh
11
+ 4. **Verifier Agent**: Kiểm tra tính đúng đắn của câu trả lời
12
+ 5. **Tutor Agent**: Điều phối các agent và quản lý hội thoại
13
+
14
+ ### Các luồng tương tác:
15
+ - ✅ **Giải toán chi tiết**: Trả lời từng bước với kiểm tra chéo
16
+ - 🎯 **Luyện tập chủ động**: Tự động đề xuất bài tập dựa trên điểm yếu
17
+ - 💚 **Hỗ trợ cảm xúc**: Nhận biết stress và phản hồi đồng cảm
18
+ - 🚫 **Từ chối an toàn**: Chỉ tập trung vào toán học
19
+
20
+ ## 🛠️ Thiết lập
21
+
22
+ ### 1. Cài đặt dependencies
23
+ ```bash
24
+ pip install -r requirements.txt
25
+ ```
26
+
27
+ ### 2. Thiết lập Google AI API Key
28
+ ```bash
29
+ export GOOGLE_API_KEY="your_api_key_here"
30
+ ```
31
+
32
+ Hoặc trên Windows:
33
+ ```cmd
34
+ set GOOGLE_API_KEY=your_api_key_here
35
+ ```
36
+
37
+ ### 3. Chuẩn bị dữ liệu
38
+ Đảm bảo có 2 file trong thư mục gốc:
39
+ - `embedded_documents.pkl`: Documents sách giáo khoa đã được embedding
40
+ - `videos.json`: Danh sách thông tin video bài giảng
41
+
42
+ ### 4. Chạy ứng dụng
43
+ ```bash
44
+ streamlit run app.py
45
+ ```
46
+
47
+ ## 📚 Cấu trúc hệ thống
48
+
49
+ ### Kiến trúc Multi-Agent
50
+ ```
51
+ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
52
+ │ Tutor │────│ Informer │────│ Verifier │
53
+ │ Agent │ │ Agent │ │ Agent │
54
+ │ (Điều phối) │ │ (RAG) │ │ (Kiểm tra) │
55
+ └─────────────┘ └─────────────┘ └─────────────┘
56
+ │ │
57
+ ▼ ▼
58
+ ┌─────────────┐ ┌─────────────┐
59
+ │ Practice │ │ Insight │
60
+ │ Agent │ │ Agent │
61
+ │(Tạo bài tập)│ │(Phân tích) │
62
+ └─────────────┘ └─────────────┘
63
+ ```
64
+
65
+ ### Luồng xử lý
66
+ 1. **Phân loại ý định** → Xác định loại câu hỏi
67
+ 2. **Điều phối agent** → Gọi agent phù hợp
68
+ 3. **Xử lý và kiểm tra** → Tạo câu trả lời + verification
69
+ 4. **Phân tích chủ động** → Đề xuất bài tập theo điểm yếu
70
+
71
+ ## 🎮 Cách sử dụng
72
 
73
+ ### Các loại câu hỏi được hỗ trợ:
74
 
75
+ 1. **Câu hỏi toán học**:
76
+ - "Giải phương trình x + 5 = 10"
77
+ - "Tính diện tích hình tròn bán kính 3cm"
78
+ - "Chứng minh định lý Pythagore"
79
 
80
+ 2. **Yêu cầu luyện tập**:
81
+ - "Cho tôi bài tập về phương trình"
82
+ - "Tôi muốn luyện tập thêm"
83
+
84
+ 3. **Biểu đạt stress**:
85
+ - "Tôi mệt quá"
86
+ - "Khó hiểu quá"
87
+ - "Không làm được"
88
+
89
+ 4. **Câu hỏi ngoài chuyên môn**:
90
+ - Hệ thống sẽ từ chối và hướng về toán học
91
+
92
+ ## 🔧 Công nghệ sử dụng
93
+
94
+ - **Framework**: Haystack-AI 2.x
95
+ - **LLM**: Google Gemini 1.5 Pro
96
+ - **Embedding**: Vietnamese BI-Encoder
97
+ - **UI**: Streamlit + Streamlit-Chat
98
+ - **Vector Store**: InMemoryDocumentStore
99
+
100
+ ## 📊 Tối ưu hóa
101
+
102
+ ### Caching thông minh:
103
+ - `@st.cache_resource` cho việc tải models
104
+ - Session state cho lịch sử chat
105
+ - Embedding được cache tự động
106
+
107
+ ### Memory Management:
108
+ - Giới hạn lịch sử chat (10 tin nhắn gần nhất)
109
+ - Lazy loading cho các component
110
+
111
+ ## 🤝 Đóng góp
112
+
113
+ Dự án này là case study cho AIQAM'25 Workshop. Nếu bạn muốn đóng góp:
114
+
115
+ 1. Fork repository
116
+ 2. Tạo feature branch
117
+ 3. Commit changes
118
+ 4. Push và tạo Pull Request
119
+
120
+ ## 📄 License
121
+
122
+ MIT License - Chi tiết xem file LICENSE
123
+
124
+ ## 🎓 Tác giả
125
+
126
+ Dự án được phát triển cho Workshop AIQAM'25 về Interactive QA Systems.
127
+
128
+ ---
129
+ **Lưu ý**: Cần thiết lập Google AI API key để sử dụng. Tham khảo [Google AI Studio](https://makersuite.google.com/app/apikey) để lấy key.
app.py ADDED
@@ -0,0 +1,1275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from altair import Bin
2
+ from numpy import tri
3
+ import streamlit as st
4
+ import pickle
5
+ import json
6
+ import os
7
+ import random
8
+ import time
9
+ import re
10
+ import hashlib
11
+ from typing import List, Dict, Any
12
+ from streamlit_chat import message
13
+ from dotenv import load_dotenv
14
+ from datetime import datetime
15
+ from supabase_utils import init_supabase_client, update_user_profile, get_user_profile
16
+ from supabase import Client
17
+ from sympy import Rem
18
+ from PIL import Image
19
+ import io
20
+ from faster_whisper import WhisperModel
21
+ from st_audiorec import st_audiorec
22
+ import tempfile
23
+
24
+ load_dotenv()
25
+
26
+ # Haystack imports
27
+ from haystack import Pipeline, Document
28
+ from haystack.document_stores.in_memory import InMemoryDocumentStore
29
+ from haystack.components.retrievers.in_memory import InMemoryBM25Retriever, InMemoryEmbeddingRetriever
30
+ from haystack.components.builders import PromptBuilder
31
+ from haystack.components.embedders import SentenceTransformersDocumentEmbedder, SentenceTransformersTextEmbedder
32
+
33
+ # Google AI integration - Custom Component
34
+ import google.generativeai as genai
35
+ from haystack import component, default_from_dict, default_to_dict
36
+
37
+ @component
38
+ class CustomGoogleAIGenerator:
39
+ """
40
+ Một component Haystack tùy chỉnh để gọi trực tiếp API Gemini của Google.
41
+ """
42
+ def __init__(self, api_key: str, model_name: str = "gemini-1.5-pro"):
43
+ self.api_key = api_key
44
+ self.model_name = model_name
45
+ genai.configure(api_key=self.api_key)
46
+
47
+ self.safety_settings = [
48
+ {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
49
+ {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
50
+ {"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_NONE"},
51
+ {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_NONE"},
52
+ ]
53
+
54
+ self.generation_config = genai.types.GenerationConfig(
55
+ temperature=0.2,
56
+ max_output_tokens=1024
57
+ )
58
+
59
+ self.model = genai.GenerativeModel(
60
+ self.model_name,
61
+ generation_config=self.generation_config,
62
+ safety_settings=self.safety_settings
63
+ )
64
+
65
+
66
+ def to_dict(self):
67
+ return default_to_dict(self, api_key=self.api_key, model_name=self.model_name)
68
+
69
+ @classmethod
70
+ def from_dict(cls, data):
71
+ return default_from_dict(cls, data)
72
+
73
+ @component.output_types(replies=List[str])
74
+ def run(self, prompt_parts: List[Any]):
75
+ """
76
+ Gửi một prompt đa phương thức (văn bản và hình ảnh) đến API Gemini.
77
+ """
78
+ try:
79
+ processed_parts = []
80
+ for part in prompt_parts:
81
+ if isinstance(part, bytes):
82
+ try:
83
+ img = Image.open(io.BytesIO(part))
84
+ processed_parts.append(img)
85
+ except Exception as e:
86
+ print(f"Lỗi khi xử lý ảnh: {e}")
87
+ else:
88
+ processed_parts.append(part)
89
+
90
+ response = self.model.generate_content(processed_parts)
91
+ print(f"DEBUG: [Generator] Raw response from Gemini: {response.text}")
92
+ return {"replies": [response.text]}
93
+ except Exception as e:
94
+ print(f"ERROR: [Generator] Lỗi trong lúc gọi API: {e}")
95
+ return {"replies": [f"Xin lỗi, đã có lỗi xảy ra khi kết nối với mô hình AI."]}
96
+
97
+ st.set_page_config(
98
+ page_title="AI Math Tutor",
99
+ page_icon="🤖",
100
+ layout="wide",
101
+ initial_sidebar_state="expanded",
102
+ menu_items={
103
+ 'About': "Gia sư Toán AI thông minh cho học sinh lớp 9"
104
+ }
105
+ )
106
+
107
+ st.markdown("""
108
+ <style>
109
+ /* Hide Streamlit branding */
110
+ #MainMenu {visibility: hidden;}
111
+ footer {visibility: hidden;}
112
+ header {visibility: hidden;}
113
+
114
+ /* Main app styling */
115
+ .main {
116
+ padding: 1rem;
117
+ }
118
+
119
+ /* Chat container */
120
+ .chat-container {
121
+ max-height: 600px;
122
+ overflow-y: auto;
123
+ padding: 1rem;
124
+ border-radius: 15px;
125
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
126
+ margin-bottom: 1rem;
127
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
128
+ }
129
+
130
+ /* User message */
131
+ .user-message {
132
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
133
+ color: white;
134
+ padding: 12px 16px;
135
+ border-radius: 18px 18px 4px 18px;
136
+ margin: 8px 0;
137
+ margin-left: 20%;
138
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
139
+ animation: slideInRight 0.3s ease-out;
140
+ }
141
+
142
+ /* Bot message */
143
+ .bot-message {
144
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
145
+ color: white;
146
+ padding: 12px 16px;
147
+ border-radius: 18px 18px 18px 4px;
148
+ margin: 8px 0;
149
+ margin-right: 20%;
150
+ box-shadow: 0 4px 12px rgba(240, 147, 251, 0.3);
151
+ animation: slideInLeft 0.3s ease-out;
152
+ }
153
+
154
+ /* Animations */
155
+ @keyframes slideInRight {
156
+ from { transform: translateX(100%); opacity: 0; }
157
+ to { transform: translateX(0); opacity: 1; }
158
+ }
159
+
160
+ @keyframes slideInLeft {
161
+ from { transform: translateX(-100%); opacity: 0; }
162
+ to { transform: translateX(0); opacity: 1; }
163
+ }
164
+
165
+ @keyframes pulse {
166
+ 0%, 100% { transform: scale(1); }
167
+ 50% { transform: scale(1.05); }
168
+ }
169
+
170
+ /* Typing indicator */
171
+ .typing-indicator {
172
+ display: flex;
173
+ align-items: center;
174
+ padding: 12px 16px;
175
+ background: rgba(255,255,255,0.1);
176
+ border-radius: 18px;
177
+ margin: 8px 0;
178
+ margin-right: 20%;
179
+ animation: pulse 2s infinite;
180
+ }
181
+
182
+ .typing-dots {
183
+ display: flex;
184
+ gap: 4px;
185
+ }
186
+
187
+ .typing-dot {
188
+ width: 8px;
189
+ height: 8px;
190
+ border-radius: 50%;
191
+ background: white;
192
+ animation: typingDots 1.5s infinite;
193
+ }
194
+
195
+ .typing-dot:nth-child(2) { animation-delay: 0.3s; }
196
+ .typing-dot:nth-child(3) { animation-delay: 0.6s; }
197
+
198
+ @keyframes typingDots {
199
+ 0%, 60%, 100% { opacity: 0.3; }
200
+ 30% { opacity: 1; }
201
+ }
202
+
203
+ /* Sidebar styling */
204
+ .sidebar .sidebar-content {
205
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
206
+ border-radius: 15px;
207
+ padding: 1rem;
208
+ margin: 1rem 0;
209
+ }
210
+
211
+ /* Input styling */
212
+ .stTextInput > div > div > input {
213
+ border-radius: 25px;
214
+ border: 2px solid #667eea;
215
+ padding: 12px 20px;
216
+ font-size: 16px;
217
+ transition: all 0.3s ease;
218
+ }
219
+
220
+ .stTextInput > div > div > input:focus {
221
+ border-color: #f093fb;
222
+ box-shadow: 0 0 20px rgba(240, 147, 251, 0.3);
223
+ }
224
+
225
+ /* Button styling */
226
+ .stButton > button {
227
+ border-radius: 25px;
228
+ border: none;
229
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
230
+ color: white;
231
+ padding: 12px 24px;
232
+ font-weight: 600;
233
+ transition: all 0.3s ease;
234
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
235
+ }
236
+
237
+ .stButton > button:hover {
238
+ transform: translateY(-2px);
239
+ box-shadow: 0 6px 16px rgba(102, 126, 234, 0.4);
240
+ }
241
+
242
+ /* Welcome message */
243
+ .welcome-message {
244
+ text-align: center;
245
+ padding: 2rem;
246
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
247
+ border-radius: 20px;
248
+ color: white;
249
+ margin: 2rem 0;
250
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
251
+ }
252
+
253
+ /* Feature cards */
254
+ .feature-card {
255
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
256
+ border-radius: 15px;
257
+ padding: 1.5rem;
258
+ margin: 1rem 0;
259
+ color: white;
260
+ box-shadow: 0 4px 12px rgba(240, 147, 251, 0.3);
261
+ transition: transform 0.3s ease;
262
+ }
263
+
264
+ .feature-card:hover {
265
+ transform: translateY(-5px);
266
+ }
267
+
268
+ /* Status indicators */
269
+ .status-online {
270
+ color: #4ade80;
271
+ font-weight: 600;
272
+ }
273
+
274
+ .status-thinking {
275
+ color: #fbbf24;
276
+ font-weight: 600;
277
+ }
278
+
279
+ /* Math expression styling */
280
+ .math-expression {
281
+ background: rgba(255,255,255,0.1);
282
+ padding: 8px 12px;
283
+ border-radius: 8px;
284
+ font-family: 'Courier New', monospace;
285
+ margin: 4px 0;
286
+ }
287
+ </style>
288
+ """, unsafe_allow_html=True)
289
+
290
+ # Kiểm tra API key
291
+ if "GOOGLE_API_KEY" not in os.environ:
292
+ st.error("⚠️ Không tìm thấy API key. Vui lòng cấu hình biến môi trường.")
293
+ st.stop()
294
+
295
+ @st.cache_resource
296
+ def load_resources():
297
+ """Load và khởi tạo tất cả tài nguyên của hệ thống"""
298
+
299
+ # Load documents
300
+ try:
301
+ with open("embedded_documents.pkl", "rb") as f:
302
+ documents = pickle.load(f)
303
+ except FileNotFoundError:
304
+ st.error("❌ Không tìm thấy dữ liệu học liệu")
305
+ st.stop()
306
+
307
+ # Load videos
308
+ try:
309
+ with open("videos.json", "r", encoding="utf-8") as f:
310
+ videos_data = json.load(f)
311
+ except FileNotFoundError:
312
+ st.error("❌ Không tìm thấy dữ liệu video")
313
+ st.stop()
314
+
315
+ # Initialize document store
316
+ document_store = InMemoryDocumentStore()
317
+ document_store.write_documents(documents)
318
+
319
+ # Initialize components
320
+ retriever = InMemoryEmbeddingRetriever(document_store=document_store)
321
+ text_embedder = SentenceTransformersTextEmbedder(
322
+ model="bkai-foundation-models/vietnamese-bi-encoder"
323
+ )
324
+
325
+ print("DEBUG: Loading Faster Whisper model...")
326
+ model_size = "small"
327
+
328
+ # Chạy trên CPU với INT8 để tối ưu
329
+ whisper_model = WhisperModel(model_size, device="cpu", compute_type="int8")
330
+
331
+ print(f"DEBUG: Faster Whisper model '{model_size}' loaded successfully.")
332
+
333
+ # Templates
334
+ informer_template = """
335
+ Bạn là một Gia sư Toán AI chuyên nghiệp. Vai trò của bạn là cung cấp một lời giải hoặc một lời giải thích chi tiết, chính xác và dễ hiểu cho học sinh lớp 9.
336
+
337
+ **QUY TRÌNH CỦA BẠN:**
338
+ 1. **Đọc Lịch sử Trò chuyện:** Hiểu rõ bối cảnh và câu hỏi trước đó của học sinh.
339
+ 2. **Nghiên cứu Tài liệu:** Tham khảo kỹ các thông tin từ sách giáo khoa được cung cấp.
340
+ 3. **Trả lời câu hỏi cuối cùng:** Dựa vào cả lịch sử và tài liệu, hãy trả lời câu hỏi cuối cùng của học sinh.
341
+
342
+ **YÊU CẦU TRÌNH BÀY:**
343
+ - Sử dụng ngôn ngữ sư phạm, rõ ràng, từng bước một.
344
+ - Sử dụng Markdown để định dạng các công thức toán học, các đề mục và nhấn mạnh các điểm quan trọng.
345
+ - Luôn trả lời bằng tiếng Việt.
346
+
347
+ ---
348
+ **LỊCH SỬ TRÒ CHUYỆN GẦN ĐÂY:**
349
+ {{ conversation_history }}
350
+ ---
351
+ **THÔNG TIN SÁCH GIÁO KHOA (TỪ RAG):**
352
+ {% for doc in documents %}
353
+ {{ doc.content }}
354
+ {% endfor %}
355
+ ---
356
+
357
+ **Câu hỏi cuối cùng của học sinh:** {{ query }}
358
+
359
+ **Lời giải chi tiết của bạn:**
360
+ """
361
+
362
+ practice_template = """
363
+ Bạn là một chuyên gia ra đề thi và tư vấn học liệu môn Toán.
364
+
365
+ **NHIỆM VỤ:**
366
+ Dựa trên **chủ đề yếu** của học sinh và **danh sách video** được cung cấp, hãy thực hiện 2 việc:
367
+
368
+ 1. **Tạo 2 Bài tập Mới:**
369
+ - Các bài tập phải liên quan trực tiếp đến chủ đề yếu.
370
+ - Độ khó tương đương chương trình lớp 9.
371
+ - Bài tập phải hoàn toàn mới, không được trùng lặp với các ví dụ phổ biến.
372
+ 2. **Đề xuất 1 Video Phù hợp nhất:**
373
+ - Chọn ra MỘT video từ danh sách có nội dung liên quan chặt chẽ nhất đến chủ đề yếu.
374
+
375
+ **THÔNG TIN ĐẦU VÀO:**
376
+ - **Chủ đề yếu của học sinh:** '{{ student_weakness }}'
377
+ - **Danh sách video có sẵn (JSON):** {{ video_cheatsheet_json }}
378
+
379
+ **YÊU CẦU OUTPUT:**
380
+ Chỉ trả lời theo định dạng Markdown dưới đây, không thêm bất kỳ lời dẫn hay giải thích nào khác.
381
+
382
+ ### 🎯 BÀI TẬP CỦNG CỐ
383
+ 1. **Bài 1:** [Nội dung câu hỏi bài tập 1]
384
+ 2. **Bài 2:** [Nội dung câu hỏi bài tập 2]
385
+
386
+
387
+ ### 📹 VIDEO ĐỀ XUẤT
388
+ **[Tên video]**
389
+ 🎬 Link: https://www.youtube.com/playlist?list=PL5q2T2FxzK7XY4s9FqDi6KCFEpGr2LX2D"""
390
+
391
+ insight_template = """
392
+ Bạn là một chuyên gia phân tích giáo dục. Nhiệm vụ của bạn là đọc kỹ đoạn hội thoại và xác định chính xác những khái niệm toán học mà học sinh đang hiểu sai.
393
+
394
+ **HƯỚNG DẪN:**
395
+ - Đọc kỹ toàn bộ hội thoại.
396
+ - Tập trung vào những câu hỏi hoặc nhận định của 'User' thể hiện sự nhầm lẫn hoặc thiếu kiến thức.
397
+ - Dựa trên sự nhầm lẫn đó, xác định khái niệm toán học cốt lõi bị hiểu sai.
398
+ - Chỉ trả lời bằng một đối tượng JSON duy nhất theo định dạng sau. Không thêm bất kỳ giải thích hay văn bản nào khác.
399
+
400
+ **VÍ DỤ:**
401
+ ---
402
+ Hội thoại:
403
+ User: hệ thức Vi-ét dùng để làm gì?
404
+ Assistant: ...
405
+ User: vậy nếu phương trình vô nghiệm thì vẫn tính tổng và tích các nghiệm được đúng không?
406
+ ---
407
+ JSON Output:
408
+ {"misunderstood_concepts": ["điều kiện áp dụng hệ thức Vi-ét"], "sentiment": "confused"}
409
+ ---
410
+
411
+ **BÂY GIỜ, HÃY PHÂN TÍCH HỘI THOẠI SAU:**
412
+
413
+ **Hội thoại:**
414
+ {{ conversation_history }}
415
+
416
+ **JSON Output:**
417
+ """
418
+
419
+ verifier_template = """Bin là một người kiểm định chất lượng toán học cực kỳ khó tính và chính xác.
420
+ Nhiệm vụ của bạn là kiểm tra xem lời giải được đề xuất có hoàn toàn đúng về mặt toán học và logic hay không.
421
+
422
+ **Câu hỏi của học sinh:** {{ query }}
423
+
424
+ **Lời giải được đề xuất:** {{ informer_answer }}
425
+
426
+ **YÊU CẦU:**
427
+ Hãy kiểm tra từng bước, từng công thức và kết quả cuối cùng. Sau đó, chỉ trả lời bằng một đối tượng JSON duy nhất theo định dạng sau.
428
+
429
+ **JSON Output:**
430
+ {"is_correct": [true hoặc false], "correction_suggestion": "[Nếu sai, hãy giải thích ngắn gọn và chính xác lỗi sai nằm ở đâu. Nếu đúng, để trống chuỗi này.]"}
431
+ """
432
+
433
+ intent_template = """
434
+ Bạn là một hệ thống phân loại ý định cực kỳ chính xác. Dựa vào câu hỏi cuối cùng của người dùng, hãy phân loại nó vào MỘT trong các loại sau.
435
+
436
+ **ĐỊNH NGHĨA CÁC LOẠI:**
437
+ - 'greeting_social': Chào hỏi, xã giao, cảm ơn, tạm biệt.
438
+ - 'math_question': Bất kỳ câu hỏi nào liên quan trực tiếp đến kiến thức toán học, bao gồm giải bài tập, tính toán, hỏi định nghĩa, hỏi công thức, hỏi tính chất.
439
+ - 'request_for_practice': Yêu cầu bài tập luyện tập, muốn thực hành.
440
+ - 'expression_of_stress': Biểu hiện căng thẳng, mệt mỏi, nản lòng.
441
+ - 'study_support': Hỏi về phương pháp học chung, cách để tiến bộ, tìm kiếm động lực.
442
+ - 'off_topic': Chủ đề hoàn toàn không liên quan đến học tập.
443
+
444
+ **VÍ DỤ:**
445
+ ---
446
+ User: Chào bạn
447
+ Phân loại: greeting_social
448
+ ---
449
+ User: Giải giúp mình phương trình x^2 + 5x - 6 = 0
450
+ Phân loại: math_question
451
+ ---
452
+ User: hệ thức Vi-ét dùng để làm gì? <-- VÍ DỤ MỚI QUAN TRỌNG
453
+ Phân loại: math_question
454
+ ---
455
+ User: Bài này khó quá, mình nản thật
456
+ Phân loại: expression_of_stress
457
+ ---
458
+ User: Có bài nào tương tự để mình luyện tập thêm không?
459
+ Phân loại: request_for_practice
460
+ ---
461
+ User: Làm sao để học tốt môn hình học không gian?
462
+ Phân loại: study_support
463
+ ---
464
+ User: Giá vàng hôm nay bao nhiêu?
465
+ Phân loại: off_topic
466
+ ---
467
+
468
+ **Bây giờ, hãy phân loại lịch sử chat sau. Chỉ trả về MỘT từ duy nhất.**
469
+
470
+ **Lịch sử chat:**
471
+ {{ conversation_history }}
472
+
473
+ **Phân loại:**
474
+ """
475
+
476
+ # --- TEMPLATES CHO TUTOR AGENT ---
477
+
478
+ # Prompt tổng quát định hình vai trò và tính cách
479
+ tutor_master_prompt = """
480
+ Bạn là một Gia sư Toán AI, một người bạn đồng hành học tập thông minh, thấu cảm và chuyên nghiệp.
481
+ Vai trò của bạn là phản hồi lại học sinh một cách phù hợp nhất dựa trên ý định của họ.
482
+ Luôn sử dụng ngôn ngữ tích cực, khuyến khích và thân thiện. Luôn trả lời bằng tiếng Việt.
483
+ """
484
+
485
+ # Prompt cho intent 'greeting_social'
486
+ greeting_template = """
487
+ {{ master_prompt }}
488
+
489
+ **Bối cảnh:** Học sinh đang bắt đầu cuộc trò chuyện hoặc nói những câu xã giao (chào hỏi, cảm ơn).
490
+ **Nhiệm vụ:** Hãy phản hồi lại một cách thân thiện, tự nhiên và mời gọi họ bắt đầu buổi học.
491
+
492
+ **Lịch sử chat gần đây:**
493
+ {{ conversation_history }}
494
+
495
+ **Lời chào thân thiện của bạn:**
496
+ """
497
+
498
+ # Prompt cho intent 'expression_of_stress'
499
+ stress_template = """
500
+ {{ master_prompt }}
501
+
502
+ **Bối cảnh:** Học sinh đang thể hiện sự căng thẳng, mệt mỏi hoặc nản lòng về việc học.
503
+ **NHIỆM VỤ CỰC KỲ QUAN TRỌNG:**
504
+ 1. **Đồng cảm:** Thể hiện rằng bạn hiểu cảm giác của họ.
505
+ 2. **Bình thường hóa:** Cho họ biết rằng cảm giác này là bình thường.
506
+ 3. **Gợi ý giải pháp AN TOÀN:** Đề xuất những hành động đơn giản như nghỉ ngơi, hít thở sâu.
507
+ 4. **TUYỆT ĐỐI KHÔNG:** Đóng vai chuyên gia tâm lý, không đưa ra lời khuyên phức tạp.
508
+
509
+ **Lịch sử chat gần đây:**
510
+ {{ conversation_history }}
511
+
512
+ **Lời động viên an toàn và thấu cảm của bạn:**
513
+ """
514
+
515
+ # Prompt cho intent 'study_support'
516
+ support_template = """
517
+ {{ master_prompt }}
518
+
519
+ **Bối cảnh:** Học sinh đang hỏi về phương pháp học tập, cách để tiến bộ hoặc tìm kiếm động lực.
520
+ **Nhiệm vụ:** Hãy đưa ra những lời khuyên chung, hữu ích và mang tính động viên về việc học Toán. Bạn có thể gợi ý về các chức năng của mình (giải bài tập, tạo luyện tập,...).
521
+
522
+ **Lịch sử chat gần đây:**
523
+ {{ conversation_history }}
524
+
525
+ **Lời khuyên và hỗ trợ của bạn:**
526
+ """
527
+
528
+ # Prompt cho intent 'off_topic'
529
+ off_topic_template = """
530
+ {{ master_prompt }}
531
+
532
+ **Bối cảnh:** Học sinh đang hỏi một câu hoàn toàn không liên quan đến toán học hoặc học tập.
533
+ **Nhiệm vụ:** Hãy lịch sự từ chối trả lời và nhẹ nhàng hướng cuộc trò chuyện quay trở lại chủ đề chính là học Toán.
534
+
535
+ **Lịch sử chat gần đây:**
536
+ {{ conversation_history }}
537
+
538
+ **Lời từ chối khéo léo của bạn:**
539
+ """
540
+
541
+ # Create prompt builders
542
+ informer_prompt_builder = PromptBuilder(template=informer_template, required_variables=["documents", "query", "conversation_history"])
543
+ practice_prompt_builder = PromptBuilder(template=practice_template, required_variables=["student_weakness", "video_cheatsheet_json"])
544
+ insight_prompt_builder = PromptBuilder(template=insight_template, required_variables=["conversation_history"])
545
+ verifier_prompt_builder = PromptBuilder(template=verifier_template, required_variables=["query", "informer_answer"])
546
+ intent_prompt_builder = PromptBuilder(template=intent_template, required_variables=["conversation_history"])
547
+
548
+ greeting_prompt_builder = PromptBuilder(template=greeting_template, required_variables=["master_prompt", "conversation_history"])
549
+ stress_prompt_builder = PromptBuilder(template=stress_template, required_variables=["master_prompt", "conversation_history"])
550
+ support_prompt_builder = PromptBuilder(template=support_template, required_variables=["master_prompt", "conversation_history"])
551
+ off_topic_prompt_builder = PromptBuilder(template=off_topic_template, required_variables=["master_prompt", "conversation_history"])
552
+
553
+ # Create generator
554
+ generator = CustomGoogleAIGenerator(api_key=os.getenv("GOOGLE_API_KEY"))
555
+
556
+ return {
557
+ "informer_prompt_builder": informer_prompt_builder,
558
+ "generator": generator,
559
+ "practice_prompt_builder": practice_prompt_builder,
560
+ "insight_prompt_builder": insight_prompt_builder,
561
+ "verifier_prompt_builder": verifier_prompt_builder,
562
+ "intent_prompt_builder": intent_prompt_builder,
563
+ "videos_data": videos_data,
564
+ "document_store": document_store,
565
+ "tutor_master_prompt": tutor_master_prompt,
566
+ "greeting_prompt_builder": greeting_prompt_builder,
567
+ "stress_prompt_builder": stress_prompt_builder,
568
+ "support_prompt_builder": support_prompt_builder,
569
+ "off_topic_prompt_builder": off_topic_prompt_builder,
570
+ "retriever": retriever,
571
+ "text_embedder": text_embedder,
572
+ "whisper_model": whisper_model
573
+ }
574
+
575
+ def transcribe_audio(audio_bytes: bytes, whisper_model: WhisperModel) -> str:
576
+ """
577
+ Nhận dữ liệu audio bytes, lưu vào file tạm, chuyển đổi thành văn bản bằng Faster Whisper.
578
+ Phiên bản này đã sửa lỗi Permission Denied trên Windows.
579
+ """
580
+ if not audio_bytes:
581
+ return ""
582
+
583
+ tmp_file_path = ""
584
+ try:
585
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmpfile:
586
+ tmpfile.write(audio_bytes)
587
+ tmp_file_path = tmpfile.name
588
+
589
+ print(f"DEBUG: [Whisper] Audio saved to temp file: {tmp_file_path}")
590
+
591
+ print(f"DEBUG: [Whisper] Transcribing audio from: {tmp_file_path}")
592
+ segments, info = whisper_model.transcribe(tmp_file_path, beam_size=5, language="vi")
593
+
594
+ print(f"DEBUG: [Whisper] Detected language: {info.language} with probability {info.language_probability}")
595
+
596
+ transcribed_text = " ".join(segment.text for segment in segments)
597
+ print(f"DEBUG: [Whisper] Transcribed text: '{transcribed_text}'")
598
+ return transcribed_text.strip()
599
+
600
+ except Exception as e:
601
+ st.error(f"Lỗi khi xử lý giọng nói: {e}")
602
+ return ""
603
+ finally:
604
+ if tmp_file_path and os.path.exists(tmp_file_path):
605
+ os.remove(tmp_file_path)
606
+ print(f"DEBUG: [Whisper] Cleaned up temp file: {tmp_file_path}")
607
+
608
+
609
+ def classify_intent(conversation_history: str, resources: Dict) -> str:
610
+ """Phân loại ý định người dùng"""
611
+ valid_intents = ['greeting_social', 'math_question', 'request_for_practice', 'expression_of_stress', 'study_support', 'off_topic']
612
+
613
+ try:
614
+ prompt_builder = resources["intent_prompt_builder"]
615
+
616
+ prompt_text = prompt_builder.run(conversation_history=conversation_history)["prompt"]
617
+
618
+ result = resources["generator"].run(prompt_parts=[prompt_text])
619
+ intent = result["replies"][0].strip().lower()
620
+
621
+ user_input_debug = "N/A"
622
+ if 'User: ' in conversation_history:
623
+ lines = conversation_history.split('\n')
624
+ for line in reversed(lines):
625
+ if line.strip().startswith('User: '):
626
+ user_input_debug = line.replace('User: ', '').strip()
627
+ break
628
+
629
+ print(f"DEBUG - User input: {user_input_debug}")
630
+ print(f"DEBUG - Classified intent: {intent}")
631
+ print(f"DEBUG - Conversation history format: {conversation_history[:200]}...")
632
+
633
+ if intent not in valid_intents:
634
+ math_keywords = ['giải', 'tính', 'phương trình', 'bài tập', 'toán', 'xác suất', 'thống kê', 'hình học', 'đại số']
635
+
636
+ user_input_for_fallback = "N/A"
637
+ if 'User: ' in conversation_history:
638
+ lines = conversation_history.split('\n')
639
+ for line in reversed(lines):
640
+ if line.strip().startswith('User: '):
641
+ user_input_for_fallback = line.replace('User: ', '').strip()
642
+ break
643
+
644
+ if any(keyword in user_input_for_fallback.lower() for keyword in math_keywords):
645
+ intent = 'math_question'
646
+ else:
647
+ intent = 'greeting_social'
648
+
649
+ return intent
650
+ except Exception as e:
651
+ print(f"DEBUG - Intent classification error: {e}")
652
+ return 'greeting_social'
653
+
654
+ def informer_agent(query: str, conversation_history_str: str, resources: Dict) -> str:
655
+ """Agent giải toán dựa trên RAG"""
656
+ try:
657
+ result = resources["informer_pipeline"].run({
658
+ "text_embedder": {"text": query},
659
+ "prompt_builder": {"query": query, "conversation_history": conversation_history_str}
660
+ })
661
+ return result["generator"]["replies"][0]
662
+ except:
663
+ return "Xin lỗi, tôi không thể giải bài này lúc này."
664
+
665
+ def verifier_agent(query: str, informer_answer: str, resources: Dict) -> Dict:
666
+ """Agent kiểm tra tính đúng đắn"""
667
+ try:
668
+ prompt_text = resources["verifier_prompt_builder"].run(query=query, informer_answer=informer_answer)["prompt"]
669
+ result = resources["generator"].run(prompt_parts=[prompt_text])
670
+ llm_reply_string = result["replies"][0]
671
+
672
+ json_match = re.search(r"\{.*\}", llm_reply_string, re.DOTALL)
673
+ if json_match:
674
+ return json.loads(json_match.group(0))
675
+ else:
676
+ return {"is_correct": True, "correction_suggestion": "Lỗi parse verifier"}
677
+ except Exception as e:
678
+ print(f"ERROR: [Verifier Agent] Lỗi: {e}")
679
+ return {"is_correct": True, "correction_suggestion": ""}
680
+
681
+ def insight_agent(conversation_history: str, resources: Dict) -> Dict:
682
+ """Agent phân tích điểm yếu, với logic trích xuất JSON thông minh."""
683
+ try:
684
+ prompt_builder = resources["insight_prompt_builder"]
685
+ prompt_text = prompt_builder.run(conversation_history=conversation_history)["prompt"]
686
+
687
+ print("\n" + "="*50)
688
+ print("DEBUG: [Insight Agent] PROMPT CUỐI CÙNG GỬI ĐẾN GEMINI:")
689
+ print(prompt_text)
690
+ print("="*50 + "\n")
691
+
692
+ result = resources["generator"].run(prompt_parts=[prompt_text])
693
+ llm_reply = result["replies"][0]
694
+
695
+ json_match = re.search(r"\{.*\}", llm_reply, re.DOTALL)
696
+
697
+ if json_match:
698
+ json_string = json_match.group(0)
699
+ print(f"DEBUG: [Insight Agent] Đã trích xuất chuỗi JSON: {json_string}")
700
+ return json.loads(json_string)
701
+ else:
702
+ print(f"ERROR: [Insight Agent] Không tìm thấy chuỗi JSON hợp lệ trong phản hồi của LLM: {llm_reply}")
703
+ return {"misunderstood_concepts": [], "sentiment": "neutral"}
704
+
705
+ except json.JSONDecodeError as e:
706
+ print(f"ERROR: [Insight Agent] Lỗi khi parse JSON đã trích xuất: {e}")
707
+ return {"misunderstood_concepts": [], "sentiment": "neutral"}
708
+ except Exception as e:
709
+ print(f"ERROR: [Insight Agent] Đã xảy ra lỗi không xác định: {e}")
710
+ return {"misunderstood_concepts": [], "sentiment": "neutral"}
711
+
712
+ def practice_agent(student_weakness: str, resources: Dict) -> str:
713
+ """Agent tạo bài tập"""
714
+ try:
715
+ video_cheatsheet = []
716
+ for video in resources["videos_data"]:
717
+ video_cheatsheet.append({
718
+ "title": video["title"],
719
+ "keywords": video["keywords"],
720
+ "summary": video["summary_for_llm"]
721
+ })
722
+
723
+ video_json = json.dumps(video_cheatsheet, ensure_ascii=False)
724
+ prompt_text = resources["practice_prompt_builder"].run(
725
+ student_weakness=student_weakness,
726
+ video_cheatsheet_json=video_json
727
+ )["prompt"]
728
+
729
+ result = resources["generator"].run(prompt_parts=[prompt_text])
730
+ return result["replies"][0]
731
+ except:
732
+ return "Xin lỗi, tôi không thể tạo bài tập lúc này."
733
+
734
+ def problem_solving_engine(
735
+ query_text: str,
736
+ query_image: bytes,
737
+ conversation_history_str: str,
738
+ resources: Dict
739
+ ) -> str:
740
+ """
741
+ Cỗ máy giải quyết vấn đề đa năng, TÁI SỬ DỤNG informer_prompt_builder.
742
+ """
743
+ print("DEBUG: Multimodal Problem-Solving Engine activated.")
744
+
745
+ try:
746
+ extracted_text_from_image = ""
747
+ if query_image:
748
+ print("DEBUG: [Stage 1] Image detected. Calling Gemini for OCR...")
749
+ try:
750
+ ocr_prompt_parts = [
751
+ "Bạn là một hệ thống OCR toán học siêu chính xác. Hãy đọc và trích xuất toàn bộ văn bản từ hình ảnh sau đây. Chỉ trả về phần văn bản được trích xuất.",
752
+ query_image
753
+ ]
754
+ ocr_result = resources["generator"].run(prompt_parts=ocr_prompt_parts)
755
+ extracted_text_from_image = ocr_result["replies"][0]
756
+ print(f"DEBUG: [Stage 1] Text extracted from image: '{extracted_text_from_image}'")
757
+ except Exception as e:
758
+ print(f"ERROR: [Stage 1] OCR failed: {e}")
759
+ extracted_text_from_image = "Không thể đọc được nội dung từ hình ảnh."
760
+
761
+ full_query_text = (query_text + " " + extracted_text_from_image).strip()
762
+ print(f"DEBUG: [Stage 1.5] Full query text: '{full_query_text}'")
763
+
764
+ context_docs = []
765
+ if full_query_text:
766
+ try:
767
+ print("DEBUG: [Stage 2] Starting RAG retrieval...")
768
+ embedding = resources["text_embedder"].run(text=full_query_text)["embedding"]
769
+ print("DEBUG: [Stage 2] Embedding created successfully")
770
+ context_docs = resources["retriever"].run(query_embedding=embedding)["documents"]
771
+ print(f"DEBUG: [Stage 2] Retrieved {len(context_docs)} documents")
772
+ except Exception as e:
773
+ print(f"ERROR: [Stage 2] RAG retrieval failed: {e}")
774
+ context_docs = []
775
+
776
+ print("DEBUG: [Stage 3] Building final prompt...")
777
+
778
+ try:
779
+ informer_prompt_builder = resources["informer_prompt_builder"]
780
+ print("DEBUG: [Stage 3a] Got informer_prompt_builder")
781
+
782
+ text_prompt_result = informer_prompt_builder.run(
783
+ query=query_text if query_text else "Giải bài toán trong hình.",
784
+ conversation_history=conversation_history_str,
785
+ documents=context_docs
786
+ )
787
+ print("DEBUG: [Stage 3a] Prompt builder ran successfully")
788
+
789
+ text_part = text_prompt_result["prompt"]
790
+ print(f"DEBUG: [Stage 3a] Generated text prompt length: {len(text_part)} chars")
791
+
792
+ except Exception as e:
793
+ print(f"ERROR: [Stage 3a] Prompt building failed: {e}")
794
+ # Fallback to simple prompt
795
+ text_part = f"""Bạn là gia sư toán AI. Hãy giải bài toán sau:
796
+
797
+ Câu hỏi: {query_text if query_text else "Giải bài toán trong hình"}
798
+ Nội dung từ hình: {extracted_text_from_image}
799
+
800
+ Lịch sử: {conversation_history_str}
801
+
802
+ Hãy trả lời chi tiết bằng tiếng Việt:"""
803
+
804
+ final_prompt_parts = [text_part]
805
+
806
+ if query_image:
807
+ final_prompt_parts.append("\n**Hình ảnh đính kèm:**")
808
+ final_prompt_parts.append(query_image)
809
+
810
+ print(f"DEBUG: [Stage 3b] Final prompt parts count: {len(final_prompt_parts)}")
811
+
812
+ print("DEBUG: [Stage 4] Calling Gemini for final answer...")
813
+ try:
814
+ final_result = resources["generator"].run(prompt_parts=final_prompt_parts)
815
+ informer_answer = final_result["replies"][0]
816
+ print(f"DEBUG: [Stage 4] Got answer, length: {len(informer_answer)} chars")
817
+ except Exception as e:
818
+ print(f"ERROR: [Stage 4] Gemini call failed: {e}")
819
+ return f"Xin lỗi, tôi không thể xử lý câu hỏi này lúc này. Lỗi: {str(e)}"
820
+
821
+ try:
822
+ print("DEBUG: [Stage 5] Starting verification...")
823
+ verification_query = full_query_text if full_query_text else "Phân tích bài toán trong hình ảnh"
824
+ verification = verifier_agent(verification_query, informer_answer, resources)
825
+ print(f"DEBUG: [Stage 5] Verification result: {verification}")
826
+
827
+ if verification.get("is_correct", True):
828
+ return informer_answer
829
+ else:
830
+ correction = verification.get("correction_suggestion", "")
831
+ return f"🔍 Tôi đã xem xét lại và thấy có một chút chưa chính xác. {correction}"
832
+ except Exception as e:
833
+ print(f"ERROR: [Stage 5] Verification failed: {e}")
834
+ return informer_answer
835
+
836
+ except Exception as e:
837
+ print(f"ERROR: [Problem-Solving Engine] Critical error: {str(e)}")
838
+ import traceback
839
+ print(f"ERROR: [Problem-Solving Engine] Traceback: {traceback.format_exc()}")
840
+ return f"Xin lỗi, đã có lỗi nghiêm trọng khi xử lý yêu cầu: {str(e)}"
841
+
842
+
843
+ def tutor_agent_response(user_input: str, intent: str, conversation_history_str: str, resources: Dict, supabase: Client, user_id: str, display_name: str) -> str:
844
+ """
845
+ Agent chính, bây giờ CHỈ xử lý các intent giao tiếp.
846
+ Các câu hỏi toán học đã được xử lý bởi problem_solving_engine.
847
+ """
848
+ print(f"DEBUG: Tutor Agent is handling a communication intent: '{intent}'")
849
+
850
+ if intent == "greeting_social":
851
+ prompt_builder = resources["greeting_prompt_builder"]
852
+ elif intent == "expression_of_stress":
853
+ prompt_builder = resources["stress_prompt_builder"]
854
+ elif intent == "study_support":
855
+ prompt_builder = resources["support_prompt_builder"]
856
+ elif intent == "request_for_practice":
857
+ print("DEBUG: Tutor Agent is triggering the Practice Flow.")
858
+ insights = insight_agent(conversation_history_str, resources)
859
+ if insights and insights.get("misunderstood_concepts"):
860
+ weakness = insights["misunderstood_concepts"][0]
861
+ return practice_agent(weakness, resources)
862
+ else:
863
+ return practice_agent("các chủ đề toán lớp 9 tổng quát", resources)
864
+ else:
865
+ prompt_builder = resources["off_topic_prompt_builder"]
866
+
867
+ try:
868
+ prompt_text = prompt_builder.run(
869
+ master_prompt=resources["tutor_master_prompt"],
870
+ conversation_history=conversation_history_str
871
+ )["prompt"]
872
+
873
+ result = resources["generator"].run(prompt_parts=[prompt_text])
874
+ return result["replies"][0]
875
+ except Exception as e:
876
+ print(f"ERROR: Could not generate response for intent '{intent}': {e}")
877
+ return "Rất xin lỗi, tôi đang gặp một chút sự cố."
878
+
879
+ def render_chat_message(content: str, is_user: bool, key: str, image: bytes = None):
880
+ """Render tin nhắn chat, có thể kèm ảnh."""
881
+ css_class = "user-message" if is_user else "bot-message"
882
+
883
+ if image:
884
+ st.image(image, width=250)
885
+
886
+ if content:
887
+ st.markdown(f'<div class="{css_class}">{content}</div>', unsafe_allow_html=True)
888
+
889
+ def should_trigger_proactive_practice(conversation_history: List[Dict[str, str]]) -> bool:
890
+ """
891
+ Kiểm tra xem có nên kích hoạt luồng luyện tập chủ động không
892
+ bằng cách đếm số lượng intent 'math_question' đã được lưu.
893
+ """
894
+ print("\n--- DEBUG: [should_trigger_proactive_practice] Bắt đầu kiểm tra điều kiện ---")
895
+
896
+ if len(conversation_history) < 6:
897
+ print("DEBUG: Kích hoạt = False. Lý do: Lịch sử chat quá ngắn.")
898
+ return False
899
+
900
+ user_intents = [msg['intent'] for msg in conversation_history if msg['role'] == 'user'][-3:]
901
+
902
+ if len(user_intents) < 3:
903
+ print("DEBUG: Kích hoạt = False. Lý do: Không có đủ 3 lượt tương tác từ người dùng.")
904
+ return False
905
+
906
+ print(f"DEBUG: Phân tích 3 intent gần nhất của người dùng: {user_intents}")
907
+
908
+ math_question_count = user_intents.count('math_question')
909
+
910
+ should_trigger = math_question_count >= 2
911
+
912
+ print(f"DEBUG: Tổng số intent 'math_question': {math_question_count}/3.")
913
+ print(f"DEBUG: Kích hoạt = {should_trigger}.")
914
+ print("--- KẾT THÚC KIỂM TRA ---")
915
+
916
+ return should_trigger
917
+
918
+
919
+ def show_typing_indicator():
920
+ """Hiển thị indicator khi bot đang suy nghĩ"""
921
+ return st.markdown('''
922
+ <div class="typing-indicator">
923
+ <span style="margin-right: 10px;">🤖 Đang suy nghĩ ...</span>
924
+ <div class="typing-dots">
925
+ <div class="typing-dot"></div>
926
+ <div class="typing-dot"></div>
927
+ <div class="typing-dot"></div>
928
+ </div>
929
+ </div>
930
+ ''', unsafe_allow_html=True)
931
+
932
+ def handle_modern_auth(supabase: Client):
933
+ """Xử lý authentication với UI hiện đại"""
934
+
935
+ # Kiểm tra session
936
+ try:
937
+ session = supabase.auth.get_session()
938
+ if session and session.user and session.user.email_confirmed_at:
939
+ if "user" not in st.session_state:
940
+ st.session_state.user = session.user
941
+ except:
942
+ if "user" in st.session_state:
943
+ del st.session_state.user
944
+
945
+ # Nếu chưa đăng nhập
946
+ if "user" not in st.session_state or st.session_state.user is None:
947
+
948
+ # Welcome message
949
+ st.markdown('''
950
+ <div class="welcome-message">
951
+ <h1>🤖 Chào mừng đến với Gia sư AI</h1>
952
+ <p style="font-size: 1.2em; margin: 1rem 0;">
953
+ Hệ thống gia sư Toán thông minh với 5 AI Agent chuyên nghiệp
954
+ </p>
955
+ <p style="opacity: 0.9;">
956
+ Đăng nhập để bắt đầu hành trình học tập cá nhân hóa
957
+ </p>
958
+ </div>
959
+ ''', unsafe_allow_html=True)
960
+
961
+ # Auth tabs
962
+ tab1, tab2 = st.tabs(["🔑 Đăng nhập", "📝 Đăng ký"])
963
+
964
+ with tab1:
965
+ with st.form("login_form"):
966
+ st.subheader("Đăng nhập tài khoản")
967
+ email = st.text_input("📧 Email", placeholder="[email protected]")
968
+ password = st.text_input("🔒 Mật khẩu", type="password")
969
+ login_btn = st.form_submit_button("Đăng nhập", use_container_width=True)
970
+
971
+ if login_btn:
972
+ if email and password:
973
+ try:
974
+ response = supabase.auth.sign_in_with_password({"email": email, "password": password})
975
+ if response.user and response.user.email_confirmed_at:
976
+ st.session_state.user = response.user
977
+ st.success("✅ Đăng nhập thành công!")
978
+ time.sleep(1)
979
+ st.rerun()
980
+ else:
981
+ st.warning("⚠️ Vui lòng xác thực email trước khi đăng nhập!")
982
+ except Exception as e:
983
+ if "invalid login credentials" in str(e).lower():
984
+ st.error("❌ Email hoặc mật khẩu không đúng")
985
+ else:
986
+ st.error(f"❌ Lỗi đăng nhập: {str(e)}")
987
+ else:
988
+ st.warning("⚠️ Vui lòng nhập đầy đủ thông tin")
989
+
990
+ with tab2:
991
+ with st.form("register_form"):
992
+ st.subheader("Tạo tài khoản mới")
993
+ display_name = st.text_input("👤 Tên của bạn", placeholder="Nguyễn Văn A")
994
+ new_email = st.text_input("📧 Email", placeholder="[email protected]")
995
+ new_password = st.text_input("🔒 Mật khẩu", type="password")
996
+ register_btn = st.form_submit_button("Đăng ký", use_container_width=True)
997
+
998
+ if register_btn:
999
+ if display_name and new_email and new_password:
1000
+ try:
1001
+ # --- THAY ĐỔI 3: GỬI KÈM TÊN TRONG OPTIONS ---
1002
+ response = supabase.auth.sign_up({
1003
+ "email": new_email,
1004
+ "password": new_password,
1005
+ "options": {
1006
+ "data": {
1007
+ "display_name": display_name
1008
+ }
1009
+ }
1010
+ })
1011
+ if response.user:
1012
+ st.success("🎉 Đăng ký thành công!")
1013
+ st.info("📧 Vui lòng kiểm tra email để xác thực tài khoản")
1014
+ except Exception as e:
1015
+ if "already registered" in str(e).lower():
1016
+ st.error("❌ Email đã được đăng ký")
1017
+ else:
1018
+ st.error(f"❌ Lỗi đăng ký: {str(e)}")
1019
+ else:
1020
+ st.warning("⚠️ Vui lòng nhập đầy đủ Tên, Email và Mật khẩu")
1021
+
1022
+ # Feature showcase
1023
+ st.subheader("🚀 Tính năng nổi bật")
1024
+
1025
+ col1, col2 = st.columns(2)
1026
+
1027
+ with col1:
1028
+ st.markdown('''
1029
+ <div class="feature-card">
1030
+ <h3>🧠 5 AI Agent thông minh</h3>
1031
+ <p>Hệ thống đa tác nhân chuyên nghiệp cho trải nghiệm học tập tối ưu</p>
1032
+ </div>
1033
+ ''', unsafe_allow_html=True)
1034
+
1035
+ st.markdown('''
1036
+ <div class="feature-card">
1037
+ <h3>📚 Dựa trên SGK chính thức</h3>
1038
+ <p>Nội dung chuẩn theo chương trình Toán lớp 9</p>
1039
+ </div>
1040
+ ''', unsafe_allow_html=True)
1041
+
1042
+ with col2:
1043
+ st.markdown('''
1044
+ <div class="feature-card">
1045
+ <h3>🎯 Học tập cá nhân hóa</h3>
1046
+ <p>Phân tích điểm yếu và đề xuất bài tập phù hợp</p>
1047
+ </div>
1048
+ ''', unsafe_allow_html=True)
1049
+
1050
+ st.markdown('''
1051
+ <div class="feature-card">
1052
+ <h3>🎥 Video bài giảng</h3>
1053
+ <p>Kho video phong phú với lời giải chi tiết</p>
1054
+ </div>
1055
+ ''', unsafe_allow_html=True)
1056
+
1057
+ return False
1058
+
1059
+ return True
1060
+
1061
+ def main():
1062
+ """Hàm chính của ứng dụng"""
1063
+
1064
+ # Khởi tạo Supabase
1065
+ supabase = init_supabase_client()
1066
+
1067
+ if not handle_modern_auth(supabase):
1068
+ return
1069
+
1070
+ # Nếu đã đăng nhập, lấy thông tin user
1071
+ user = st.session_state.user
1072
+ user_id = user.id
1073
+
1074
+ display_name = user.user_metadata.get("display_name", user.email)
1075
+
1076
+ with st.spinner("🚀 Đang khởi tạo hệ thống AI..."):
1077
+ resources = load_resources()
1078
+
1079
+ # --- Giao diện chính sau khi đăng nhập ---
1080
+
1081
+ # Header
1082
+ st.markdown(f'''
1083
+ <div style="text-align: center; padding: 1rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 15px; margin-bottom: 1rem; color: white; box-shadow: 0 8px 32px rgba(0,0,0,0.1);">
1084
+ <h1>🤖 Gia sư Toán AI</h1>
1085
+ <p class="status-online">● Online - Sẵn sàng hỗ trợ {display_name}</p>
1086
+ </div>
1087
+ ''', unsafe_allow_html=True)
1088
+
1089
+ # Khởi tạo session state cho cuộc trò chuyện
1090
+ if "messages" not in st.session_state:
1091
+ st.session_state.messages = []
1092
+ # Thêm tin nhắn chào mừng đầu tiên
1093
+ welcome_msg = "Xin chào! Tôi là gia sư AI của bạn 😊. Hôm nay chúng ta cùng học Toán nhé!"
1094
+ st.session_state.messages.append({"role": "assistant", "content": welcome_msg, "intent": "greeting_social"})
1095
+
1096
+ # Container để chứa các tin nhắn chat
1097
+ chat_placeholder = st.container()
1098
+ with chat_placeholder:
1099
+ for i, msg_data in enumerate(st.session_state.messages):
1100
+ is_user = msg_data["role"] == "user"
1101
+ # Sử dụng hàm render tùy chỉnh
1102
+ render_chat_message(msg_data["content"], is_user, key=f"msg_{i}")
1103
+
1104
+
1105
+ st.markdown("#### Hoặc nói chuyện trực tiếp với gia sư:")
1106
+ audio_bytes = st_audiorec() # Component ghi âm
1107
+
1108
+ # Khởi tạo session state để theo dõi audio đã xử lý
1109
+ if "processed_audio_hash" not in st.session_state:
1110
+ st.session_state.processed_audio_hash = None
1111
+
1112
+ # 2. Form Nhập liệu cho Text và Ảnh
1113
+ with st.form(key="chat_form", clear_on_submit=True):
1114
+ # Chia layout
1115
+ col1, col2 = st.columns([1, 4])
1116
+ with col1:
1117
+ uploaded_image = st.file_uploader("Đính kèm ảnh", type=["png", "jpg", "jpeg"], label_visibility="collapsed")
1118
+ with col2:
1119
+ user_text = st.text_input("Nhập câu hỏi của bạn...", placeholder="Nhập câu hỏi hoặc mô tả cho ảnh...", label_visibility="collapsed")
1120
+
1121
+ submit_button = st.form_submit_button(label="Gửi")
1122
+
1123
+
1124
+ final_user_text = ""
1125
+ final_image_data = None
1126
+
1127
+ current_audio_hash = None
1128
+ is_new_audio = False
1129
+
1130
+ if audio_bytes and len(audio_bytes) > 0:
1131
+ current_audio_hash = hashlib.md5(audio_bytes).hexdigest()
1132
+ is_new_audio = current_audio_hash != st.session_state.processed_audio_hash
1133
+
1134
+ if is_new_audio and audio_bytes:
1135
+ with st.spinner("🎧 Đang xử lý giọng nói..."):
1136
+ transcribed_text = transcribe_audio(audio_bytes, resources["whisper_model"])
1137
+ if transcribed_text and transcribed_text.strip() and len(transcribed_text.strip()) > 1:
1138
+ final_user_text = transcribed_text
1139
+ st.session_state.processed_audio_hash = current_audio_hash
1140
+ else:
1141
+ st.session_state.processed_audio_hash = current_audio_hash
1142
+
1143
+ elif submit_button:
1144
+ final_user_text = user_text
1145
+ if uploaded_image:
1146
+ final_image_data = uploaded_image.getvalue()
1147
+
1148
+ if final_user_text or final_image_data:
1149
+
1150
+ st.session_state.messages.append({
1151
+ "role": "user",
1152
+ "content": final_user_text,
1153
+ "image": final_image_data,
1154
+ "intent": "unknown"
1155
+ })
1156
+ with chat_placeholder:
1157
+ render_chat_message(final_user_text, is_user=True, image=final_image_data, key=f"user_{len(st.session_state.messages)}")
1158
+
1159
+ history_str_for_llm = "\n".join([f"{msg['role'].capitalize()}: {msg['content']}" for msg in st.session_state.messages[-10:] if msg['content']])
1160
+ detected_intent = classify_intent(history_str_for_llm, resources)
1161
+ st.session_state.messages[-1]["intent"] = detected_intent
1162
+
1163
+ with chat_placeholder:
1164
+ typing_indicator_placeholder = show_typing_indicator()
1165
+
1166
+ if final_image_data or detected_intent == "math_question":
1167
+ bot_response = problem_solving_engine(
1168
+ query_text=final_user_text,
1169
+ query_image=final_image_data,
1170
+ conversation_history_str=history_str_for_llm,
1171
+ resources=resources
1172
+ )
1173
+ else:
1174
+ bot_response = tutor_agent_response(
1175
+ user_input=final_user_text,
1176
+ intent=detected_intent,
1177
+ conversation_history_str=history_str_for_llm,
1178
+ resources=resources,
1179
+ supabase=supabase,
1180
+ user_id=user_id,
1181
+ display_name=display_name
1182
+ )
1183
+
1184
+ typing_indicator_placeholder.empty()
1185
+
1186
+ st.session_state.messages.append({"role": "assistant", "content": bot_response, "intent": detected_intent, "image": None})
1187
+ with chat_placeholder:
1188
+ render_chat_message(bot_response, is_user=False, key=f"bot_{len(st.session_state.messages)}")
1189
+
1190
+ if should_trigger_proactive_practice(st.session_state.messages):
1191
+
1192
+ with chat_placeholder:
1193
+ proactive_typing_placeholder = show_typing_indicator()
1194
+
1195
+ try:
1196
+ print("\n--- DEBUG: [Proactive Flow] Bắt đầu luồng phân tích và đề xuất ---")
1197
+
1198
+ history_str_for_insight = "\n".join([f"{msg['role'].capitalize()}: {msg['content']}" for msg in st.session_state.messages[-10:]])
1199
+
1200
+ # Gọi Insight Agent
1201
+ print("DEBUG: [Proactive Flow] Gọi Insight Agent...")
1202
+ insights = insight_agent(history_str_for_insight, resources)
1203
+ print(f"DEBUG: [Proactive Flow] Insight Agent trả về: {insights}")
1204
+
1205
+ if insights and isinstance(insights, dict) and insights.get("misunderstood_concepts"):
1206
+
1207
+ current_profile = get_user_profile(supabase, user_id)
1208
+
1209
+ old_concepts = current_profile.get("misunderstood_concepts", []) if current_profile else []
1210
+
1211
+ new_concepts = insights["misunderstood_concepts"]
1212
+
1213
+ combined_concepts_set = set(old_concepts) | set(new_concepts)
1214
+ updated_concepts = list(combined_concepts_set)
1215
+
1216
+ last_weakness = new_concepts[0] if new_concepts else (old_concepts[0] if old_concepts else None)
1217
+ user_email = user.email
1218
+
1219
+ profile_data_to_save = {
1220
+ "email": user_email,
1221
+ "misunderstood_concepts": updated_concepts,
1222
+ "last_weakness": last_weakness,
1223
+ "updated_at": datetime.now().isoformat()
1224
+ }
1225
+
1226
+ print(f"DEBUG: [Proactive Flow] Dữ liệu cập nhật (đã cộng dồn): {profile_data_to_save}")
1227
+ update_user_profile(supabase, user_id, profile_data_to_save)
1228
+
1229
+ st.toast("✅ Đã phân tích và cập nhật hồ sơ học tập!", icon="🧠")
1230
+ print(f"DEBUG: [Proactive Flow] Phát hiện điểm yếu: '{last_weakness}'. Gọi Practice Agent...")
1231
+
1232
+ practice_response = practice_agent(last_weakness, resources)
1233
+
1234
+ proactive_msg = f"💡 **Phân tích nhanh:** Dựa trên các câu hỏi vừa rồi, tôi nhận thấy bạn có thể cần luyện tập thêm về chủ đề **'{last_weakness}'**. Đây là một số gợi ý cho bạn:\n\n{practice_response}"
1235
+
1236
+ proactive_typing_placeholder.empty()
1237
+ st.session_state.messages.append({"role": "assistant", "content": proactive_msg, "intent": "proactive_suggestion"})
1238
+
1239
+ with chat_placeholder:
1240
+ render_chat_message(proactive_msg, is_user=False, key=f"proactive_{len(st.session_state.messages)}")
1241
+
1242
+ else:
1243
+ print("DEBUG: [Proactive Flow] Insight Agent không tìm thấy điểm yếu nào cụ thể. Bỏ qua đề xuất.")
1244
+ proactive_typing_placeholder.empty()
1245
+
1246
+ except Exception as e:
1247
+ print(f"ERROR: [Proactive Flow] Đã xảy ra lỗi: {str(e)}")
1248
+ proactive_typing_placeholder.empty()
1249
+
1250
+
1251
+ # Rerun để cập nhật giao diện
1252
+ st.rerun()
1253
+
1254
+ # Sidebar với thông tin khi đã đăng nhập
1255
+ with st.sidebar:
1256
+ st.header(f"👤 Chào, {display_name}")
1257
+ st.caption(f"Email: {user.email}")
1258
+
1259
+ if st.button("Đăng xuất", use_container_width=True):
1260
+ supabase.auth.sign_out()
1261
+ # Xóa các session state liên quan đến user
1262
+ keys_to_delete = ["user", "messages"]
1263
+ for key in keys_to_delete:
1264
+ if key in st.session_state:
1265
+ del st.session_state[key]
1266
+ st.success("✅ Đã đăng xuất!")
1267
+ time.sleep(1)
1268
+ st.rerun()
1269
+
1270
+ if st.button("🗑️ Xóa lịch sử chat", use_container_width=True):
1271
+ st.session_state.messages = []
1272
+ st.rerun()
1273
+
1274
+ if __name__ == "__main__":
1275
+ main()
embedded_documents.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b3d80af7ea93a573b0fd8ca5d49aa5af2808f3405e711ea6e784e733c1a38b6f
3
+ size 932258
images/informer_agent.png ADDED

Git LFS Details

  • SHA256: fb1512953302e298d336dbc8ca31c6b66bb76b6055d8809d124f18d8d607e5aa
  • Pointer size: 130 Bytes
  • Size of remote file: 19.7 kB
images/insight_agent.png ADDED

Git LFS Details

  • SHA256: 98266385c228d70a9ef3bfe6a32ea07c7f730ee979d5e5693073788f4b1166a1
  • Pointer size: 130 Bytes
  • Size of remote file: 22.4 kB
images/practice_agent.png ADDED

Git LFS Details

  • SHA256: 9efad98c557aad059009e8cbdf6e6fac2de6bbe280b64fa5bea108f8c0d58f0e
  • Pointer size: 130 Bytes
  • Size of remote file: 32.5 kB
images/system.jpg ADDED

Git LFS Details

  • SHA256: fee3cb0f8a3c692bf044be43f3b8e785cde16d384f08d4a6d43a0e8612092224
  • Pointer size: 131 Bytes
  • Size of remote file: 185 kB
images/tutor_agent.png ADDED

Git LFS Details

  • SHA256: 6bc05a770f6d81785e2b177898e72dc16136007745daefccc30419067a2dc202
  • Pointer size: 130 Bytes
  • Size of remote file: 19.9 kB
images/verifier_agent.png ADDED

Git LFS Details

  • SHA256: 163231f4a7b62040b6c89c6635dfadc0b10927fa300da5b1b04b992124eb8d7d
  • Pointer size: 130 Bytes
  • Size of remote file: 41.8 kB
math.txt ADDED
@@ -0,0 +1,1589 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Sách Giáo Khoa Toán 9 - Tập 1 (Cánh Diều)
2
+
3
+ **ĐỖ ĐỨC THÁI** (Tổng Chủ biên kiêm Chủ biên)
4
+ LÊ TUẤN ANH - ĐỖ TIẾN ĐẠT - NGUYỄN SƠN HÀ
5
+ NGUYỄN THỊ PHƯƠNG LOAN - PHẠM SỸ NAM - PHẠM ĐỨC QUANG
6
+
7
+ ---
8
+
9
+ ### Lời nói đầu
10
+
11
+ Các em học sinh lớp 9 yêu quý!
12
+
13
+ Năm học này, chúng ta lại vui mừng gặp nhau qua cuốn sách Toán 9. Sách Toán 9 tiếp tục giúp các em có thêm nhiều hiểu biết về phương trình và hệ phương trình bậc nhất, bất đẳng thức và bất phương trình bậc nhất một ẩn, căn thức, hàm số bậc hai và đồ thị (dạng đơn giản), phương trình bậc hai, một số hình khối trong thực tiễn (hình trụ, hình nón, hình cầu). Các em cũng được tìm hiểu hệ thức lượng trong tam giác vuông, đường tròn, đa giác đều, từ đó các em có thể tìm hiểu sâu sắc hơn đặc điểm của những hình phẳng quen thuộc. Ngoài ra, các em cũng được tiếp tục làm quen với thống kê và xác suất; tiến hành những hoạt động thực hành và trải nghiệm; đặc biệt về những hoạt động tài chính đơn giản; sử dụng phần mềm toán học trong thực hành tính toán và vẽ hình hình học. Qua đó giúp các em hiểu biết thêm những công cụ quan trọng của toán học trong việc giải quyết các vấn đề thực tiễn.
14
+
15
+ Năm học này cũng là năm học cuối cùng của các em cấp trung học cơ sở, sách Toán 9 sẽ giúp các em nhìn nhận lại những học vấn toán học cốt lõi những lớp trước, chuẩn bị tốt nhất cho các em bước vào cấp trung học phổ thông.
16
+
17
+ Toàn bộ những điều trên được thể hiện qua những tranh ảnh, hình vẽ, bài tập độc đáo và hấp dẫn; qua những câu chuyện lí thú về khoa học tự nhiên, về văn hóa và nghệ thuật, kiến trúc, thể thao và du lịch. Từ đó, các em được tiến thêm một bước trên con đường khám phá thế giới bí ẩn và đẹp đẽ của toán học, đặc biệt là được "làm giàu" về vốn văn hóa chung và có cơ hội "Mang cuộc sống vào bài học - Đưa bài học vào cuộc sống".
18
+
19
+ Chịu khó suy nghĩ, trao đổi với các thầy cô giáo và bạn bè, nhất định các em sẽ ngày càng tiến bộ và cảm thấy vui sướng khi nhận ra ý nghĩa: Học Toán rất có ích cho cuộc sống hằng ngày.
20
+
21
+ Chúc các em học tập thật tốt, say mê học Toán và có thêm nhiều niềm vui.
22
+
23
+ *Các tác giả*
24
+
25
+ ---
26
+
27
+ # MỤC LỤC
28
+
29
+ | Chương | Nội dung | Trang |
30
+ | :--- | :--- | :--- |
31
+ | **I** | **PHƯƠง TRÌNH VÀ HỆ PHƯƠNG TRÌNH BẬC NHẤT** | |
32
+ | | §1. Phương trình quy về phương trình bậc nhất một ẩn | 5 |
33
+ | | §2. Phương trình bậc nhất hai ẩn. Hệ hai phương trình bậc nhất hai ẩn | 12 |
34
+ | | §3. Giải hệ hai phương trình bậc nhất hai ẩn | 19 |
35
+ | | Bài tập cuối chương I | 26 |
36
+ | **II** | **BẤT ĐẲNG THỨC. BẤT PHƯƠNG TRÌNH BẬC NHẤT MỘT ẨN** | |
37
+ | | §1. Bất đẳng thức | 28 |
38
+ | | §2. Bất phương trình bậc nhất một ẩn | 35 |
39
+ | | Bài tập cuối chương II | 42 |
40
+ | | **HOẠT ĐỘNG THỰC HÀNH VÀ TRẢI NGHIỆM** (Chủ đề 1. Làm quen với bảo hiểm) | |
41
+ | **III** | **CĂN THỨC** | |
42
+ | | §1. Căn bậc hai và căn bậc ba của số thực | 48 |
43
+ | | §2. Một số phép tính về căn bậc hai của số thực | 55 |
44
+ | | §3. Căn thức bậc hai và căn thức bậc ba của biểu thức đại số | 61 |
45
+ | | §4. Một số phép biến đổi căn thức bậc hai của biểu thức đại số | 67 |
46
+ | | Bài tập cuối chương III | 72 |
47
+ | **IV** | **HỆ THỨC LƯỢNG TRONG TAM GIÁC VUÔNG** | |
48
+ | | §1. Tỉ số lượng giác của góc nhọn | 74 |
49
+ | | §2. Một số hệ thức về cạnh và góc trong tam giác vuông | 82 |
50
+ | | §3. Ứng dụng của tỉ số lượng giác của góc nhọn | 88 |
51
+ | | Bài tập cuối chương IV | 92 |
52
+ | **V** | **ĐƯỜNG TRÒN** | |
53
+ | | §1. Đường tròn. Vị trí tương đối của hai đường tròn | 93 |
54
+ | | §2. Vị trí tương đối của đường thẳng và đường tròn | 101 |
55
+ | | §3. Tiếp tuyến của đường tròn | 106 |
56
+ | | §4. Góc ở tâm. Góc nội tiếp | 111 |
57
+ | | §5. Độ dài cung tròn, diện tích hình quạt tròn, diện tích hình vành khuyên | 118 |
58
+ | | Bài tập cuối chương V | 124 |
59
+ | | **BẢNG GIẢI THÍCH THUẬT NGỮ** | 126 |
60
+ | | **BẢNG TRA CỨU TỪ NGỮ** | 127 |
61
+
62
+ ---
63
+
64
+ # CHƯƠNG I: PHƯƠNG TRÌNH VÀ HỆ PHƯƠNG TRÌNH BẬC NHẤT
65
+
66
+ Trong chương này, chúng ta sẽ tìm hiểu những nội dung sau: phương trình quy về phương trình bậc nhất một ẩn; phương trình và hệ hai phương tr��nh bậc nhất hai ẩn; giải hệ hai phương trình bậc nhất hai ẩn.
67
+
68
+ ## §1. PHƯƠNG TRÌNH QUY VỀ PHƯƠNG TRÌNH BẬC NHẤT MỘT ẨN
69
+
70
+ Trong một khu đất có dạng hình vuông, người ta dành một mảnh đất có dạng hình chữ nhật ở góc khu đất để làm bể bơi (Hình 1). Biết diện tích của bể bơi bằng $1250 \text{ m}^2$.
71
+
72
+ ### I. PHƯƠNG TRÌNH TÍCH CÓ DẠNG $(ax+b)(cx+d) = 0$ ($a \neq 0, c \neq 0$)
73
+
74
+ a) Cho hai số thực $u, v$ có tích $uv = 0$. Có nhận xét gì về giá trị của $u, v$?
75
+ b) Cho phương trình $(x-3)(2x+1) = 0$. Hãy giải mỗi phương trình bậc nhất sau: $x-3=0$ và $2x+1=0$.
76
+
77
+ Chứng tỏ rằng nghiệm của phương trình $x-3=0$ và nghiệm của phương trình $2x+1=0$ đều là nghiệm của phương trình $(x-3)(2x+1)=0$. Giả sử $x = x_0$ là nghiệm của phương trình $(x-3)(2x+1)=0$. Giá trị $x=x_0$ có phải là nghiệm của phương trình $x-3=0$ hoặc phương trình $2x+1=0$ hay không?
78
+
79
+ Để giải phương trình tích $(ax+b)(cx+d)=0$ với $a \neq 0$ và $c \neq 0$ ta có thể làm như sau:
80
+ * **Bước 1.** Giải hai phương trình bậc nhất: $ax+b=0$ và $cx+d=0$.
81
+ * **Bước 2.** Kết luận nghiệm: Lấy tất cả các nghiệm của hai phương trình bậc nhất vừa giải được ở Bước 1.
82
+
83
+ **Ví dụ 1** Giải phương trình: $(x+5)(3x-9)=0$.
84
+
85
+ > **Giải**
86
+ >
87
+ > Để giải phương trình đã cho, ta giải hai phương trình sau:
88
+ >
89
+ > *) $x+5=0 \implies x = -5$
90
+ >
91
+ > *) $3x-9=0 \implies 3x=9 \implies x=3$
92
+ >
93
+ > Vậy phương trình đã cho có hai nghiệm là $x=-5$ và $x=3$.
94
+
95
+ **Ví dụ 2** Giải các phương trình:
96
+ a) $(2x-3)^2 = (x+7)^2$
97
+ b) $x^2-9 = 3(x+3)$
98
+
99
+ > **Giải**
100
+ >
101
+ > a) Ta có:
102
+ > $$
103
+ > (2x-3)^2 = (x+7)^2 \\
104
+ > (2x-3)^2 - (x+7)^2 = 0 \\
105
+ > [(2x-3) - (x+7)][(2x-3) + (x+7)] = 0 \\
106
+ > (x-10)(3x+4) = 0
107
+ > $$
108
+ > Để giải phương trình trên, ta giải hai phương trình sau:
109
+ > *) $x-10=0 \implies x=10$
110
+ > *) $3x+4=0 \implies x = -\frac{4}{3}$
111
+ >
112
+ > Vậy phương trình đã cho có hai nghiệm là $x=10$ và $x=-\frac{4}{3}$.
113
+ >
114
+ > b) Ta có:
115
+ > $$
116
+ > x^2-9 = 3(x+3) \\
117
+ > (x-3)(x+3) - 3(x+3) = 0 \\
118
+ > (x+3)[(x-3)-3] = 0 \\
119
+ > (x+3)(x-6) = 0
120
+ > $$
121
+ > Để giải phương trình trên, ta giải hai phương trình sau:
122
+ > *) $x+3=0 \implies x=-3$
123
+ > *) $x-6=0 \implies x=6$
124
+ >
125
+ > Vậy phương trình đã cho có hai nghiệm là $x=-3$ và $x=6$.
126
+
127
+ **Bài tập 2** Giải các phương trình:
128
+ a) $x^2 - 10x + 25 = 5(x-5)$
129
+ b) $4x^2 - 16 = 5(x+2)$
130
+
131
+ **Ví dụ 3** Giải bài toán nêu trong phần mở đầu.
132
+
133
+ > **Giải**
134
+ >
135
+ > Gọi độ dài cạnh của khu đất có dạng hình vuông là $x$ (m) với $x>50$.
136
+ > Khi đó, mảnh đất dạng hình chữ nhật để làm bể bơi có các kích thước lần lượt là $(x-50)$ (m) và $(x-25)$ (m).
137
+ > Do đó, diện tích của mảnh đất đó là: $(x-50)(x-25) \text{ (m}^2\text{)}$.
138
+ >
139
+ > Vì vậy, ta có phương trình: $(x-50)(x-25) = 1250$.
140
+ >
141
+ > Giải phương trình:
142
+ > $$
143
+ > (x-50)(x-25) = 1250 \\
144
+ > x^2 - 25x - 50x + 1250 = 1250 \\
145
+ > x^2 - 75x = 0 \\
146
+ > x(x-75) = 0
147
+ > $$
148
+ > Suy ra $x=0$ hoặc $x=75$.
149
+ >
150
+ > Do $x>50$ nên $x=75$.
151
+ > Vậy độ dài cạnh của khu đất là $75 \text{ m}$.
152
+
153
+ ### II. PHƯƠNG TRÌNH CHỨA ẨN Ở MẪU
154
+
155
+ Cho phương trình: $\frac{x+2}{x} = \frac{x-3}{x-2}$ (1)
156
+
157
+ Tìm điều kiện của $x$ để cả hai mẫu thức có trong phương trình (1) là khác 0.
158
+
159
+ Phương trình (1) được gọi là **phương trình chứa ẩn ở mẫu**. Điều kiện $x \neq 0$ và $x \neq 2$ được gọi là **điều kiện xác định** của phương trình (1).
160
+
161
+ Trong phương trình chứa ẩn ở mẫu, điều kiện của ẩn để tất cả các mẫu thức trong phương trình đều khác 0 được gọi là **điều kiện xác định** của phương trình.
162
+
163
+ **Ví dụ 4** Tìm điều kiện xác định của mỗi phương trình sau:
164
+ a) $\frac{2x+1}{x-2} = 5$
165
+ b) $\frac{2}{5x-3} = 1 + \frac{1}{x+2}$
166
+
167
+ > **Giải**
168
+ >
169
+ > a) Điều kiện xác định của phương trình $\frac{2x+1}{x-2} = 5$ là $x-2 \neq 0$ hay $x \neq 2$.
170
+ >
171
+ > b) Điều kiện xác định của phương trình $\frac{2}{5x-3} = 1 + \frac{1}{x+2}$ là $5x-3 \neq 0$ và $x+2 \neq 0$, hay $x \neq \frac{3}{5}$ và $x \neq -2$.
172
+
173
+ **Bài tập 3** Tìm điều kiện xác định của phương trình sau: $\frac{x-8}{x-7} = 8 + \frac{1}{1-x}$.
174
+
175
+ Cho phương trình: $\frac{2x+1}{2x} = 1 - \frac{2}{x-3}$ (2)
176
+
177
+ Hãy giải phương trình (2) theo các bước sau:
178
+ a) Tìm điều kiện xác định của phương trình (2).
179
+ b) Tìm mẫu thức chung, quy đồng mẫu thức các phân thức hai vế của phương trình (2) và khử mẫu.
180
+ c) Giải phương trình vừa tìm được.
181
+ d) Kiểm tra điều kiện xác định của phương trình (2) đối với các giá trị của ẩn vừa tìm được rồi kết luận.
182
+
183
+ Để giải phương trình chứa ẩn ở mẫu, ta có thể làm như sau:
184
+ * **Bước 1.** Tìm điều kiện xác định của phương trình.
185
+ * **Bước 2.** Quy đồng mẫu thức hai vế của phương trình rồi khử mẫu.
186
+ * **Bước 3.** Giải phương trình vừa tìm được.
187
+ * **Bước 4.** Kết luận nghiệm: Trong các giá trị của ẩn tìm được ở Bước 3, các giá trị thoả mãn điều kiện xác định chính là các nghiệm của phương trình đã cho.
188
+
189
+ **Ví dụ 5** Giải các phương trình:
190
+ a) $\frac{x^2}{2-x} + \frac{3x-1}{3} = \frac{5}{3}$
191
+ b) $\frac{4}{x(x-1)} + \frac{3}{x} = \frac{4}{x-1}$
192
+
193
+ > **Giải**
194
+ >
195
+ > a) Điều kiện xác định: $2-x \neq 0$ hay $x \neq 2$.
196
+ > $$
197
+ > \frac{x^2}{2-x} + \frac{3x-1}{3} = \frac{5}{3} \\
198
+ > \frac{3x^2}{3(2-x)} + \frac{(3x-1)(2-x)}{3(2-x)} = \frac{5(2-x)}{3(2-x)}
199
+ > $$
200
+ > Khử mẫu ta được:
201
+ > $$
202
+ > 3x^2 + (6x - 3x^2 - 2 + x) = 10 - 5x \\
203
+ > 7x - 2 = 10 - 5x \\
204
+ > 12x = 12 \\
205
+ > x = 1
206
+ > $$
207
+ > Ta thấy $x=1$ thoả mãn điều kiện xác định của phương trình.
208
+ > Vậy phương trình đã cho có nghiệm $x=1$.
209
+ >
210
+ > b) Điều kiện xác định: $x \neq 0$ và $x \neq 1$.
211
+ > $$
212
+ > \frac{4}{x(x-1)} + \frac{3(x-1)}{x(x-1)} = \frac{4x}{x(x-1)}
213
+ > $$
214
+ > Khử mẫu ta được:
215
+ > $$
216
+ > 4 + 3(x-1) = 4x \\
217
+ > 4 + 3x - 3 = 4x \\
218
+ > 3x + 1 = 4x \\
219
+ > x = 1
220
+ > $$
221
+ > Ta thấy $x=1$ không thoả mãn điều kiện xác định của phương trình.
222
+ > Vậy phương trình đã cho vô nghiệm.
223
+
224
+ **Ví dụ 6** Hai bạn Phong và Khang cùng hẹn nhau đạp xe đến một địa điểm cách vị trí bạn Phong $6 \text{ km}$ và cách vị trí bạn Khang $7 \text{ km}$. Hai bạn cùng xuất phát và đến địa điểm đã hẹn cùng một lúc. Tính tốc độ của mỗi bạn, biết tốc độ của bạn Khang hơn tốc độ của bạn Phong là $2 \text{ km/h}$.
225
+
226
+ > **Giải**
227
+ >
228
+ > Gọi tốc độ của bạn Phong là $x (\text{km/h}) (x > 0)$.
229
+ > Khi đó, tốc độ của bạn Khang là $x+2 (\text{km/h})$.
230
+ > Thời gian đi của bạn Phong là $\frac{6}{x}$ (giờ).
231
+ > Thời gian đi của bạn Khang là $\frac{7}{x+2}$ (giờ).
232
+ >
233
+ > Do hai bạn cùng xuất phát và đến địa điểm đã hẹn cùng một lúc nên thời gian đi của hai bạn là như nhau. Ta có phương trình:
234
+ > $$
235
+ > \frac{6}{x} = \frac{7}{x+2}
236
+ > $$
237
+ > Giải phương trình:
238
+ > $$
239
+ > \frac{6(x+2)}{x(x+2)} = \frac{7x}{x(x+2)} \\
240
+ > 6(x+2) = 7x \\
241
+ > 6x + 12 = 7x \\
242
+ > x = 12
243
+ > $$
244
+ > Vậy tốc độ của bạn Phong là $12 \text{ km/h}$, tốc độ của bạn Khang là $14 \text{ km/h}$.
245
+
246
+ **Ví dụ 7** Biết nồng độ muối của nước biển là $3,5\%$ và khối lượng riêng của nước biển là $1020 \text{ g/l}$. Từ 2 lít nước biển như thế, người ta hòa thêm muối để được một dung dịch có nồng độ muối là $20\%$. Tính lượng muối cần hòa thêm.
247
+
248
+ > **Giải**
249
+ >
250
+ > Khối lượng của 2 lít nước biển là: $1020 \cdot 2 = 2040 \text{ (g)}$.
251
+ > Khối lượng muối trong 2 lít nước biển là: $2040 \cdot 3,5\% = 71,4 \text{ (g)}$.
252
+ >
253
+ > Gọi lượng muối cần hòa thêm vào 2 lít nước biển để được một dung dịch có nồng độ muối là $20\%$ là $x \text{ (g)} (x>0)$.
254
+ > Ta có phương trình:
255
+ > $$
256
+ > \frac{71,4 + x}{2040 + x} = \frac{20}{100}
257
+ > $$
258
+ > Giải phương trình:
259
+ > $$
260
+ > 100 \cdot (71,4 + x) = 20 \cdot (2040 + x) \\
261
+ > 7140 + 100x = 40800 + 20x \\
262
+ > 80x = 33660 \\
263
+ > x = 420,75
264
+ > $$
265
+ > Vậy cần hòa thêm $420,75 \text{ g}$ muối vào 2 lít nước biển ban đầu để được một dung dịch có nồng độ muối là $20\%$.
266
+
267
+ ### BÀI TẬP
268
+
269
+ 1. Giải các phương trình:
270
+ a) $(9x-4)(2x+5)=0$
271
+ b) $(1,3x+0,26)(0,2x-4)=0$
272
+ c) $2x(x+3) - 5(x+3) = 0$
273
+ d) $x^2 - 4 + (x+2)(2x-1) = 0$
274
+
275
+ 2. Giải các phương trình:
276
+ a) $\frac{1}{x} = \frac{5}{3(x+2)}$
277
+ b) $\frac{x}{2x-1} = \frac{x-2}{2x+5}$
278
+ c) $\frac{5x}{x-2} = 7 + \frac{10}{x-2}$
279
+ d) $\frac{x^2-6}{x} = x + \frac{3}{2}$
280
+
281
+ 3. Một ca nô đi xuôi dòng từ địa điểm A đến địa điểm B rồi lại đi ngược dòng từ địa điểm B trở về địa điểm A. Thời gian cả đi và về là 3 giờ. Tính tốc độ của dòng nước. Biết tốc độ của ca nô khi nước yên lặng là $27 \text{ km/h}$ và độ dài quãng đường AB là $40 \text{ km}$.
282
+
283
+ 4. Một doanh nghiệp sử dụng than để sản xuất sản phẩm. Doanh nghiệp đó lập kế hoạch tài chính cho việc loại bỏ chất ô nhiễm trong khí thải theo dự kiến sau: Để loại bỏ $p\%$ chất ô nhiễm trong khí thải thì chi phí $C$ (triệu đồng) được tính theo công thức: $C = \frac{80}{100-p}$ với $0 \le p < 100$.
284
+ a) Với chi phí là 20 triệu đồng thì có thể loại bỏ được bao nhiêu phần trăm chất ô nhiễm?
285
+ b) Để loại bỏ được $95\%$ chất ô nhiễm thì cần chi phí là bao nhiêu?
286
+
287
+ ---
288
+
289
+ ## §2. PHƯƠNG TRÌNH BẬC NHẤT HAI ẨN. HỆ HAI PHƯƠNG TRÌNH BẬC NHẤT HAI ẨN
290
+
291
+ ### I. PHƯƠNG TRÌNH BẬC NHẤT HAI ẨN
292
+
293
+ **Phương trình bậc nhất hai ẩn** $x, y$ là hệ thức có dạng $ax+by=c$, trong đó $a, b, c$ là những số đã cho, $a \neq 0$ hoặc $b \neq 0$.
294
+
295
+ Nếu với cặp số $(x_0; y_0)$, giá trị của biểu thức $ax+by$ tại $x=x_0, y=y_0$ bằng $c$ thì cặp số $(x_0; y_0)$ được gọi là một **nghiệm** của phương trình $ax+by=c$.
296
+
297
+ **Ví dụ 1** Trong các phương trình sau, phương trình nào là phương trình bậc nhất hai ẩn?
298
+ a) $2x-3y=5$
299
+ b) $0x+4y=8$
300
+ c) $x^2+y=1$
301
+ d) $x+y-z=0$
302
+
303
+ > **Giải**
304
+ >
305
+ > Các phương trình ở câu a, b là phương trình bậc nhất hai ẩn.
306
+ > Phương trình ở câu c không phải là phương trình bậc nhất hai ẩn vì có chứa $x^2$.
307
+ > Phương trình ở câu d không phải là phương trình bậc nhất hai ẩn vì có ba ẩn là $x, y, z$.
308
+
309
+ **Ví dụ 2** Cho phương trình $2x-3y=5$.
310
+ a) Cặp số $(1; -1)$ có phải là một nghiệm của phương trình trên không?
311
+ b) Tìm thêm hai nghiệm khác của phương trình trên.
312
+
313
+ > **Giải**
314
+ >
315
+ > a) Thay $x=1, y=-1$ vào vế trái của phương trình, ta có: $2 \cdot 1 - 3 \cdot (-1) = 5$. Vế trái bằng vế phải nên cặp số $(1; -1)$ là một nghiệm của phương trình.
316
+ > b) Hai nghiệm khác của phương trình là $(4; 1)$ và $(-2; -3)$.
317
+
318
+ **Ví dụ 3** Cô Hạnh đầu tư hai khoản tiền với tổng số vốn là 200 triệu đồng.
319
+ a) Viết phương trình bậc nhất hai ẩn $x, y$ cho hai khoản đầu tư của cô Hạnh.
320
+ b) Tìm ba nghiệm của phương trình đó.
321
+
322
+ > **Giải**
323
+ >
324
+ > a) Gọi $x$ (triệu đồng) là khoản đầu tư thứ nhất ($x>0$).
325
+ > Gọi $y$ (triệu đồng) là khoản đầu tư thứ hai ($y>0$).
326
+ > Ta có phương trình bậc nhất hai ẩn $x, y$ là: $x+y=200$.
327
+ >
328
+ > b) Ba nghiệm của phương trình trên là: $(100; 100)$, $(50; 150)$, $(120; 80)$.
329
+
330
+ ### II. HỆ HAI PHƯƠNG TRÌNH BẬC NHẤT HAI ẨN
331
+
332
+ Hai bạn Dung, Huy vào siêu thị mua vở và bút bi để ủng hộ các bạn học sinh vùng lũ lụt. Bạn Dung mua 5 quyển vở và 3 chiếc bút bi với tổng số tiền phải trả là 39 000 đồng. Bạn Huy mua 6 quyển vở và 2 chiếc bút bi với tổng số tiền phải trả là 42 000 đồng. Giả sử giá của mỗi quyển vở là $x$ đồng ($x>0$), giá của mỗi chiếc bút bi là $y$ đồng ($y>0$).
333
+
334
+ a) Viết hai phương trình bậc nhất hai ẩn $x, y$ lần lượt biểu thị tổng số tiền phải trả của bạn Dung, bạn Huy.
335
+ b) Cặp số $(x; y) = (6000; 3000)$ có phải là nghiệm của từng phương trình bậc nhất đó hay không? Vì sao?
336
+
337
+ Ta nói rằng cặp số $(x; y) = (6000; 3000)$ là một nghiệm của **hệ hai phương trình bậc nhất hai ẩn**:
338
+ $$
339
+ \begin{cases}
340
+ 5x + 3y = 39000 \\
341
+ 6x + 2y = 42000
342
+ \end{cases}
343
+ $$
344
+
345
+ **Hệ hai phương trình bậc nhất hai ẩn** có dạng:
346
+ $$
347
+ \begin{cases}
348
+ ax + by = c \\
349
+ a'x + b'y = c'
350
+ \end{cases} \quad (I)
351
+ $$
352
+ trong đó mỗi phương trình $ax+by=c$ và $a'x+b'y=c'$ đều là phương trình bậc nhất hai ẩn.
353
+
354
+ Nếu cặp số $(x_0; y_0)$ là nghiệm của từng phương trình trong hệ (I) thì cặp số $(x_0; y_0)$ được gọi là **nghiệm** của hệ (I).
355
+ **Giải hệ phương trình** là tìm tất cả các nghiệm của hệ phương trình đó.
356
+
357
+ **Ví dụ 7** Trong những trường hợp sau, hãy chỉ ra các hệ hai phương trình bậc nhất hai ẩn:
358
+ a) $\begin{cases} 2x-3y=5 \\ x+3y=-11 \end{cases}$
359
+ b) $\begin{cases} x-y=1 \\ x+y=3 \end{cases}$
360
+ c) $\begin{cases} 4x=8 \\ 2x-y=1 \end{cases}$
361
+ d) $\begin{cases} x^2+y=1 \\ x-y=2 \end{cases}$
362
+
363
+ > **Giải**
364
+ >
365
+ > Hệ phương trình ở các câu a, b, c là hệ hai phương trình bậc nhất hai ẩn.
366
+ > Trường hợp câu d không phải là hệ hai phương trình bậc nhất hai ẩn.
367
+
368
+ **Ví dụ 8** Cho hệ phương trình: $\begin{cases} 2x-3y=5 \\ x+3y=-11 \end{cases}$.
369
+ Trong các cặp số sau, cặp số nào là nghiệm của hệ phương trình đã cho?
370
+ a) $(-2; -3)$
371
+ b) $(1; -1)$
372
+
373
+ > **Giải**
374
+ >
375
+ > a) Thay giá trị $x=-2, y=-3$ vào mỗi phương trình trong hệ, ta có:
376
+ > $2 \cdot (-2) - 3 \cdot (-3) = -4 + 9 = 5$ (đúng)
377
+ > $-2 + 3 \cdot (-3) = -2 - 9 = -11$ (đúng)
378
+ > Suy ra cặp số $(-2; -3)$ là nghiệm của từng phương trình trong hệ. Do đó cặp số $(-2; -3)$ là nghiệm của hệ phương trình đã cho.
379
+ >
380
+ > b) Thay giá trị $x=1, y=-1$ vào mỗi phương trình trong hệ, ta có:
381
+ > $2 \cdot 1 - 3 \cdot (-1) = 2 + 3 = 5$ (đúng)
382
+ > $1 + 3 \cdot (-1) = 1 - 3 = -2 \neq -11$ (sai)
383
+ > Do đó, cặp số $(1; -1)$ không là nghiệm của phương trình thứ hai trong hệ.
384
+ > Vậy cặp số $(1; -1)$ không là nghiệm của hệ phương trình đã cho.
385
+
386
+ ### BÀI TẬP
387
+
388
+ 1. Trong các cặp số $(8; 1), (-3; 6), (4; -1), (0; 2)$, cho biết cặp số nào là nghiệm của mỗi phương trình sau:
389
+ a) $x - 2y = 6$
390
+ b) $x + y = 3$
391
+
392
+ 2. Cho hệ phương trình: $\begin{cases} x+2y=1 \\ 3x-2y=3 \end{cases}$.
393
+ Trong các cặp số sau, cặp số nào là nghiệm của hệ phương trình đã cho?
394
+ a) $(3; -1)$
395
+ b) $(1; 0)$
396
+
397
+ 3. Nhân dịp tết Trung thu, một doanh nghiệp dự định sản xuất hai loại bánh: bánh nướng và bánh dẻo. Lượng đường cần cho mỗi chiếc bánh nướng, bánh dẻo lần lượt là $60 \text{ g}$ và $50 \text{ g}$. Gọi $x$ và $y$ lần lượt là số lượng bánh nướng và bánh dẻo mà doanh nghiệp dự định sản xuất để lượng đường sản xuất bánh là $500 \text{ kg}$. Viết phương trình bậc nhất hai ẩn $x, y$ và chỉ ra ba nghiệm của phương trình đó.
398
+
399
+ 4. Năm bạn Châu, Hà, Khang, Minh, Phong cùng đi mua sticker để trang trí vở. Có hai loại sticker: loại I giá 2 nghìn đồng/chiếc và loại II giá 3 nghìn đồng/chiếc. Mỗi bạn mua 1 chiếc và tổng số tiền năm bạn phải trả là 12 nghìn đồng. Gọi $x$ và $y$ lần lượt là số sticker loại I và loại II mà năm bạn đã mua.
400
+ a) Viết hệ phương trình bậc nhất hai ẩn $x, y$.
401
+ b) Cặp số $(3; 2)$ có phải là nghiệm của hệ phương trình câu a hay không? Vì sao?
402
+
403
+ 5. Để chuẩn bị cho buổi liên hoan của gia đình, bác Ngọc mua hai loại thực phẩm là thịt lợn và cá chép. Giá tiền thịt lợn là 130 nghìn đồng/kg, giá tiền cá chép là 50 nghìn đồng/kg. Bác Ngọc đã chi 295 nghìn để mua $3,5 \text{ kg}$ hai loại thực phẩm trên. Gọi $x$ và $y$ lần lượt là số kilôgam thịt lợn và cá chép mà bác Ngọc đã mua.
404
+ a) Viết hệ phương trình bậc nhất hai ẩn $x, y$.
405
+ b) Cặp số $(1,5; 2)$ có phải là nghiệm của hệ phương trình ở câu a hay không? Vì sao?
406
+
407
+ 6. Người ta cần sơn hai loại sản phẩm A, B bằng hai loại sơn: sơn xanh, sơn vàng. Lượng sơn để sơn mỗi loại sản phẩm đó được cho ở Bảng 1 (đơn vị: kg/1 sản phẩm).
408
+ **Bảng 1**
409
+ | Loại sơn \ Loại sản phẩm | Sơn xanh | Sơn vàng |
410
+ | :--- | :--- | :--- |
411
+ | Sản phẩm loại A | 0,6 | 0,3 |
412
+ | Sản phẩm loại B | 0,5 | 0,4 |
413
+ Người ta dự định sử dụng $85 \text{ kg}$ sơn xanh và $50 \text{ kg}$ sơn vàng để sơn tất cả các sản phẩm của hai loại đó. Gọi $x$ và $y$ lần lượt là số sản phẩm loại A, số sản phẩm loại B được sơn.
414
+ a) Viết hệ phương trình bậc nhất hai ẩn $x, y$.
415
+ b) Cặp số $(100; 50)$ có phải là nghiệm của hệ phương trình ở câu a hay không? Vì sao?
416
+
417
+ ---
418
+
419
+ ## §3. GIẢI HỆ HAI PHƯƠNG TRÌNH BẬC NHẤT HAI ẨN
420
+
421
+ Một nhóm khách vào cửa hàng bán trà sữa. Nhóm khách đó đã mua 6 cốc trà sữa gồm trà sữa trân châu và trà sữa phô mai. Giá mỗi cốc trà sữa trân châu, trà sữa phô mai lần lượt là 33 000 đồng, 28 000 đồng. Tổng số tiền nhóm khách thanh toán cho cửa hàng là 188 000 đồng. Hỏi nhóm khách đó mua bao nhiêu cốc trà sữa mỗi loại?
422
+
423
+ ### I. GIẢI HỆ PHƯƠNG TRÌNH BẰNG PHƯƠNG PHÁP THẾ
424
+
425
+ Cho hệ phương trình: $\begin{cases} -x+y=3 \quad (1) \\ 3x+2y=11 \quad (2) \end{cases} \quad (I)$
426
+
427
+ Hãy giải hệ phương trình (I) theo các bước sau:
428
+ a) Từ phương trình (1), ta biểu diễn $y$ theo $x$ rồi thế vào phương trình (2) để được phương trình ẩn $x$.
429
+ b) Giải phương trình (ẩn $x$) vừa nhận được để tìm giá trị của $x$.
430
+ c) Thế giá trị vừa tìm được của $x$ vào biểu thức biểu diễn $y$ theo $x$ ở câu a để tìm giá trị của $y$. Từ đó, kết luận nghiệm của hệ phương trình (I).
431
+
432
+ Ta có thể giải hệ phương trình bậc nhất hai ẩn bằng **phương pháp thế** theo các bước sau:
433
+ * **Bước 1 (Thế).** Từ một phương trình của hệ đã cho, ta biểu diễn một ẩn theo ẩn kia rồi thế vào phương trình còn lại của hệ để được phương trình một ẩn.
434
+ * **Bước 2 (Giải phương trình một ẩn).** Giải phương trình (một ẩn) nhận được ở Bước 1 để tìm giá trị của ẩn đó.
435
+ * **Bước 3 (Tìm ẩn còn lại và kết luận).** Thế giá trị vừa tìm được của ẩn đó ở Bước 2 vào biểu thức biểu diễn một ẩn theo ẩn kia ở Bước 1 để tìm giá trị của ẩn còn lại. Từ đó, ta tìm được nghiệm của hệ phương trình đã cho.
436
+
437
+ **Ví dụ 1** Giải hệ phương trình: $\begin{cases} 2x+y=5 \quad (1) \\ 3x-2y=11 \quad (2) \end{cases}$
438
+
439
+ > **Giải**
440
+ >
441
+ > Từ phương trình (1), ta có: $y = 5-2x \quad (3)$.
442
+ >
443
+ > Thay vào phương trình (2), ta được: $3x - 2(5-2x) = 11 \quad (4)$.
444
+ >
445
+ > Giải phương trình (4):
446
+ > $$
447
+ > 3x - 10 + 4x = 11 \\
448
+ > 7x = 21 \\
449
+ > x = 3
450
+ > $$
451
+ > Thay giá trị $x=3$ vào phương trình (3), ta có: $y = 5 - 2 \cdot 3 = -1$.
452
+ >
453
+ > Vậy hệ phương trình đã cho có nghiệm $(x; y) = (3; -1)$.
454
+
455
+ **Ví dụ 2** Giải hệ phương trình: $\begin{cases} 3x+12y=-5 \quad (1) \\ x+4y=3 \quad (2) \end{cases}$
456
+
457
+ > **Giải**
458
+ >
459
+ > Từ phương trình (2), ta có: $x = 3-4y \quad (3)$.
460
+ >
461
+ > Thay vào phương trình (1), ta được: $3(3-4y) + 12y = -5 \quad (4)$.
462
+ >
463
+ > Giải phương trình (4):
464
+ > $$
465
+ > 9 - 12y + 12y = -5 \\
466
+ > 0y = -14
467
+ > $$
468
+ > Do đó, phương trình (4) vô nghiệm. Vậy hệ phương trình đã cho vô nghiệm.
469
+
470
+ **Ví dụ 3** Giải hệ phương trình: $\begin{cases} 12x-4y=-16 \quad (1) \\ 3x-y=-4 \quad (2) \end{cases}$
471
+
472
+ > **Giải**
473
+ >
474
+ > Từ phương trình (2), ta có: $y = 3x+4 \quad (3)$.
475
+ >
476
+ > Thay vào phương trình (1), ta được: $12x - 4(3x+4) = -16 \quad (4)$.
477
+ >
478
+ > Giải phương trình (4):
479
+ > $$
480
+ > 12x - 12x - 16 = -16 \\
481
+ > 0x = 0
482
+ > $$
483
+ > Do đó, phương trình (4) có vô số nghiệm. Vậy hệ phương trình đã cho có vô số nghiệm.
484
+ >
485
+ > *Nhận xét:* Ta có thể viết phương trình (1) về dạng: $3x-y=-4$. Do đó, hệ phương trình đã cho có thể viết về dạng: $\begin{cases} 3x-y=-4 \\ 3x-y=-4 \end{cases}$.
486
+ > Vì vậy, nghiệm của hệ phương trình đã cho cũng là nghiệm của phương trình $3x-y=-4$.
487
+ > Vậy hệ phương trình đã cho có vô số nghiệm $(x; y)$ với $x \in \mathbb{R}$ và $y=3x+4$.
488
+
489
+ **Chú ý:** Hệ phương trình bậc nhất hai ẩn có thể có nghiệm duy nhất, hoặc vô nghiệm, hoặc vô số nghiệm.
490
+
491
+ ### II. GIẢI HỆ PHƯƠNG TRÌNH BẰNG PHƯƠNG PHÁP CỘNG ĐẠI SỐ
492
+
493
+ Cho hệ phương trình: $\begin{cases} x+y=7 \quad (1) \\ x-y=1 \quad (2) \end{cases} \quad (II)$
494
+
495
+ a) Các hệ số của $y$ trong hai phương trình (1) và (2) có đặc điểm gì?
496
+ b) Cộng từng vế hai phương trình của hệ (II), ta nhận được phương trình nào?
497
+ c) Giải phương trình nhận được ở câu b. Từ đó, ta tìm được nghiệm của hệ phương trình (II).
498
+
499
+ Cách giải hệ phương trình như trên được gọi là giải hệ phương trình bằng **phương pháp cộng đại số**.
500
+
501
+ Ta có thể giải hệ phương trình bậc nhất hai ẩn bằng phương pháp cộng đại số theo các bước sau:
502
+ * **Bước 1 (Làm cho hai hệ số của một ẩn nào đó bằng nhau hoặc đối nhau).** Nhân hai vế của mỗi phương trình với một số thích hợp (nếu cần) sao cho các hệ số của một ẩn nào đó trong hai phương trình của hệ bằng nhau hoặc đối nhau.
503
+ * **Bước 2 (Đưa về phương trình một ẩn).** Cộng (hay trừ) từng vế hai phương trình của hệ phương trình nhận được ở Bước 1 để nhận được một phương trình mà hệ số của một trong hai ẩn bằng 0, tức là nhận được phương trình một ẩn. Giải phương trình một ẩn đó.
504
+ * **Bước 3 (Tìm ẩn còn lại và kết luận).** Thế giá trị vừa tìm được ở Bước 2 vào một trong hai phương trình của hệ đã cho để tìm giá trị của ẩn còn lại. Từ đó, ta tìm được nghiệm của hệ phương trình đã cho.
505
+
506
+ **Ví dụ 5** Giải hệ phương trình: $\begin{cases} 3x+2y=4 \quad (1) \\ -2x+3y=-7 \quad (2) \end{cases}$
507
+
508
+ > **Giải**
509
+ >
510
+ > Nhân hai vế của phương trình (1) với 2 và nhân hai vế của phương trình (2) với 3, ta được hệ phương trình sau:
511
+ > $\begin{cases} 6x+4y=8 \quad (3) \\ -6x+9y=-21 \quad (4) \end{cases}$
512
+ >
513
+ > Cộng từng vế hai phương trình (3) và (4), ta nhận được phương trình: $13y = -13 \implies y = -1$.
514
+ >
515
+ > Thế giá trị $y=-1$ vào phương trình (1), ta được phương trình: $3x + 2(-1) = 4$.
516
+ > Giải phương trình: $3x - 2 = 4 \implies 3x = 6 \implies x = 2$.
517
+ >
518
+ > Vậy hệ phương trình đã cho có nghiệm $(x; y) = (2; -1)$.
519
+
520
+ **Ví dụ 6** Một trường trung học cơ sở mua 500 quyển vở để làm phần thưởng cho học sinh. Giá bán của mỗi quyển vở loại thứ nhất, loại thứ hai lần lượt là 8 000 đồng, 9 000 đồng. Hỏi nhà trường đã mua mỗi loại bao nhiêu quyển vở? Biết rằng số tiền nhà trường đã dùng để mua 500 quyển vở đó là 4 200 000 đồng.
521
+
522
+ > **Giải**
523
+ >
524
+ > Gọi số quyển vở loại thứ nhất, loại thứ hai lần lượt là $x, y$ ($x, y \in \mathbb{N}^*$).
525
+ >
526
+ > Theo giả thiết, ta có phương trình: $x+y=500$.
527
+ >
528
+ > Mặt khác, ta có phương trình: $8000x + 9000y = 4200000$, tức là $8x+9y=4200$.
529
+ >
530
+ > Ta có hệ phương trình: $\begin{cases} x+y=500 \quad (1) \\ 8x+9y=4200 \quad (2) \end{cases}$.
531
+ >
532
+ > Ta giải hệ phương trình trên:
533
+ > Từ phương trình (1), ta có: $y = 500-x$.
534
+ > Thay vào phương trình (2), ta được: $8x + 9(500-x) = 4200$.
535
+ > Giải phương trình:
536
+ > $$
537
+ > 8x + 4500 - 9x = 4200 \\
538
+ > -x + 4500 = 4200 \\
539
+ > x = 300
540
+ > $$
541
+ > Thay giá trị $x=300$ vào phương trình $y=500-x$, ta có: $y = 500-300 = 200$.
542
+ >
543
+ > Do đó, hệ phương trình đã cho có nghiệm $(x; y) = (300; 200)$.
544
+ > Vậy nhà trường đã mua 300 quyển vở loại thứ nhất và 200 quyển vở loại thứ hai.
545
+
546
+ ### III. SỬ DỤNG MÁY TÍNH CẦM TAY ĐỂ TÌM NGHIỆM CỦA HỆ HAI PHƯƠNG TRÌNH BẬC NHẤT HAI ẨN
547
+
548
+ Ta có thể tìm nghiệm (đúng hoặc gần đúng) của hệ hai phương trình bậc nhất hai ẩn bằng cách sử dụng máy tính cầm tay. Mỗi loại máy tính khác nhau có thể có các phím khác nhau. Tuy nhiên, đều có quy tắc chung là phải mở chương trình giải hệ phương trình bậc nhất hai ẩn rồi mới nhập dữ liệu. Chẳng hạn, ấn liên tiếp các phím `MODE` `5` `1`.
549
+
550
+ ### BÀI TẬP
551
+
552
+ 1. Giải các hệ phương trình sau bằng phương pháp thế:
553
+ a) $\begin{cases} x-2y=0 \\ 3x+2y=8 \end{cases}$
554
+ b) $\begin{cases} -\frac{3}{4}x + \frac{1}{2}y = -2 \\ \frac{3}{2}x - y = 4 \end{cases}$
555
+ c) $\begin{cases} 4x-2y=1 \\ -2x+y=0 \end{cases}$
556
+
557
+ 2. Giải các hệ phương trình sau bằng phương pháp cộng đại số:
558
+ a) $\begin{cases} 2x+y=4 \\ x-y=2 \end{cases}$
559
+ b) $\begin{cases} 4x+5y=11 \\ 2x-3y=0 \end{cases}$
560
+ c) $\begin{cases} 12x+18y=-24 \\ -2x-3y=4 \end{cases}$
561
+ d) $\begin{cases} x-3y=5 \\ -2x+6y=10 \end{cases}$
562
+
563
+ 3. Xác định $a$ và $b$ để đồ thị của hàm số $y=ax+b$ đi qua hai điểm $A, B$ trong mỗi trường hợp sau:
564
+ a) $A(1; -2)$ và $B(-2; -11)$
565
+ b) $A(2; 8)$ và $B(-4; 5)$
566
+
567
+ 4. Một ca nô đi xuôi dòng một quãng đường $42 \text{ km}$ hết 1 giờ 30 phút và ngược dòng quãng đường đó hết 2 giờ 6 phút. Tính tốc độ của ca nô khi nước yên lặng và tốc độ của dòng nước. Biết rằng tốc độ của ca nô khi nước yên lặng không đổi trên suốt quãng đường và tốc độ của dòng nước cũng không đổi khi ca nô chuyển động.
568
+
569
+ 5. Bác Phương chia số tiền 800 triệu đồng của mình cho hai khoản đầu tư. Sau một năm, tổng số tiền lãi thu được là 54 triệu đồng. Lãi suất cho khoản đầu tư thứ nhất là $6\%/\text{năm}$ và khoản đầu tư thứ hai là $8\%/\text{năm}$. Tính số tiền bác Phương đầu tư cho mỗi khoản.
570
+
571
+ 6. Nhân dịp ngày Giỗ Tổ Hùng Vương, một siêu thị điện máy đã giảm giá nhiều mặt hàng để kích cầu mua sắm. Giá niêm yết của một chiếc tủ lạnh và một chiếc máy giặt có tổng số tiền là 25,4 triệu đồng. Tuy nhiên, trong dịp này tủ lạnh giảm $40\%$ giá niêm yết và máy giặt giảm $25\%$ giá niêm yết. Vì thế, cô Liên đã mua hai mặt hàng trên với tổng số tiền là 16,77 triệu đồng. Hỏi giá niêm yết của mỗi mặt hàng trên là bao nhiêu?
572
+
573
+ 7. Tìm các hệ số $x, y$ để cân bằng mỗi phương trình phản ứng hoá học sau:
574
+ a) $2\text{Fe} + y\text{Cl}_2 \to x\text{FeCl}_3$
575
+ b) $x\text{FeCl}_3 + \text{Fe} \to y\text{FeCl}_2$
576
+
577
+ ---
578
+ # BÀI TẬP CUỐI CHƯƠNG I
579
+
580
+ 1. Nghiệm của phương trình $\frac{1}{x} - \frac{3}{2x} = \frac{1}{6}$ là:
581
+ A. $x=3$
582
+ B. $x=-3$
583
+ C. $x=6$
584
+ D. $x=-6$
585
+
586
+ 2. Nghiệm của hệ phương trình $\begin{cases} x+y=9 \\ x-y=-1 \end{cases}$ là:
587
+ A. $(x; y) = (4; 5)$
588
+ B. $(x; y) = (5; 4)$
589
+ C. $(x; y) = (-5; -4)$
590
+ D. $(x; y) = (-4; -5)$
591
+
592
+ 3. Giải các phương trình:
593
+ a) $(3x+7)(4x-9)=0$
594
+ b) $(5x-0,2)(0,3x+6)=0$
595
+ c) $x(2x-1) + 5(2x-1) = 0$
596
+ d) $x^2-9 - (x+3)(3x+1) = 0$
597
+ e) $x^2-10x+25 = 5(5-x)$
598
+ g) $4x^2 = (x-12)^2$
599
+
600
+ 4. Giải các phương trình:
601
+ a) $\frac{-6}{x+3} = \frac{2}{3}$
602
+ b) $\frac{x-2}{2} + \frac{1}{2x} = 0$
603
+ c) $\frac{8}{3x-4} = \frac{1}{x+2}$
604
+ d) $\frac{x}{x-2} + \frac{2}{(x-2)^2} = 1$
605
+ e) $\frac{3x-2}{x+1} = 4 - \frac{x+2}{x-1}$
606
+ g) $\frac{x^2}{(x-1)(x-2)} = 1 - \frac{1}{x-1}$
607
+
608
+ 5. Giải các hệ phương trình:
609
+ a) $\begin{cases} x+3y=-2 \\ 5x-4y=11 \end{cases}$
610
+ b) $\begin{cases} 2x+3y=-2 \\ 3x-2y=-3 \end{cases}$
611
+ c) $\begin{cases} 2x-4y=-1 \\ -3x+6y=2 \end{cases}$
612
+
613
+ 6. Một nhóm bạn trẻ cùng tham gia khởi nghiệp và dự định góp vốn là 240 triệu đồng, số tiền góp mỗi người là như nhau. Nếu có thêm 2 người tham gia cùng thì số tiền mỗi người góp giảm đi 4 triệu đồng. Hỏi nhóm bạn trẻ đó có bao nhiêu người?
614
+
615
+ 7. Một nhóm công nhân cần phải cắt cỏ một số mặt sân cỏ. Nếu nhóm công nhân ��ó sử dụng 3 máy cắt có người lái và 2 máy cắt đẩy tay trong 10 phút thì cắt được $2990 \text{ m}^2$ cỏ. Nếu nhóm công nhân đó sử dụng 4 máy cắt có người lái và 3 máy cắt đẩy tay trong 10 phút thì cắt được $4060 \text{ m}^2$ cỏ. Hỏi trong 10 phút, mỗi loại máy trên sẽ cắt được bao nhiêu mét vuông cỏ?
616
+
617
+ 8. Tại một buổi biểu diễn nhằm gây quỹ từ thiện, ban tổ chức đã bán được 500 vé. Trong đó có hai loại vé: vé loại I giá 100 000 đồng; vé loại II giá 75 000 đồng. Tổng số tiền thu được từ bán vé là 44 500 000 đồng. Tính số vé bán ra của mỗi loại.
618
+
619
+ 9. Trong một đợt khuyến mãi, siêu thị giảm giá cho mặt hàng A là $20\%$ và mặt hàng B là $15\%$ so với giá niêm yết. Một khách hàng mua 2 món hàng A và 1 món hàng B thì phải trả số tiền là 362 000 đồng. Nhưng nếu mua trong khung giờ vàng thì mặt hàng A được giảm giá $30\%$ và mặt hàng B được giảm giá $25\%$ so với giá niêm yết. Một khách hàng mua 3 món hàng A và 2 món hàng B trong khung giờ vàng nên phải trả số tiền là 552 000 đồng. Tính giá niêm yết của mỗi mặt hàng A và B.
620
+
621
+ 10. Trong phòng thí nghiệm, cô Linh muốn tạo ra $500 \text{ g}$ dung dịch HCl $19\%$ từ hai loại dung dịch HCl $10\%$ và HCl $25\%$. Hỏi cô Linh cần dùng bao nhiêu gam cho mỗi loại dung dịch đó?
622
+
623
+ 11. Một ca nô đi xuôi dòng từ địa điểm A đến địa điểm B và lại ngược dòng từ địa điểm B về địa điểm A mất 9 giờ, tốc độ của ca nô khi nước yên lặng không đổi trên suốt quãng đường đó và tốc độ của dòng nước cũng không đổi khi ca nô chuyển động. Biết thời gian ca nô đi xuôi dòng $5 \text{ km}$ bằng thời gian ca nô đi ngược dòng $4 \text{ km}$ và quãng đường AB là $160 \text{ km}$. Tính tốc độ của ca nô khi nước yên lặng và tốc độ của dòng nước.
624
+
625
+ ---
626
+ # CHƯƠNG II: BẤT ĐẲNG THỨC. BẤT PHƯƠNG TRÌNH BẬC NHẤT MỘT ẨN
627
+
628
+ Trong chương này, chúng ta sẽ tìm hiểu những nội dung sau: bất đẳng thức; bất phương trình bậc nhất một ẩn.
629
+
630
+ ## §1. BẤT ĐẲNG THỨC
631
+
632
+ Tìm hiểu trên Internet, bạn Châu được biết một con voi nặng khoảng $5000 \text{ kg}$, một con hổ nặng khoảng $200 \text{ kg}$, một con tê giác đen nặng khoảng $450 \text{ kg}$.
633
+
634
+ Để biểu thị con voi nặng hơn cả con hổ và con tê giác đen, bạn Châu đã viết:
635
+ $5000 > 200 + 450$.
636
+
637
+ ### I. NHẮC LẠI VỀ THỨ TỰ TRONG TẬP HỢP SỐ THỰC
638
+
639
+ Như ta đã biết, trong hai số thực khác nhau luôn có một số nhỏ hơn số kia.
640
+ * Nếu số thực $a$ nhỏ hơn số thực $b$ thì ta viết $a < b$.
641
+ * Nếu số thực $a$ lớn hơn số thực $b$ thì ta viết $a > b$.
642
+ * Số thực lớn hơn 0 gọi là số thực dương.
643
+ * Số thực nhỏ hơn 0 gọi là số thực âm.
644
+
645
+ Trên trục số nằm ngang, nếu số thực $a$ nằm bên trái số thực $b$ thì $a < b$.
646
+
647
+ Với hai số thực $a, b$, ta có:
648
+ * Nếu $ab > 0$ thì $a$ và $b$ cùng dương hoặc cùng âm (hay $a$ và $b$ cùng dấu) và ngược lại.
649
+ * Nếu $ab < 0$ thì $a$ và $b$ trái dấu và ngược lại.
650
+
651
+ Với hai số thực không âm $a, b$, ta có:
652
+ * Nếu $a > b$ thì $\sqrt{a} > \sqrt{b}$.
653
+
654
+ **Ví dụ 1** So sánh:
655
+ a) $3\frac{1}{7}$ và $3,14$
656
+ b) $4$ và $\sqrt{17}$
657
+
658
+ > **Giải**
659
+ >
660
+ > a) Do $3\frac{1}{7} = 3,1428...$ nên $3\frac{1}{7} > 3,14$.
661
+ > b) Ta có: $4 = \sqrt{16}$. Do $16 < 17$ nên $\sqrt{16} < \sqrt{17}$ hay $4 < \sqrt{17}$.
662
+
663
+ ### II. BẤT ĐẲNG THỨC
664
+
665
+ Hệ thức có dạng $a < b$ (hay $a > b, a \leq b, a \geq b$) là **bất đẳng thức** và gọi $a$ là vế trái, $b$ là vế phải của bất đẳng thức.
666
+
667
+ **Chú ý:**
668
+ * Hai bất đẳng thức $a < b$ và $c < d$ được gọi là hai bất đẳng thức **cùng chiều**.
669
+ * Hai bất đẳng thức $a < b$ và $c > d$ được gọi là hai bất đẳng thức **ngược chiều**.
670
+
671
+ **Ví dụ 2** Cho $a > b$. Chứng minh:
672
+ a) $a+b > 2b$
673
+ b) $5a-b > 4a$
674
+
675
+ > **Giải**
676
+ >
677
+ > a) Xét hiệu: $(a+b) - 2b = a-b$. Do $a>b$ nên $a-b>0$. Vậy $(a+b) > 2b$.
678
+ > b) Xét hiệu: $(5a-b) - 4a = a-b$. Do $a>b$ nên $a-b>0$. Vậy $5a-b > 4a$.
679
+
680
+ ### III. TÍNH CHẤT CỦA BẤT ĐẲNG THỨC
681
+
682
+ **1. Liên hệ giữa thứ tự và phép cộng**
683
+
684
+ Khi cộng cùng một số vào cả hai vế của một bất đẳng thức, ta được bất đẳng thức mới **cùng chiều** với bất đẳng thức đã cho.
685
+ * Nếu $a > b$ thì $a+c > b+c$ với mọi số thực $c$.
686
+ * Nếu $a \geq b$ thì $a+c \geq b+c$ với mọi số thực $c$.
687
+
688
+ **Ví dụ 4** Chứng minh: $\frac{2024}{2023} > \frac{2025}{2024}$.
689
+
690
+ > **Giải**
691
+ >
692
+ > Do $\frac{1}{2023} > \frac{1}{2024}$ nên $\frac{1}{2023} + 1 > \frac{1}{2024} + 1$.
693
+ > Hay $\frac{2024}{2023} > \frac{2025}{2024}$.
694
+
695
+ **2. Liên hệ giữa thứ tự và phép nhân**
696
+
697
+ * Khi nhân cả hai vế của bất đẳng thức với cùng một số **dương**, ta được bất đẳng thức mới **cùng chiều** với bất đẳng thức đã cho.
698
+ Với ba số $a, b, c$ mà $c > 0$, ta có:
699
+ * Nếu $a > b$ thì $ac > bc$.
700
+ * Nếu $a < b$ thì $ac < bc$.
701
+
702
+ * Khi nhân cả hai vế của bất đẳng thức với cùng một số **âm**, ta được bất đẳng thức mới **ngược chiều** với bất đẳng thức đã cho.
703
+ Với ba số $a, b, c$ mà $c < 0$, ta có:
704
+ * Nếu $a > b$ thì $ac < bc$.
705
+ * Nếu $a < b$ thì $ac > bc$.
706
+
707
+ **3. Tính chất bắc cầu**
708
+
709
+ Nếu $a > b$ và $b > c$ thì $a > c$.
710
+
711
+ **Ví dụ 8** Cho $a > b$ và $c > d$. Chứng minh $a+c > b+d$.
712
+
713
+ > **Giải**
714
+ >
715
+ > Do $a > b$ nên $a+c > b+c$.
716
+ > Lại do $c > d$ nên $b+c > b+d$.
717
+ > Vậy $a+c > b+d$.
718
+
719
+ ### BÀI TẬP
720
+
721
+ 1. Chứng minh:
722
+ a) $\sqrt{29} - \sqrt{6} > \sqrt{28} - \sqrt{6}$
723
+ b) $26,2 < 26,21$
724
+ c) $-5,13 > -5,131$
725
+
726
+ 2. Cho $m > n$. Chứng minh:
727
+ a) $m+2 > n+2$
728
+ b) $m-5 > n-5$
729
+ c) $-3m < -3n$
730
+ d) $2m+3 > 2n+3$
731
+
732
+ 3. a) Cho $a > b > 0$. Chứng minh: $\frac{1}{a} < \frac{1}{b}$.
733
+ b) Áp dụng, so sánh: $\frac{2022}{2023}$ và $\frac{2023}{2024}$.
734
+
735
+ ---
736
+
737
+ ## §2. BẤT PHƯƠNG TRÌNH BẬC NHẤT MỘT ẨN
738
+
739
+ ### I. MỞ ĐẦU VỀ BẤT PHƯƠNG TRÌNH MỘT ẨN
740
+
741
+ Xét hệ thức $3x+4 > x+6$. Ta nói rằng hệ thức này là một **bất phương trình** với ẩn $x$.
742
+ Giá trị $x=5$ là một **nghiệm** của bất phương trình đó vì $3 \cdot 5 + 4 > 5+6$ (tức $19 > 11$) là một khẳng định đúng.
743
+
744
+ Một bất phương trình với ẩn $x$ có dạng $A(x) > B(x)$ (hoặc $A(x) < B(x), A(x) \geq B(x), A(x) \leq B(x)$), trong đó $A(x)$ và $B(x)$ là hai biểu thức của cùng một biến $x$.
745
+
746
+ ### II. BẤT PHƯƠNG TRÌNH BẬC NHẤT MỘT ẨN
747
+
748
+ **1. Định nghĩa**
749
+
750
+ **Bất phương trình bậc nhất một ẩn** có dạng $ax+b > 0$ (hoặc $ax+b < 0, ax+b \geq 0, ax+b \leq 0$), trong đó $a, b$ là hai số đã cho và $a \neq 0$.
751
+
752
+ **2. Cách giải**
753
+
754
+ Giải bất phương trình $ax+b > 0$ (với $a>0$) được giải như sau:
755
+ $$
756
+ ax+b > 0 \\
757
+ ax > -b \\
758
+ x > -\frac{b}{a}
759
+ $$
760
+ Vậy nghiệm của bất phương trình đã cho là $x > -\frac{b}{a}$.
761
+
762
+ Giải bất phương trình $ax+b > 0$ (với $a<0$) được giải như sau:
763
+ $$
764
+ ax+b > 0 \\
765
+ ax > -b \\
766
+ x < -\frac{b}{a}
767
+ $$
768
+ Vậy nghiệm của bất phương trình đã cho là $x < -\frac{b}{a}$.
769
+
770
+ **Ví dụ 3** Giải các bất phương trình:
771
+ a) $-0,3x + 12 > 0$
772
+ b) $\frac{3}{4}x - 6 \leq 0$
773
+
774
+ > **Giải**
775
+ >
776
+ > a) $-0,3x + 12 > 0 \implies -0,3x > -12 \implies x < \frac{-12}{-0,3} \implies x < 40$.
777
+ > Vậy nghiệm của bất phương trình đã cho là $x < 40$.
778
+ >
779
+ > b) $\frac{3}{4}x - 6 \leq 0 \implies \frac{3}{4}x \leq 6 \implies x \leq 6 \cdot \frac{4}{3} \implies x \leq 8$.
780
+ > Vậy nghiệm của bất phương trình đã cho là $x \leq 8$.
781
+
782
+ **Ví dụ 5** Giải bất phương trình: $3x-5-2x > 25+4x$.
783
+
784
+ > **Giải**
785
+ >
786
+ > $$
787
+ > 3x-5-2x > 25+4x \\
788
+ > x-5 > 25+4x \\
789
+ > x-4x > 25+5 \\
790
+ > -3x > 30 \\
791
+ > x < \frac{30}{-3} \\
792
+ > x < -10
793
+ > $$
794
+ > Vậy nghiệm của bất phương trình đã cho là $x < -10$.
795
+
796
+ ### BÀI TẬP
797
+
798
+ 1. Kiểm tra xem số nào là nghiệm của mỗi bất phương trình tương ứng sau đây:
799
+ a) $x^2 - 3x + 2 > 0$ với $x=-3; x=1,5$.
800
+ b) $2-2x < 3x+1$ với $x=0,5; x=\frac{1}{5}$.
801
+
802
+ 2. Giải các bất phương trình:
803
+ a) $x-5 \geq 0$
804
+ b) $0,6x+2 > 6x+9$
805
+ c) $1,7x+4 \geq 2+1,5x$
806
+
807
+ 3. Giải các bất phương trình:
808
+ a) $\frac{8-3x}{2} - x < 0$
809
+ b) $3(2x-1) - \frac{x+3}{2} \leq 1$
810
+ c) $0,7x + \frac{2x-4}{3} - \frac{x}{6} > 1$
811
+
812
+ 4. Tìm $x>0$ sao cho chu vi của hình tam giác lớn hơn chu vi của hình chữ nhật (Hình 2).
813
+
814
+ 5. Một kho chứa 100 tấn xi măng, mỗi ngày đều xuất đi 20 tấn xi măng. Gọi $x$ là số ngày xuất xi măng của kho đó. Tìm $x$ sao cho khối lượng xi măng còn lại trong kho ít nhất là 10 tấn sau $x$ ngày xuất hàng.
815
+
816
+ ---
817
+ # BÀI TẬP CUỐI CHƯƠNG II
818
+
819
+ 1. Cho bất đẳng thức $a > b$. Kết luận nào sau đây là không đúng?
820
+ A. $2a > 2b$
821
+ B. $-a < -b$
822
+ C. $a-3 > b-3$
823
+ D. $a+1 < b+1$
824
+
825
+ 2. Trong các phát biểu sau, phát biểu nào đúng, phát biểu nào sai?
826
+ a) Bất phương trình $ax+b > 0$ có nghiệm là $x > -\frac{b}{a}$
827
+ b) Bất phương trình $ax+b < 0$ với $a>0$ có nghiệm là $x < -\frac{b}{a}$
828
+ c) Bất phương trình $ax+b \geq 0$ với $a<0$ có nghiệm là $x \leq -\frac{b}{a}$
829
+ d) Bất phương trình $ax+b \leq 0$ với $a<0$ có nghiệm là $x \geq -\frac{b}{a}$
830
+
831
+ 3. Chứng minh:
832
+ a) Nếu $a>5$ thì $\frac{a-1}{2} > 2$
833
+ b) Nếu $b>7$ thì $4 - \frac{b+3}{5} < 0$
834
+
835
+ 4. Giải các bất phương trình:
836
+ a) $2x-1 > 0$
837
+ b) $5-x \leq 0$
838
+ c) $2x-9 < 9+4x$
839
+ d) $\frac{3x+5}{2} + \frac{x}{5} - 0,2x \geq 4$
840
+ e) $2x - \frac{x-7}{3} < 1$
841
+
842
+ 5. Tìm $x$ sao cho:
843
+ a) Giá trị của biểu thức $2x-5$ không âm.
844
+ b) Giá trị của biểu thức $-3x$ không lớn hơn giá trị của biểu thức $-7x+5$.
845
+
846
+ 6. Một hãng taxi có giá mở cửa là 15 000 đồng và giá 12 000 đồng cho mỗi kilômét tiếp theo.
847
+ a) Viết biểu thức tính số tiền $y$ (đồng) mà khách hàng phải trả khi đi $x$ (km).
848
+ b) Một khách hàng có 200 000 đồng. Hỏi khách hàng đó có thể đi được quãng đường tối đa là bao nhiêu kilômét?
849
+
850
+ ---
851
+ # CHƯƠNG III: CĂN THỨC
852
+
853
+ ### §1. CĂN BẬC HAI VÀ CĂN BẬC BA CỦA SỐ THỰC
854
+
855
+ ### I. CĂN BẬC HAI
856
+
857
+ **Căn bậc hai** của một số thực không âm $a$ là số thực $x$ sao cho $x^2 = a$.
858
+ * Số dương $a$ có đúng hai căn bậc hai là hai số đối nhau: số dương kí hiệu là $\sqrt{a}$; số âm kí hiệu là $-\sqrt{a}$. Ta gọi $\sqrt{a}$ là **căn bậc hai số học** của $a$.
859
+ * Căn bậc hai của số $0$ bằng 0.
860
+ * Số âm không có căn bậc hai.
861
+
862
+ **Ví dụ 2**
863
+ a) Số 8 và -8 có phải là căn bậc hai của 64 hay không?
864
+ b) Từ đó, hãy sử dụng kí hiệu căn bậc hai để biểu thị giá trị 8 và giá trị -8.
865
+
866
+ > **Giải**
867
+ >
868
+ > a) Ta thấy: $8^2 = 64$ và $(-8)^2 = 64$ nên số 8 và -8 là căn bậc hai của 64.
869
+ > b) Ta có: $\sqrt{64} = 8$ và $-\sqrt{64} = -8$.
870
+
871
+ **Ví dụ 5** So sánh:
872
+ a) $\sqrt{3}$ và $\sqrt{5}$
873
+ b) $3$ và $\sqrt{10}$
874
+
875
+ > **Giải**
876
+ >
877
+ > a) Do $3 < 5$ nên $\sqrt{3} < \sqrt{5}$.
878
+ > b) Ta có $3 = \sqrt{9}$. Do $9 < 10$ nên $\sqrt{9} < \sqrt{10}$, hay $3 < \sqrt{10}$.
879
+
880
+ ### II. CĂN BẬC BA
881
+
882
+ **Căn bậc ba** của một số thực $a$ là số thực $x$ sao cho $x^3 = a$.
883
+ Căn bậc ba của số thực $a$ được kí hiệu là $\sqrt[3]{a}$.
884
+ Ta có: $(\sqrt[3]{a})^3 = a$.
885
+
886
+ **Chú ý:** Mỗi số thực $a$ đều có duy nhất một căn bậc ba.
887
+
888
+ **Ví dụ 8** Tìm giá trị của:
889
+ a) $\sqrt[3]{1000}$
890
+ b) $\sqrt[3]{-0,064}$
891
+ c) $\sqrt[3]{\frac{1}{125}}$
892
+
893
+ > **Giải**
894
+ >
895
+ > a) $\sqrt[3]{1000} = 10$
896
+ > b) $\sqrt[3]{-0,064} = -0,4$
897
+ > c) $\sqrt[3]{\frac{1}{125}} = \frac{1}{5}$
898
+
899
+ Với hai số $a, b$ ta có: Nếu $a < b$ thì $\sqrt[3]{a} < \sqrt[3]{b}$.
900
+
901
+ ---
902
+ ## §2. MỘT SỐ PHÉP TÍNH VỀ CĂN BẬC HAI CỦA SỐ THỰC
903
+
904
+ ### I. CĂN BẬC HAI CỦA MỘT TÍCH
905
+
906
+ Với $a \geq 0, b \geq 0$ ta có: $\sqrt{ab} = \sqrt{a} \cdot \sqrt{b}$.
907
+
908
+ ### II. CĂN BẬC HAI CỦA MỘT THƯƠNG
909
+
910
+ Với $a \geq 0, b > 0$ ta có: $\sqrt{\frac{a}{b}} = \frac{\sqrt{a}}{\sqrt{b}}$.
911
+
912
+ ### III. ĐƯA THỪA SỐ RA NGOÀI DẤU CĂN BẬC HAI
913
+
914
+ Cho hai số $a, b$ với $b \geq 0$. Khi đó $\sqrt{a^2 b} = |a|\sqrt{b}$.
915
+ Cụ thể, ta có:
916
+ * Nếu $a \geq 0$ thì $\sqrt{a^2 b} = a\sqrt{b}$.
917
+ * Nếu $a < 0$ thì $\sqrt{a^2 b} = -a\sqrt{b}$.
918
+
919
+ ### IV. ĐƯA THỪA SỐ VÀO TRONG DẤU CĂN BẬC HAI
920
+
921
+ * Với $a \geq 0, b \geq 0$, ta có $a\sqrt{b} = \sqrt{a^2 b}$.
922
+ * Với $a < 0, b \geq 0$, ta có $a\sqrt{b} = -\sqrt{a^2 b}$.
923
+
924
+ ---
925
+ ## §3. CĂN THỨC BẬC HAI VÀ CĂN THỨC BẬC BA CỦA BIỂU THỨC ĐẠI SỐ
926
+
927
+ ### I. CĂN THỨC BẬC HAI
928
+
929
+ Với $A$ là một biểu thức đại số, người ta gọi $\sqrt{A}$ là **căn thức bậc hai** của $A$. $A$ được gọi là biểu thức lấy căn hay biểu thức dưới dấu căn.
930
+ $\sqrt{A}$ xác định (hay có nghĩa) khi $A$ lấy giá trị không âm.
931
+
932
+ **Ví dụ 1** Biểu thức $\sqrt{3x-12}$ có nghĩa khi nào?
933
+
934
+ > **Giải**
935
+ >
936
+ > Biểu thức $\sqrt{3x-12}$ có nghĩa khi $3x-12 \geq 0$, tức là $3x \geq 12$ hay $x \geq 4$.
937
+
938
+ **Hằng đẳng thức $\sqrt{A^2} = |A|$**
939
+ Với mọi biểu thức $A$, ta có $\sqrt{A^2} = |A|$.
940
+ Cụ thể:
941
+ * $\sqrt{A^2} = A$ nếu $A \geq 0$.
942
+ * $\sqrt{A^2} = -A$ nếu $A < 0$.
943
+
944
+ ### II. CĂN THỨC BẬC BA
945
+
946
+ Với $A$ là một biểu thức đại số, người ta gọi $\sqrt[3]{A}$ là **căn thức bậc ba** của $A$.
947
+ Căn thức bậc ba $\sqrt[3]{A}$ xác định với mọi giá trị của các biến trong $A$.
948
+
949
+ ---
950
+ ## §4. MỘT SỐ PHÉP BIẾN ĐỔI CĂN THỨC BẬC HAI CỦA BIỂU THỨC ĐẠI SỐ
951
+
952
+ ### I. CĂN THỨC BẬC HAI CỦA MỘT TÍCH
953
+
954
+ Với hai biểu thức $A, B$ không âm, ta có $\sqrt{A \cdot B} = \sqrt{A} \cdot \sqrt{B}$.
955
+
956
+ ### II. CĂN THỨC BẬC HAI CỦA MỘT THƯƠNG
957
+
958
+ Với biểu thức $A$ không âm và biểu thức $B$ dương, ta có $\sqrt{\frac{A}{B}} = \frac{\sqrt{A}}{\sqrt{B}}$.
959
+
960
+ ### III. TRỤC CĂN THỨC Ở MẪU
961
+
962
+ Phép biến đổi làm mất căn thức bậc hai ở mẫu thức của một biểu thức được gọi là **trục căn thức ở mẫu** của biểu thức đó.
963
+
964
+ * Với các biểu thức $A, B$ mà $B > 0$, ta có: $\frac{A}{\sqrt{B}} = \frac{A\sqrt{B}}{B}$.
965
+ * Với các biểu thức $A, B, C$ mà $B \geq 0$ và $A^2 \neq B$, ta có:
966
+ $\frac{C}{A+\sqrt{B}} = \frac{C(A-\sqrt{B})}{A^2-B}$
967
+ $\frac{C}{A-\sqrt{B}} = \frac{C(A+\sqrt{B})}{A^2-B}$
968
+ * Với các biểu thức $A, B, C$ mà $A \geq 0, B \geq 0$ và $A \neq B$, ta có:
969
+ $\frac{C}{\sqrt{A}+\sqrt{B}} = \frac{C(\sqrt{A}-\sqrt{B})}{A-B}$
970
+ $\frac{C}{\sqrt{A}-\sqrt{B}} = \frac{C(\sqrt{A}+\sqrt{B})}{A-B}$
971
+
972
+ ---
973
+ # BÀI TẬP CUỐI CHƯƠNG III
974
+
975
+ 1. Căn bậc hai của 16 là:
976
+ A. 4
977
+ B. 4 và -4
978
+ C. 256
979
+ D. 256 và -256
980
+
981
+ 2. Nếu $\sqrt{x}=9$ thì $x$ bằng:
982
+ A. 3
983
+ B. 3 hoặc -3
984
+ C. 81
985
+ D. 81 hoặc -81
986
+
987
+ 3. Rút gọn biểu thức:
988
+ a) $A = \sqrt{40^2 - 24^2}$
989
+ b) $B = (\sqrt{12} + 2\sqrt{3} - \sqrt{27}) \cdot \sqrt{3}$
990
+ c) $C = \frac{\sqrt{63^3+1}}{\sqrt{63^2-62}}$
991
+ d) $D = \sqrt{60} - 5\sqrt{\frac{3}{5}} - 3\sqrt{\frac{5}{3}}$
992
+
993
+ 4. Trục căn thức ở mẫu:
994
+ a) $\frac{1}{\sqrt{x+1}}$ với $x > -1$
995
+ b) $\frac{3}{\sqrt{x}-2}$ với $x>0, x \neq 4$
996
+ c) $\frac{x-5}{\sqrt{x}-\sqrt{5}}$ với $x>0, x \neq 5$
997
+ d) $\frac{x^2-9}{\sqrt{x}-\sqrt{3}}$ với $x>0, x \neq 3$
998
+
999
+ 5. So sánh:
1000
+ a) $2\sqrt{3}$ và $3\sqrt{2}$
1001
+ b) $7\sqrt{\frac{3}{7}}$ và $\sqrt{21}$
1002
+ c) $\frac{2}{\sqrt{5}}$ và $\frac{6}{\sqrt{10}}$
1003
+
1004
+ 6. Cho biểu thức: $M = \frac{a\sqrt{a} + b\sqrt{b}}{\sqrt{a} + \sqrt{b}}$ với $a>0, b>0$.
1005
+ a) Rút gọn biểu thức $M$.
1006
+ b) Tính giá trị của biểu thức tại $a=2, b=8$.
1007
+
1008
+ 7. Cho biểu thức: $N = \frac{x\sqrt{x}+8}{x-4} - \frac{x+4}{\sqrt{x}-2}$ với $x \geq 0$ và $x \neq 4$.
1009
+ a) Rút gọn biểu thức $N$.
1010
+ b) Tính giá trị của biểu thức tại $x=9$.
1011
+
1012
+ 8. Tốc độ con sóng thần $v (\text{m/s})$ và chiều sâu đại dương $d (\text{m})$ liên hệ bởi công thức $v = \sqrt{dg}$, trong đó $g=9,81 \text{ m/s}^2$.
1013
+ a) Hãy tính tốc độ con sóng thần xuất phát từ Thái Bình Dương, ở độ sâu trung bình $4000 \text{ m}$.
1014
+ b) Theo tính toán, tốc độ con sóng thần ngày 28/9/2018 là $800 \text{ km/h}$, hãy tính chiều sâu đại dương của nơi tâm chấn động đất gây ra sóng thần.
1015
+
1016
+ ---
1017
+ # CHƯƠNG IV: HỆ THỨC LƯỢNG TRONG TAM GIÁC VUÔNG
1018
+
1019
+ ### §1. TỈ SỐ LƯỢNG GIÁC CỦA GÓC NHỌN
1020
+
1021
+ Cho góc nhọn $\alpha$. Xét tam giác $ABC$ vuông tại $A$ có $\widehat{B} = \alpha$.
1022
+ * Tỉ số giữa cạnh đối và cạnh huyền được gọi là **sin** của góc $\alpha$, kí hiệu $\sin\alpha$.
1023
+ * Tỉ số giữa cạnh kề và cạnh huyền được gọi là **côsin** của góc $\alpha$, kí hiệu $\cos\alpha$.
1024
+ * Tỉ số giữa cạnh đối và cạnh kề được gọi là **tang** của góc $\alpha$, kí hiệu $\tan\alpha$.
1025
+ * Tỉ số giữa cạnh kề và cạnh đối được gọi là **côtang** của góc $\alpha$, kí hiệu $\cot\alpha$.
1026
+
1027
+ Trong $\triangle ABC$ vuông tại $A$:
1028
+ $\sin B = \frac{AC}{BC}$; $\cos B = \frac{AB}{BC}$; $\tan B = \frac{AC}{AB}$; $\cot B = \frac{AB}{AC}$.
1029
+
1030
+ **Tính chất:**
1031
+ Nếu hai góc phụ nhau ($\alpha + \beta = 90^\circ$) thì:
1032
+ $\sin\alpha = \cos\beta$; $\cos\alpha = \sin\beta$; $\tan\alpha = \cot\beta$; $\cot\alpha = \tan\beta$.
1033
+
1034
+ Với mọi góc nhọn $\alpha$, ta có:
1035
+ * $0 < \sin\alpha < 1$; $0 < \cos\alpha < 1$
1036
+ * $\sin^2\alpha + \cos^2\alpha = 1$
1037
+ * $\tan\alpha = \frac{\sin\alpha}{\cos\alpha}$; $\cot\alpha = \frac{\cos\alpha}{\sin\alpha}$; $\tan\alpha \cdot \cot\alpha = 1$
1038
+
1039
+ ---
1040
+ ## §2. MỘT SỐ HỆ THỨC VỀ CẠNH VÀ GÓC TRONG TAM GIÁC VUÔNG
1041
+
1042
+ Trong một tam giác vuông, mỗi cạnh góc vuông bằng:
1043
+ * Cạnh huyền nhân với sin góc đối hoặc nhân với côsin góc kề.
1044
+ * Cạnh góc vuông kia nhân với tang góc đối hoặc nhân với côtang góc kề.
1045
+
1046
+ **Giải tam giác vuông** là tìm tất cả các cạnh và các góc còn lại của tam giác vuông khi biết trước hai yếu tố (trong đó có ít nhất một yếu tố về cạnh).
1047
+
1048
+ ---
1049
+ ## §3. ỨNG DỤNG CỦA TỈ SỐ LƯỢNG GIÁC CỦA GÓC NHỌN
1050
+
1051
+ (Phần này chủ yếu là các bài toán thực tế áp dụng các hệ thức đã học)
1052
+
1053
+ ---
1054
+ # BÀI TẬP CUỐI CHƯƠNG IV
1055
+ (Bao gồm các bài tập tổng hợp về tỉ số lượng giác và giải tam giác vuông)
1056
+
1057
+ ---
1058
+ # CHƯƠNG V: ĐƯỜNG TRÒN
1059
+
1060
+ ### §1. ĐƯỜNG TRÒN. VỊ TRÍ TƯƠNG ĐỐI CỦA HAI ĐƯỜNG TRÒN
1061
+
1062
+ **Đường tròn** tâm $O$, bán kính $R$ (kí hiệu $(O; R)$) là tập hợp các điểm trong mặt phẳng cách điểm $O$ một khoảng bằng $R$.
1063
+
1064
+ **Vị trí tương đối của hai đường tròn**
1065
+ Cho hai đường tròn $(O; R)$ và $(O'; r)$ với $d = OO'$.
1066
+ * **Cắt nhau** (2 điểm chung): $|R-r| < d < R+r$
1067
+ * **Tiếp xúc nhau** (1 điểm chung):
1068
+ * Tiếp xúc ngoài: $d = R+r$
1069
+ * Tiếp xúc trong: $d = |R-r|$ ($R \neq r$)
1070
+ * **Không giao nhau** (0 điểm chung):
1071
+ * Ở ngoài nhau: $d > R+r$
1072
+ * Đựng nhau: $d < |R-r|$ ($R \neq r$)
1073
+
1074
+ ### §2. VỊ TRÍ TƯƠNG ĐỐI CỦA ĐƯỜNG THẲNG VÀ ĐƯỜNG TRÒN
1075
+
1076
+ Cho đường thẳng $a$ và đường tròn $(O; R)$. Gọi $d$ là khoảng cách từ $O$ đến $a$.
1077
+ * **Cắt nhau** (2 điểm chung): $d < R$
1078
+ * **Tiếp xúc nhau** (1 điểm chung): $d = R$. Đường thẳng $a$ được gọi là **tiếp tuyến**, điểm chung được gọi là **tiếp điểm**.
1079
+ * **Không giao nhau** (0 điểm chung): $d > R$
1080
+
1081
+ ### §3. TIẾP TUYẾN CỦA ĐƯỜNG TRÒN
1082
+
1083
+ **Tính chất:**
1084
+ * Nếu một đường thẳng là tiếp tuyến của một đường tròn thì nó vuông góc với bán kính đi qua tiếp điểm.
1085
+ * Nếu một đường thẳng đi qua một điểm của đường tròn và vuông góc với bán kính đi qua điểm đó thì đường thẳng ấy là một tiếp tuyến của đường tròn.
1086
+
1087
+ **Tính chất của hai tiếp tuyến cắt nhau:**
1088
+ Nếu hai tiếp tuyến của một đường tròn cắt nhau tại một điểm thì:
1089
+ * Điểm đó cách đều hai tiếp điểm.
1090
+ * Tia kẻ từ điểm đó đi qua tâm là tia phân giác của góc tạo bởi hai tiếp tuyến.
1091
+ * Tia kẻ từ tâm đi qua điểm đó là tia phân giác của góc tạo bởi hai bán kính đi qua các tiếp điểm.
1092
+
1093
+ ### §4. GÓC Ở TÂM. GÓC NỘI TIẾP
1094
+
1095
+ * **Góc ở tâm:** Góc có đỉnh trùng với tâm đường tròn.
1096
+ * **Số đo cung nhỏ** bằng số đo của góc ở tâm chắn cung đó.
1097
+ * **Số đo cung lớn** bằng $360^\circ$ trừ đi số đo cung nhỏ (có chung hai mút).
1098
+ * **Góc nội tiếp:** Góc có đỉnh nằm trên đường tròn và hai cạnh chứa hai dây cung của đường tròn đó.
1099
+ * Trong một đường tròn, số đo của góc nội tiếp bằng nửa số đo của cung bị chắn.
1100
+
1101
+ ### §5. ĐỘ DÀI CUNG TRÒN, DIỆN TÍCH HÌNH QUẠT TRÒN, DIỆN TÍCH HÌNH VÀNH KHUYÊN
1102
+
1103
+ Trên đường tròn bán kính $R$, độ dài $l$ của một cung $n^\circ$ được tính theo công thức:
1104
+ $l = \frac{\pi R n}{180}$
1105
+
1106
+ Diện tích $S$ của hình quạt tròn bán kính $R$, cung $n^\circ$ được tính theo công thức:
1107
+ $S = \frac{\pi R^2 n}{360}$ hoặc $S = \frac{lR}{2}$
1108
+
1109
+ **Hình vành khuyên** là phần hình phẳng giới hạn bởi hai đường tròn đồng tâm $(O; R)$ và $(O; r)$ với $R > r$.
1110
+ Diện tích hình vành khuyên: $S = \pi(R^2 - r^2)$.
1111
+
1112
+ ---
1113
+ # BÀI TẬP CUỐI CHƯƠNG V
1114
+
1115
+ 1. Trong Hình 92, cho các điểm A,B, C,D, E thuộc đường tròn $(O)$.
1116
+ a) Số đo góc BOC là...
1117
+ b) Số đo góc BDC là...
1118
+ c) Số đo góc BEC là...
1119
+
1120
+ 2. a) Độ dài cung tròn có số đo $30^\circ$ của đường tròn bán kính $R$ là:
1121
+ A. $\frac{\pi R}{180}$
1122
+ B. $\frac{\pi R}{360}$
1123
+ C. $30\pi R$
1124
+ D. $\frac{\pi R}{6}$
1125
+ b) Diện tích của hình quạt tròn tâm O, bán kính R, cung có số đo $45^\circ$ là:
1126
+ A. $\frac{\pi R^2}{45}$
1127
+ B. $\frac{\pi R^2}{4}$
1128
+ C. $\frac{\pi R^2}{8}$
1129
+ D. $\frac{\pi R^2}{16}$
1130
+
1131
+ 3. Cho hình vuông ABCD cạnh $r$ và đường tròn $(C; r)$. Giả sử $M$ là một điểm nằm trên đường tròn $(C; r)$ sao cho điểm $M$ nằm trong hình vuông $ABCD$. Tiếp tuyến của đường tròn $(C; r)$ tại tiếp điểm $M$ cắt các đoạn thẳng $AB, AD$ lần lượt tại $N$ và $P$. Chứng minh:
1132
+ a) Các đường thẳng NB, $PD$ là các tiếp tuyến của đường tròn $(C; r)$.
1133
+ b) $\widehat{NCP} = \widehat{NCB} + \widehat{PCD} = 45^\circ$.
1134
+
1135
+ 4. Chứng minh trong một đường tròn:
1136
+ a) Đường kính vuông góc với một dây thì đi qua trung điểm của dây ấy.
1137
+ b) Đường kính đi qua trung điểm của một dây không đi qua tâm thì vuông góc với dây ấy.
1138
+ c) Hai dây bằng nhau thì cách đều tâm.
1139
+ d) Hai dây cách đều tâm thì bằng nhau.
1140
+
1141
+ 5. Mặt đĩa CD có dạng hình vành khuyên giới hạn bởi hai đường tròn có bán kính lần lượt là 1,5 cm và 6 cm. Hình vành khuyên đó có diện tích bằng bao nhiêu centimét vuông?
1142
+
1143
+ 6. Logo có dạng một hình quạt tròn bán kính 8 cm và góc ở tâm bằng $60^\circ$. Tính diện tích mỗi hình sau:
1144
+ a) Toàn bộ logo.
1145
+ b) Phần logo màu đỏ có dạng hình viên phân.
1146
+
1147
+ ---
1148
+ ### BẢNG GIẢI THÍCH THUẬT NGỮ
1149
+
1150
+ | THUẬT NGỮ | GIẢI THÍCH | TRANG |
1151
+ | :--- | :--- | :--- |
1152
+ | **Bất đẳng thức** | Hệ thức dạng $a < b$ (hay $a > b, a \leq b, a \geq b$). | 29 |
1153
+ | **Bất phương trình bậc nhất một ẩn** | Bất phương trình dạng $ax+b > 0$ (hoặc $ax+b < 0, ax+b \geq 0, ax+b \leq 0$) với $a, b$ là hai số đã cho và $a \neq 0$. | 36 |
1154
+ | **Căn thức bậc ba** | Với A là một biểu thức đại số, người ta gọi $\sqrt[3]{A}$ là căn thức bậc ba của A. | 63 |
1155
+ | **Căn thức bậc hai** | Với A là một biểu thức đại số, người ta gọi $\sqrt{A}$ là căn thức bậc hai của A. | 61 |
1156
+ | **Đường tròn (O; R)** | Tập hợp các điểm trong mặt phẳng cách điểm O một khoảng bằng R. | 93 |
1157
+ | **Góc nội tiếp** | Góc có đỉnh thuộc đường tròn và hai cạnh chứa hai dây cung của đường tròn đó. | 115 |
1158
+ | **Góc ở tâm** | Góc có đỉnh trùng với tâm đường tròn. | 111 |
1159
+ | **Hệ hai phương trình bậc nhất hai ẩn** | Hệ phương trình có dạng $\begin{cases} ax + by = c \\ a'x + b'y = c' \end{cases}$ trong đó mỗi phương trình đều là phương trình bậc nhất hai ẩn. | 16 |
1160
+ | **Phương trình bậc nhất hai ẩn** | Phương trình có dạng $ax+by=c$, trong đó $a, b, c$ là những số cho trước, $a \neq 0$ hoặc $b \neq 0$. | 12 |
1161
+ | **Hình quạt tròn** | Một phần hình tròn giới hạn bởi một cung tròn và hai bán kính đi qua hai mút của cung. | 120 |
1162
+ | **Hình vành khuyên** | Hình giới hạn bởi hai đường tròn cùng tâm. | 122 |
1163
+ | **Tỉ số lượng giác của góc nhọn** | Cho góc nhọn $\alpha$. Xét tam giác ABC vuông tại A có $\widehat{B} = \alpha$. Tỉ số giữa cạnh đối và cạnh huyền được gọi là sin của góc $\alpha$, kí hiệu $\sin\alpha$. Tỉ số giữa cạnh kề và cạnh huyền được gọi là côsin của góc $\alpha$, kí hiệu $\cos\alpha$. Tỉ số giữa cạnh đối và cạnh kề được gọi là tang của góc $\alpha$, kí hiệu $\tan\alpha$. Tỉ số giữa cạnh kề và cạnh đối được gọi là côtang của góc $\alpha$, kí hiệu $\cot\alpha$. | 75 |
1164
+ | **Hai góc phụ nhau (tỉ số lượng giác)** | Nếu hai góc phụ nhau thì sin góc này bằng côsin góc kia, tang góc này bằng côtang góc kia. | 77 |
1165
+ | **Tiếp tuyến của đường tròn** | Đường thẳng đi qua một điểm của đường tròn và vuông góc với bán kính đi qua điểm đó. | 107 |
1166
+
1167
+ ---
1168
+ ### BẢNG TRA CỨU TỪ NGỮ
1169
+
1170
+ | TỪ NGỮ | TRANG |
1171
+ | :--- | :--- |
1172
+ | Bảo hiểm xã hội | 44 |
1173
+ | Bảo hiểm y tế | 45 |
1174
+ | Bất đẳng thức Cauchy | 71 |
1175
+ | Bất phương trình một ẩn | 35 |
1176
+ | Căn bậc ba | 51 |
1177
+ | Căn bậc hai | 48 |
1178
+ | Căn bậc hai của một tích | 56 |
1179
+ | Căn thức bậc hai của một bình phương | 67 |
1180
+ | Căn thức bậc hai của một thương | 68 |
1181
+ | Cung (hay cung tròn) | 112 |
1182
+ | Dây (hay dây cung) | 94 |
1183
+ | Diện tích hình quạt tròn | 119 |
1184
+ | Diện tích hình vành khuyên | 122 |
1185
+ | Độ dài cung tròn | 118 |
1186
+ | Đưa thừa số ra ngoài dấu căn bậc hai | 57 |
1187
+ | Đưa thừa số vào trong dấu căn bậc hai | 58 |
1188
+ | Đường thẳng và đường tròn cắt nhau | 101 |
1189
+ | Đường thẳng và đường tròn không giao nhau | 103 |
1190
+ | Đường thẳng và đường tròn tiếp xúc nhau | 102 |
1191
+ | Giải bất phương trình | 35 |
1192
+ | Giải hệ hai phương trình bậc nhất | 19 |
1193
+ | Giải hệ phương trình bằng phương pháp cộng đại số | 21 |
1194
+ | Giải hệ phương trình bằng phương pháp thế | 19 |
1195
+ | Giải tam giác vuông | 84 |
1196
+ | Hai đường tròn cắt nhau | 96 |
1197
+ | Hai đường tròn không giao nhau | 98 |
1198
+ | Hai đường tròn tiếp xúc nhau | 97 |
1199
+ | Phương trình chứa ẩn ở mẫu | 8 |
1200
+ | Phương trình tích | 5 |
1201
+ | Số đo của cung | 112 |
1202
+ | Thứ tự trong tập hợp số thực | 28 |
1203
+ | Tiếp điểm | 97 |
1204
+ | Tính chất hai tiếp tuyến cắt nhau | 108 |
1205
+ | Tính đối xứng của đường tròn | 95 |
1206
+ | Trục căn thức ở mẫu | 69 |
1207
+ | Ước lượng chiều cao | 89 |
1208
+
1209
+
1210
+ # Sách Giáo Khoa Toán 9 - Tập 2 (Cánh Diều)
1211
+
1212
+ **ĐỖ ĐỨC THÁI** (Tổng Chủ biên kiêm Chủ biên)
1213
+ LÊ TUẤN ANH - ĐỖ TIẾN ĐẠT - NGUYỄN SƠN HÀ
1214
+ NGUYỄN THỊ PHƯƠNG LOAN - PHẠM SỸ NAM - PHẠM ĐỨC QUANG
1215
+
1216
+ ---
1217
+
1218
+ # MỤC LỤC
1219
+
1220
+ | Chương | Nội dung | Trang |
1221
+ | :--- | :--- | :--- |
1222
+ | **VI** | **MỘT SỐ YẾU TỐ THỐNG KÊ VÀ XÁC SUẤT** | 3 |
1223
+ | | §1. Mô tả và biểu diễn dữ liệu trên các bảng, biểu đồ | 3 |
1224
+ | | §2. Tần số. Tần số tương đối | 16 |
1225
+ | | §3. Tần số ghép nhóm. Tần số tương đối ghép nhóm | 24 |
1226
+ | | §4. Phép thử ngẫu nhiên và không gian mẫu. Xác suất của biến cố | 35 |
1227
+ | | Bài tập cuối chương VI | 40 |
1228
+ | | **HOẠT ĐỘNG THỰC HÀNH VÀ TRẢI NGHIỆM** (Chủ đề 2. Mật độ dân số) | 43 |
1229
+ | **VII** | **HÀM SỐ $y=ax^2 (a \neq 0)$. PHƯƠNG TRÌNH BẬC HAI MỘT ẨN** | 46 |
1230
+ | | §1. Hàm số $y=ax^2 (a \neq 0)$ | 46 |
1231
+ | | §2. Phương trình bậc hai một ẩn | 52 |
1232
+ | | §3. Định lí Viète | 61 |
1233
+ | | Bài tập cuối chương VII | 66 |
1234
+ | **VIII** | **ĐƯỜNG TRÒN NGOẠI TIẾP VÀ ĐƯỜNG TRÒN NỘI TIẾP** | 68 |
1235
+ | | §1. Đường tròn ngoại tiếp tam giác. Đường tròn nội tiếp tam giác | 68 |
1236
+ | | §2. Tứ giác nội tiếp đường tròn | 75 |
1237
+ | | Bài tập cuối chương VIII | 79 |
1238
+ | **IX** | **ĐA GIÁC ĐỀU** | 80 |
1239
+ | | §1. Đa giác đều. Hình đa giác đều trong thực tiễn | 80 |
1240
+ | | §2. Phép quay | 86 |
1241
+ | | Bài tập cuối chương IX | 90 |
1242
+ | **X** | **HÌNH HỌC TRỰC QUAN** | 92 |
1243
+ | | §1. Hình trụ | 92 |
1244
+ | | §2. Hình nón | 98 |
1245
+ | | §3. Hình cầu | 104 |
1246
+ | | Bài tập cuối chương X | 109 |
1247
+ | | **HOẠT ĐỘNG THỰC HÀNH VÀ TRẢI NGHIỆM** (Chủ đề 3. Tạo đồ dùng dạng hình nón, hình trụ) | 111 |
1248
+ | | **THỰC HÀNH PHẦN MỀM GEOGEBRA** | 114 |
1249
+ | | **BẢNG GIẢI THÍCH THUẬT NGỮ** | 116 |
1250
+ | | **BẢNG TRA CỨU TỪ NGỮ** | 117 |
1251
+
1252
+ ---
1253
+
1254
+ # CHƯƠNG VI: MỘT SỐ YẾU TỐ THỐNG KÊ VÀ XÁC SUẤT
1255
+
1256
+ Trong chương này, chúng ta sẽ tìm hiểu những nội dung sau: mô tả và biểu diễn dữ liệu trên các bảng, biểu đồ; tần số, tần số tương đối; tần số ghép nhóm, tần số tương đối ghép nhóm; phép thử ngẫu nhiên và không gian mẫu, xác suất của biến cố trong một số trò chơi đơn giản.
1257
+
1258
+ ## §1. MÔ TẢ VÀ BIỂU DIỄN DỮ LIỆU TRÊN CÁC BẢNG, BIỂU ĐỒ
1259
+
1260
+ Ở các lớp dưới, chúng ta đã làm quen với việc biểu diễn, phân tích và xử lí dữ liệu thu được dạng bảng, biểu đồ thống kê.
1261
+
1262
+ ### I. BIỂU DIỄN DỮ LIỆU TRÊN BẢNG THỐNG KÊ, BIỂU ĐỒ TRANH
1263
+
1264
+ **Hoạt động 1** Một trường trung học cơ sở cho học sinh khối lớp 9 đăng kí tham gia các câu lạc bộ: Thể thao; Nghệ thuật; Tin học. Thống kê số lượng học sinh của từng lớp đăng kí tham gia các câu lạc bộ đó được cho trong bảng sau:
1265
+
1266
+ | Lớp \ Câu lạc bộ | Thể thao | Nghệ thuật | Tin học |
1267
+ | :--- | :--- | :--- | :--- |
1268
+ | 9A | 15 | 10 | 15 |
1269
+ | 9B | 20 | 5 | 15 |
1270
+ | 9C | 15 | 15 | 10 |
1271
+ | 9D | 20 | 10 | 10 |
1272
+
1273
+ Quan sát Bảng 1 và cho biết:
1274
+ a) Bảng 1 có bao nhiêu dòng và bao nhiêu cột?
1275
+ b) Cột đầu tiên, dòng đầu tiên lần lượt cho biết những dữ liệu thống kê nào?
1276
+ c) Các cột còn lại lần lượt cho biết những dữ liệu thống kê nào?
1277
+
1278
+ Để biểu diễn dữ liệu trên bảng thống kê, ta có thể làm như sau:
1279
+ * **Bước 1.** Các đối tượng thống kê lần lượt được biểu diễn ở cột đầu tiên, trong khi các tiêu chí thống kê lần lượt được biểu diễn ở dòng đầu tiên hoặc ngược lại.
1280
+ * **Bước 2.** Các số liệu thống kê theo tiêu chí của mỗi đối tượng thống kê lần lượt được biểu diễn ở dòng (hoặc cột) tương ứng.
1281
+
1282
+ **Ví dụ 1** Trị giá xuất khẩu hải sản (đơn vị: nghìn đô la Mỹ) của Việt Nam sang Cộng đồng các nước châu Âu (EU) trong các tháng 9, 10, 11, 12 của năm 2022 lần lượt như sau: 90 154; 89 412; 72 134; 81 904. (Nguồn: https://www.gso.gov.vn)
1283
+ Lập bảng thống kê biểu diễn các số liệu đó.
1284
+
1285
+ > **Giải**
1286
+ >
1287
+ > Bảng thống kê biểu diễn các số liệu đó như sau (Bảng 2):
1288
+ >
1289
+ > **Bảng 2**
1290
+ >
1291
+ > | Tháng | 9 | 10 | 11 | 12 |
1292
+ > | :--- | :--- | :--- | :--- | :--- |
1293
+ > | Trị giá xuất khẩu hải sản (nghìn đô la Mỹ) | 90 154 | 89 412 | 72 134 | 81 904 |
1294
+
1295
+ **Ví dụ 2** Bảng 3 thống kê khối lượng thanh long bán được trong các tháng 6, 7, 8, 9 năm 2022 của một hệ thống siêu thị.
1296
+
1297
+ **Bảng 3**
1298
+
1299
+ | Tháng | 6 | 7 | 8 | 9 |
1300
+ | :--- | :--- | :--- | :--- | :--- |
1301
+ | Khối lượng thanh long bán được (tạ) | 10 | 30 | 40 | 25 |
1302
+
1303
+ Vẽ biểu đồ tranh biểu diễn các số liệu đó.
1304
+
1305
+ > **Giải**
1306
+ >
1307
+ > Biểu đồ tranh biểu diễn các số liệu Bảng 3 được cho trong Hình 1.
1308
+ >
1309
+ > | Tháng 6 | 🍈 |
1310
+ > | :--- | :--- |
1311
+ > | Tháng 7 | 🍈🍈🍈 |
1312
+ > | Tháng 8 | 🍈🍈🍈🍈 |
1313
+ > | Tháng 9 | 🍈🍈 (nửa quả) |
1314
+ >
1315
+ > (Mỗi 🍈 biểu thị 10 tạ)
1316
+
1317
+ Để biểu diễn dữ liệu trên biểu đồ tranh, ta có thể làm như sau:
1318
+ * **Bước 1.** Các đối tượng thống kê được biểu diễn ở cột đầu tiên của bảng thống kê.
1319
+ * **Bước 2.** Chọn biểu tượng để biểu diễn số liệu thống kê. Các biểu tượng đó được trình bày ở dòng cuối cùng trong bảng thống kê.
1320
+ * **Bước 3.** Số liệu thống kê theo tiêu chí của mỗi đối tượng thống kê được biểu diễn bằng các biểu tượng ở dòng tương ứng trong bảng thống kê.
1321
+
1322
+ ### II. BIỂU DIỄN DỮ LIỆU TRÊN BIỂU ĐỒ CỘT, BIỂU ĐỒ CỘT KÉP
1323
+
1324
+ **Hoạt động 2** Biểu đồ Hình 2 biểu diễn lượng mưa tại trạm khí tượng Huế trong sáu tháng cuối năm dương lịch.
1325
+ a) Nêu các đối tượng thống kê và cho biết các đối tượng này lần lượt được biểu diễn ở trục nào.
1326
+ b) Nêu tiêu chí thống kê và cho biết tiêu chí đó được biểu diễn ở trục nào.
1327
+ c) Số liệu thống kê theo tiêu chí của mỗi đối tượng thống kê lần lượt được biểu diễn ở đâu?
1328
+ d) Lập bảng thống kê biểu diễn các dữ liệu thống kê nêu trong biểu đồ cột ở Hình 2.
1329
+
1330
+ Để biểu diễn dữ liệu trên biểu đồ cột, ta có thể làm như sau:
1331
+ * **Bước 1.** Vẽ hai trục vuông góc với nhau. Trên trục nằm ngang: biểu diễn các đối tượng thống kê. Trên trục thẳng đứng: xác định độ dài đơn vị để biểu diễn số liệu thống kê và cần chọn độ dài đơn vị thích hợp với số liệu.
1332
+ * **Bước 2.** Tại vị trí các đối tượng thống kê trên trục nằm ngang, vẽ những cột hình chữ nhật: cách đều nhau; có cùng chiều rộng; có chiều cao thể hiện số liệu thống kê theo tiêu chí của mỗi đối tượng thống kê.
1333
+ * **Bước 3.** Hoàn thiện biểu đồ: ghi tên các trục và ghi số liệu tương ứng trên mỗi cột (nếu cần).
1334
+
1335
+ **Ví dụ 3** Dựa theo Báo cáo của Tổ chức Y tế Thế giới, bạn An thống kê tuổi thọ trung bình của người dân Indonesia, Myanmar, Thái Lan, Việt Nam lần lượt là: 71,3 năm; 69,1 năm; 932,4 tháng; 75,4 năm.
1336
+ a) Nếu vẽ biểu đồ cột biểu diễn các số liệu đó thì số liệu nào được viết chưa hợp lí?
1337
+ b) Viết lại dãy số liệu thống kê đó rồi lập bảng thống kê và vẽ biểu đồ cột biểu diễn các số liệu đó.
1338
+
1339
+ > **Giải**
1340
+ >
1341
+ > a) Để vẽ biểu đồ cột biểu diễn các số liệu, các số liệu đó cần được tính theo cùng một đơn vị. Nếu các số liệu đó được tính theo đơn vị năm thì số liệu 932,4 tháng được viết chưa hợp lí.
1342
+ > b) $932,4 \text{ tháng} = 932,4 / 12 = 77,7 \text{ năm}$.
1343
+ > Tuổi thọ trung bình (đơn vị: năm) của người dân Indonesia, Myanmar, Thái Lan, Việt Nam lần lượt là: 71,3; 69,1; 77,7; 75,4.
1344
+ >
1345
+ > **Bảng 4**
1346
+ >
1347
+ > | Nước | Indonesia | Myanmar | Thái Lan | Việt Nam |
1348
+ > | :--- | :--- | :--- | :--- | :--- |
1349
+ > | Tuổi thọ trung bình (năm) | 71,3 | 69,1 | 77,7 | 75,4 |
1350
+
1351
+ **Hoạt động 3** Biểu đồ cột kép Hình 4 thống kê tổng sản phẩm trong nước (GDP) theo giá hiện hành của Việt Nam và Singapore trong các năm 2016, 2017, 2018, 2019.
1352
+ a) Nêu các đối tượng thống kê và cho biết các đối tượng này lần lượt được biểu diễn ở trục nào.
1353
+ b) Nêu tiêu chí thống kê và cho biết tiêu chí đó được biểu diễn ở trục nào.
1354
+ c) Số liệu thống kê theo tiêu chí của mỗi đối tượng thống kê lần lượt được biểu diễn ở đâu?
1355
+ d) Lập bảng thống kê biểu diễn các dữ liệu thống kê nêu trong biểu đồ cột kép Hình 4.
1356
+
1357
+ **Nhận xét:**
1358
+ Cách vẽ biểu đồ cột kép tương tự như cách vẽ biểu đồ cột. Nhưng tại vị trí ghi mỗi đối tượng trên trục ngang, ta vẽ hai cột sát nhau thể hiện hai loại số liệu của đối tượng đó. Các cột thể hiện số liệu theo cùng một tiêu chí thống kê của các đối tượng thường được tô cùng màu để thuận tiện cho việc đọc biểu đồ.
1359
+
1360
+ ### III. BIỂU DIỄN DỮ LIỆU TRÊN BIỂU ĐỒ ĐOẠN THẲNG
1361
+
1362
+ **Hoạt động 4** Biểu đồ đoạn thẳng Hình 6 biểu diễn lượng mưa trung bình sáu tháng cuối năm 2019 tại Thành phố Hồ Chí Minh.
1363
+ a) Nêu các đối tượng thống kê và cho biết các đối tượng này được biểu diễn ở trục nào.
1364
+ b) Nêu tiêu chí thống kê và cho biết tiêu chí đó được biểu diễn ở trục nào.
1365
+ c) Số liệu thống kê theo tiêu chí của mỗi đối tượng thống kê được biểu diễn ở đâu?
1366
+ d) Vẽ biểu đồ cột biểu diễn các dữ liệu thống kê nêu trong biểu đồ đoạn thẳng Hình 6.
1367
+
1368
+ Để biểu diễn dữ liệu trên biểu đồ đoạn thẳng, ta có thể làm như sau:
1369
+ * **Bước 1.** Vẽ hai trục vuông góc với nhau tại điểm O.
1370
+ * Trên trục nằm ngang: mỗi đối tượng thống kê được đánh dấu bằng một điểm và các điểm này thường được vẽ cách đều nhau.
1371
+ * Trên trục thẳng đứng: xác định độ dài đơn vị để biểu diễn số liệu thống kê và cần chọn độ dài đơn vị thích hợp với số liệu, đánh dấu điểm theo tiêu chí của đối tượng thống kê tương ứng.
1372
+ * **Bước 2.** Với mỗi đối tượng thống kê, ta tiếp tục:
1373
+ * Xác định điểm A đánh dấu số liệu thống kê trên trục thẳng đứng của đối tượng thống kê đó.
1374
+ * Kẻ bằng nét đứt một đoạn thẳng có độ dài bằng OA, vuông góc với trục nằm ngang và đi qua điểm đánh dấu đối tượng thống kê đó trên trục nằm ngang. Đầu mút trên của đoạn thẳng đó là điểm mốc của đối tượng thống kê.
1375
+ * **Bước 3.** Vẽ đường gấp khúc gồm các đoạn thẳng nối liền liên tiếp các điểm mốc.
1376
+ * **Bước 4.** Hoàn thiện biểu đồ: ghi tên các trục và ghi số liệu tương ứng trên mỗi điểm mốc (nếu cần).
1377
+
1378
+ Như vậy, mỗi điểm mốc được xác định bởi hai "tọa độ", trong đó "hoành độ" là điểm đánh dấu đối tượng thống kê, "tung độ" là số liệu thống kê theo tiêu chí của đối tượng đó.
1379
+
1380
+ ---
1381
+ # CHƯƠNG VII: HÀM SỐ $y=ax^2 (a \neq 0)$. PHƯƠNG TRÌNH BẬC HAI MỘT ẨN
1382
+
1383
+ ## §1. HÀM SỐ $y=ax^2 (a \neq 0)$
1384
+
1385
+ ### I. HÀM SỐ $y=ax^2 (a \neq 0)$
1386
+
1387
+ **Ví dụ 1** Một vật rơi tự do từ độ cao $100 \text{ m}$ so với mặt đất. Quãng đường chuyển động $s$ (mét) của vật phụ thuộc vào thời gian $t$ (giây) bởi công thức $s = 5t^2$.
1388
+ a) Tính quãng đường vật chuyển động được sau 1 giây, 2 giây, 3 giây.
1389
+ b) Sau bao lâu thì vật chạm đất?
1390
+
1391
+ > **Giải**
1392
+ >
1393
+ > a) Sau 1 giây: $s = 5 \cdot 1^2 = 5 \text{ m}$.
1394
+ > Sau 2 giây: $s = 5 \cdot 2^2 = 20 \text{ m}$.
1395
+ > Sau 3 giây: $s = 5 \cdot 3^2 = 45 \text{ m}$.
1396
+ >
1397
+ > b) Khi vật chạm đất, $s=100$. Ta có $100 = 5t^2 \implies t^2 = 20 \implies t = \sqrt{20} \approx 4,47$ (giây).
1398
+
1399
+ **Tính chất:**
1400
+ Hàm số $y=ax^2 (a \neq 0)$ xác định với mọi $x \in \mathbb{R}$.
1401
+ * Nếu $a>0$ thì hàm số đồng biến khi $x>0$ và nghịch biến khi $x<0$.
1402
+ * Nếu $a<0$ thì hàm số đồng biến khi $x<0$ và nghịch biến khi $x>0$.
1403
+
1404
+ ### II. ĐỒ THỊ CỦA HÀM SỐ $y=ax^2 (a \neq 0)$
1405
+
1406
+ Đồ thị của hàm số $y=ax^2 (a \neq 0)$ là một đường cong đi qua gốc toạ độ và nhận trục $Oy$ làm trục đối xứng. Đường cong đó được gọi là một **parabol** với đỉnh $O$.
1407
+ * Nếu $a>0$ thì đồ thị nằm phía trên trục hoành, $O$ là điểm thấp nhất của đồ thị.
1408
+ * Nếu $a<0$ thì đồ thị nằm phía dưới trục hoành, $O$ là điểm cao nhất của đồ thị.
1409
+
1410
+ ---
1411
+ ## §2. PHƯƠNG TRÌNH BẬC HAI MỘT ẨN
1412
+
1413
+ ### I. ĐỊNH NGHĨA
1414
+
1415
+ **Phương trình bậc hai một ẩn** (nói gọn là phương trình bậc hai) là phương trình có dạng $ax^2+bx+c=0$, trong đó $x$ là ẩn; $a, b, c$ là những số cho trước gọi là các hệ số và $a \neq 0$.
1416
+
1417
+ ### II. GIẢI PHƯƠNG TRÌNH
1418
+
1419
+ **Công thức nghiệm:**
1420
+ Đối với phương trình $ax^2+bx+c=0 (a \neq 0)$, ta có biệt thức $\Delta = b^2-4ac$.
1421
+ * Nếu $\Delta > 0$ thì phương trình có hai nghiệm phân biệt: $x_{1,2} = \frac{-b \pm \sqrt{\Delta}}{2a}$.
1422
+ * Nếu $\Delta = 0$ thì phương trình có nghiệm kép: $x_1 = x_2 = -\frac{b}{2a}$.
1423
+ * Nếu $\Delta < 0$ thì phương trình vô nghiệm.
1424
+
1425
+ **Công thức nghiệm thu gọn:**
1426
+ Đối với phương trình $ax^2+bx+c=0 (a \neq 0)$ và $b=2b'$, ta có biệt thức thu gọn $\Delta' = (b')^2-ac$.
1427
+ * Nếu $\Delta' > 0$ thì phương trình có hai nghiệm phân biệt: $x_{1,2} = \frac{-b' \pm \sqrt{\Delta'}}{a}$.
1428
+ * Nếu $\Delta' = 0$ thì phương trình có nghiệm kép: $x_1 = x_2 = -\frac{b'}{a}$.
1429
+ * Nếu $\Delta' < 0$ thì phương trình vô nghiệm.
1430
+
1431
+ ---
1432
+ ## §3. ĐỊNH LÍ VIÈTE
1433
+
1434
+ ### I. ĐỊNH LÍ VIÈTE
1435
+
1436
+ Nếu $x_1, x_2$ là hai nghiệm của phương trình $ax^2+bx+c=0 (a \neq 0)$ thì:
1437
+ $$
1438
+ \begin{cases}
1439
+ x_1 + x_2 = -\frac{b}{a} \\
1440
+ x_1 x_2 = \frac{c}{a}
1441
+ \end{cases}
1442
+ $$
1443
+
1444
+ **Nhận xét:**
1445
+ * Nếu phương trình $ax^2+bx+c=0 (a \neq 0)$ có $a+b+c=0$ thì phương trình có một nghiệm là $x_1=1$ và nghiệm còn lại là $x_2 = \frac{c}{a}$.
1446
+ * Nếu phương trình $ax^2+bx+c=0 (a \neq 0)$ có $a-b+c=0$ thì phương trình có một nghiệm là $x_1=-1$ và nghiệm còn lại là $x_2 = -\frac{c}{a}$.
1447
+
1448
+ ### II. TÌM HAI SỐ KHI BIẾT TỔNG VÀ TÍCH
1449
+
1450
+ Nếu hai số có tổng bằng $S$ và tích bằng $P$ thì hai số đó là nghiệm của phương trình $x^2 - Sx + P = 0$.
1451
+ (Điều kiện để có hai số đó là $S^2 - 4P \ge 0$).
1452
+
1453
+ ---
1454
+ # CHƯƠNG VIII: ĐƯỜNG TRÒN NGOẠI TIẾP VÀ ĐƯỜNG TRÒN NỘI TIẾP
1455
+
1456
+ ## §1. ĐƯỜNG TRÒN NGOẠI TIẾP TAM GIÁC. ĐƯỜNG TRÒN NỘI TIẾP TAM GIÁC
1457
+
1458
+ ### I. ĐƯỜNG TRÒN NGOẠI TIẾP TAM GIÁC
1459
+
1460
+ **Đường tròn ngoại tiếp tam giác** là đường tròn đi qua ba đỉnh của tam giác đó.
1461
+ * Tâm đường tròn ngoại tiếp tam giác là giao điểm ba đường trung trực của tam giác đó.
1462
+ * Tâm đường tròn ngoại tiếp tam giác vuông là trung điểm của cạnh huyền.
1463
+ * Trong một tam giác đều, trọng tâm của tam giác đồng thời là tâm đường tròn ngoại tiếp. Bán kính đường tròn ngoại tiếp tam giác đều cạnh $a$ là $R = \frac{a\sqrt{3}}{3}$.
1464
+
1465
+ ### II. ĐƯỜNG TRÒN NỘI TIẾP TAM GIÁC
1466
+
1467
+ **Đường tròn nội tiếp tam giác** là đường tròn tiếp xúc với ba cạnh của tam giác đó.
1468
+ * Tâm đường tròn nội tiếp tam giác là giao điểm ba đường phân giác của tam giác đó.
1469
+ * Trong một tam giác đều, trọng tâm của tam giác đồng thời là tâm đường tròn nội tiếp. Bán kính đường tròn nội tiếp tam giác đều cạnh $a$ là $r = \frac{a\sqrt{3}}{6}$.
1470
+
1471
+ ---
1472
+ ## §2. TỨ GIÁC NỘI TIẾP ĐƯỜNG TRÒN
1473
+
1474
+ ### I. ĐỊNH NGHĨA
1475
+
1476
+ **Tứ giác nội tiếp đường tròn** (hay tứ giác nội tiếp) là tứ giác có bốn đỉnh thuộc một đường tròn.
1477
+
1478
+ ### II. TÍNH CHẤT
1479
+
1480
+ Trong một tứ giác nội tiếp đường tròn, tổng số đo hai góc đối bằng $180^\circ$.
1481
+
1482
+ ### III. HÌNH CHỮ NHẬT, HÌNH VUÔNG NỘI TIẾP ĐƯỜNG TRÒN
1483
+
1484
+ * Mọi hình chữ nhật là một tứ giác nội tiếp đường tròn. Tâm của đường tròn ngoại tiếp hình chữ nhật là giao điểm của hai đường chéo.
1485
+ * Mọi hình vuông là một tứ giác nội tiếp đường tròn. Bán kính của đường tròn ngoại tiếp hình vuông cạnh $a$ là $R = \frac{a\sqrt{2}}{2}$.
1486
+
1487
+ ---
1488
+ # CHƯƠNG IX: ĐA GIÁC ĐỀU
1489
+
1490
+ ## §1. ĐA GIÁC ĐỀU. HÌNH ĐA GIÁC ĐỀU TRONG THỰC TIỄN
1491
+
1492
+ **Đa giác đều** là đa giác có tất cả các cạnh bằng nhau và tất cả các góc bằng nhau.
1493
+
1494
+ ---
1495
+ ## §2. PHÉP QUAY
1496
+
1497
+ **Phép quay** thuận chiều $\alpha^\circ$ ($0^\circ < \alpha^\circ < 360^\circ$) tâm $O$ giữ nguyên điểm $O$, biến điểm $M$ (khác $O$) thành điểm $M'$ thuộc đường tròn $(O; OM)$ sao cho tia $OM$ quay thuận chiều kim đồng hồ đến tia $OM'$ thì điểm $M$ tạo nên cung $MM'$ có số đo $\alpha^\circ$.
1498
+
1499
+ Phép quay giữ nguyên hình đa giác đều $A_1A_2...A_n$ là phép quay tâm $O$ (tâm của đa giác đều) biến mỗi đỉnh của hình đa giác đều thành một đỉnh của hình đa giác đều đó.
1500
+
1501
+ ---
1502
+ # CHƯƠNG X: HÌNH HỌC TRỰC QUAN
1503
+
1504
+ ## §1. HÌNH TRỤ
1505
+
1506
+ Hình được tạo ra khi quay một hình chữ nhật một vòng xung quanh đường thẳng cố định chứa một cạnh của nó là **hình trụ**.
1507
+ * Diện tích xung quanh: $S_{xq} = 2\pi rh$
1508
+ * Diện tích toàn phần: $S_{tp} = 2\pi rh + 2\pi r^2$
1509
+ * Thể tích: $V = \pi r^2 h$
1510
+ (Với $r$ là bán kính đáy, $h$ là chiều cao)
1511
+
1512
+ ## §2. HÌNH NÓN
1513
+
1514
+ Hình được tạo ra khi quay một hình tam giác vuông một vòng xung quanh đường thẳng cố định chứa một cạnh góc vuông của tam giác đó là **hình nón**.
1515
+ * Hệ thức: $l^2 = h^2 + r^2$
1516
+ * Diện tích xung quanh: $S_{xq} = \pi rl$
1517
+ * Diện tích toàn phần: $S_{tp} = \pi rl + \pi r^2$
1518
+ * Thể tích: $V = \frac{1}{3}\pi r^2 h$
1519
+ (Với $r$ là bán kính đáy, $h$ là chiều cao, $l$ là độ dài đường sinh)
1520
+
1521
+ ## §3. HÌNH CẦU
1522
+
1523
+ Hình được tạo ra khi quay một nửa hình tròn một vòng xung quanh đường thẳng cố định chứa đường kính của nó là **hình cầu**.
1524
+ * Diện tích mặt cầu: $S = 4\pi R^2$
1525
+ * Thể tích hình cầu: $V = \frac{4}{3}\pi R^3$
1526
+ (Với $R$ là bán kính của hình cầu)
1527
+
1528
+ ---
1529
+ ### BẢNG GIẢI THÍCH THUẬT NGỮ
1530
+
1531
+ | THUẬT NGỮ | GIẢI THÍCH | TRANG |
1532
+ | :--- | :--- | :--- |
1533
+ | **Đa giác đều** | Đa giác có tất cả các cạnh bằng nhau và tất cả các góc bằng nhau. | 82 |
1534
+ | **Đa giác lồi** | Đa giác luôn nằm về một phía của đường thẳng chứa một cạnh bất kì của đa giác đó. | 81 |
1535
+ | **Đường tròn ngoại tiếp tam giác** | Đường tròn đi qua ba đỉnh của tam giác. | 68 |
1536
+ | **Đường tròn nội tiếp tam giác** | Đường tròn tiếp xúc với ba cạnh của tam giác. | 71 |
1537
+ | **Hình cầu** | Hình được tạo ra khi quay một nửa hình tròn một vòng xung quanh đường thẳng cố định chứa đường kính của nó. | 104 |
1538
+ | **Hình nón** | Hình được tạo ra khi quay một hình tam giác vuông một vòng xung quanh đường thẳng cố định chứa một cạnh góc vuông của tam giác đó. | 98 |
1539
+ | **Hình trụ** | Hình được tạo ra khi quay một hình chữ nhật một vòng xung quanh đường thẳng cố định chứa một cạnh của nó. | 92 |
1540
+ | **Không gian mẫu** | Tập hợp gồm các kết quả có thể xảy ra của một phép thử. | 35 |
1541
+ | **Phương trình bậc hai một ẩn** | Phương trình có dạng $ax^2+bx+c=0$, trong đó $x$ là ẩn; $a, b, c$ là những số cho trước gọi là các hệ số và $a \neq 0$. | 52 |
1542
+ | **Tần số của giá trị $x_i$** | Số lần xuất hiện của giá trị $x_i$ trong mẫu dữ liệu thống kê. | 17 |
1543
+ | **Tần số ghép nhóm của m���t nhóm** | Số số liệu trong mẫu số liệu thuộc vào nhóm. | 26 |
1544
+ | **Tần số tương đối của $x_i$** | Tỉ số giữa tần số $n_i$ của giá trị $x_i$ và số lượng $N$ các dữ liệu trong mẫu dữ liệu thống kê. | 20 |
1545
+ | **Tần số tương đối ghép nhóm của một nhóm** | Tỉ số giữa tần số $n_i$ của nhóm và số lượng $N$ các số liệu trong mẫu dữ liệu thống kê. | 29 |
1546
+ | **Tứ giác nội tiếp** | Tứ giác có bốn đỉnh cùng thuộc một đường tròn. | 75 |
1547
+
1548
+ ---
1549
+ ### BẢNG TRA CỨU TỪ NGỮ
1550
+
1551
+ | TỪ NGỮ | TRANG |
1552
+ | :--- | :--- |
1553
+ | Bảng tần số | 16 |
1554
+ | Bảng tần số ghép nhóm | 26 |
1555
+ | Bảng tần số tương đối | 19 |
1556
+ | Bảng tần số tương đối ghép nhóm | 29 |
1557
+ | Biểu diễn dữ liệu trên bảng thống kê, biểu đồ tranh | 3 |
1558
+ | Biểu diễn dữ liệu trên biểu đồ cột, biểu đồ cột kép | 5 |
1559
+ | Biểu diễn dữ liệu trên biểu đồ đoạn thẳng | 8 |
1560
+ | Biểu diễn dữ liệu trên biểu đồ hình quạt tròn | 10 |
1561
+ | Biểu đồ tần số | 18 |
1562
+ | Biểu đồ tần số ghép nhóm | 26 |
1563
+ | Biểu đồ tần số tương đối | 21 |
1564
+ | Biểu đồ tần số tương đối ghép nhóm | 30 |
1565
+ | Diện tích mặt cầu | 105 |
1566
+ | Diện tích xung quanh của hình nón | 100 |
1567
+ | Diện tích xung quanh của hình trụ | 94 |
1568
+ | Đa giác | 80 |
1569
+ | Định lí Viète | 61 |
1570
+ | Đồ thị của hàm số $y=ax^2 (a \neq 0)$ | 47 |
1571
+ | Giải bài toán bằng cách lập phương trình bậc hai | 57 |
1572
+ | Giải phương trình bậc hai | 54 |
1573
+ | Hàm số $y=ax^2 (a \neq 0)$ | 46 |
1574
+ | Mẫu số liệu ghép nhóm | 24 |
1575
+ | Nửa khoảng | 25 |
1576
+ | Phép quay | 86 |
1577
+ | Phép thử ngẫu nhiên | 35 |
1578
+ | Phương trình bậc hai một ẩn | 52 |
1579
+ | Tạo đồ dùng dạng hình nón, hình trụ | 111 |
1580
+ | Tạo lập hình cầu | 105 |
1581
+ | Tạo lập hình nón | 99 |
1582
+ | Tạo lập hình trụ | 93 |
1583
+ | Tần số | 16 |
1584
+ | Tần số ghép nhóm | 26 |
1585
+ | Tần số tương đối | 19 |
1586
+ | Tần số tương đối ghép nhóm | 29 |
1587
+ | Thể tích của hình cầu | 107 |
1588
+ | Thể tích của hình nón | 102 |
1589
+ | Thể tích của hình trụ | 96 |
pages/multiagent_system.py ADDED
@@ -0,0 +1,759 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+ from supabase import create_client, Client
4
+ from datetime import datetime
5
+ import json
6
+
7
+ # Thiết lập page config
8
+ st.set_page_config(
9
+ page_title="Multi-Agent System - Gia sư Toán AI",
10
+ page_icon="🤖",
11
+ layout="wide"
12
+ )
13
+
14
+ def init_supabase_client() -> Client:
15
+ """
16
+ Khởi tạo Supabase client
17
+ """
18
+ url = os.getenv("SUPABASE_URL")
19
+ key = os.getenv("SUPABASE_KEY")
20
+
21
+ if not url or not key:
22
+ st.error("Không tìm thấy SUPABASE_URL hoặc SUPABASE_KEY trong file .env")
23
+ st.stop()
24
+
25
+ return create_client(url, key)
26
+
27
+ def display_system_architecture():
28
+ """
29
+ Hiển thị kiến trúc hệ thống
30
+ """
31
+ st.markdown("""
32
+ <div style='background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
33
+ padding: 2rem;
34
+ border-radius: 15px;
35
+ margin-bottom: 2rem;
36
+ text-align: center;'>
37
+ <h1 style='color: white; margin-bottom: 1rem; font-size: 2.5rem;'>
38
+ 🤖 An Adaptive Multi-Agent Tutoring System
39
+ </h1>
40
+ <p style='color: #f0f0f0; font-size: 1.2rem; margin-bottom: 0;'>
41
+ Hệ thống gia sư thông minh với kiến trúc đa tác nhân thích ứng
42
+ </p>
43
+ </div>
44
+ """, unsafe_allow_html=True)
45
+
46
+ # Placeholder cho hình ảnh system architecture
47
+ st.markdown("### 📊 Kiến trúc Hệ thống")
48
+
49
+ # Container cho hình ảnh với styling đẹp
50
+ with st.container():
51
+ col1, col2, col3 = st.columns([1, 3, 1])
52
+ with col2:
53
+ st.image("images/system.jpg", use_container_width=True)
54
+
55
+ def display_agents():
56
+ """
57
+ Hiển thị chi tiết từng Agent với giao diện hiện đại
58
+ """
59
+ # Header section
60
+ st.markdown("""
61
+ <div style="margin: 3rem 0 2rem 0;">
62
+ <h2 style="text-align: center; color: #333; margin-bottom: 0.5rem; font-size: 2.5rem;">
63
+ 🤖 Chi tiết các AI Agents
64
+ </h2>
65
+ <p style="text-align: center; color: #666; font-size: 1.1rem; margin-bottom: 2rem;">
66
+ Khám phá hệ sinh thái AI agents thông minh và chuyên biệt
67
+ </p>
68
+ </div>
69
+ """, unsafe_allow_html=True)
70
+
71
+ # CSS cho styling hiện đại
72
+ st.markdown("""
73
+ <style>
74
+ .agent-container {
75
+ background: white;
76
+ border-radius: 20px;
77
+ box-shadow: 0 10px 30px rgba(0,0,0,0.1);
78
+ margin-bottom: 2rem;
79
+ overflow: hidden;
80
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
81
+ border: 1px solid rgba(0,0,0,0.05);
82
+ }
83
+
84
+ .agent-container:hover {
85
+ transform: translateY(-5px);
86
+ box-shadow: 0 20px 40px rgba(0,0,0,0.15);
87
+ }
88
+
89
+ .agent-header {
90
+ padding: 2rem;
91
+ color: white;
92
+ position: relative;
93
+ overflow: hidden;
94
+ }
95
+
96
+ .agent-header::before {
97
+ content: '';
98
+ position: absolute;
99
+ top: 0;
100
+ left: 0;
101
+ right: 0;
102
+ bottom: 0;
103
+ background: rgba(255,255,255,0.1);
104
+ backdrop-filter: blur(10px);
105
+ z-index: 1;
106
+ }
107
+
108
+ .agent-header-content {
109
+ position: relative;
110
+ z-index: 2;
111
+ }
112
+
113
+ .agent-title {
114
+ display: flex;
115
+ align-items: center;
116
+ margin-bottom: 1rem;
117
+ font-size: 1.8rem;
118
+ font-weight: 600;
119
+ }
120
+
121
+ .agent-title-icon {
122
+ font-size: 2.5rem;
123
+ margin-right: 1rem;
124
+ filter: drop-shadow(0 2px 4px rgba(0,0,0,0.3));
125
+ }
126
+
127
+ .agent-role {
128
+ background: rgba(255,255,255,0.2);
129
+ padding: 1rem;
130
+ border-radius: 12px;
131
+ font-size: 1.1rem;
132
+ border: 1px solid rgba(255,255,255,0.3);
133
+ backdrop-filter: blur(5px);
134
+ }
135
+
136
+ .agent-body {
137
+ padding: 2rem;
138
+ background: #fafafa;
139
+ }
140
+
141
+ .agent-features {
142
+ background: white;
143
+ border-radius: 15px;
144
+ padding: 1.5rem;
145
+ box-shadow: 0 5px 15px rgba(0,0,0,0.05);
146
+ border: 1px solid rgba(0,0,0,0.05);
147
+ }
148
+
149
+ .features-title {
150
+ display: flex;
151
+ align-items: center;
152
+ margin-bottom: 1.5rem;
153
+ font-size: 1.3rem;
154
+ font-weight: 600;
155
+ color: #333;
156
+ }
157
+
158
+ .features-list {
159
+ list-style: none;
160
+ padding: 0;
161
+ margin: 0;
162
+ }
163
+
164
+ .feature-item {
165
+ padding: 0.8rem 0;
166
+ border-bottom: 1px solid rgba(0,0,0,0.05);
167
+ display: flex;
168
+ align-items: flex-start;
169
+ }
170
+
171
+ .feature-item:last-child {
172
+ border-bottom: none;
173
+ }
174
+
175
+ .feature-bullet {
176
+ width: 8px;
177
+ height: 8px;
178
+ border-radius: 50%;
179
+ margin-right: 1rem;
180
+ margin-top: 0.5rem;
181
+ flex-shrink: 0;
182
+ }
183
+
184
+ .feature-text {
185
+ flex: 1;
186
+ line-height: 1.6;
187
+ }
188
+
189
+ .feature-name {
190
+ font-weight: 600;
191
+ margin-right: 0.5rem;
192
+ }
193
+
194
+ .image-placeholder {
195
+ background: rgba(255,255,255,0.9);
196
+ border: 2px dashed #ddd;
197
+ border-radius: 15px;
198
+ padding: 2rem;
199
+ text-align: center;
200
+ height: 250px;
201
+ display: flex;
202
+ flex-direction: column;
203
+ justify-content: center;
204
+ align-items: center;
205
+ transition: all 0.3s ease;
206
+ backdrop-filter: blur(10px);
207
+ }
208
+
209
+ .image-placeholder:hover {
210
+ border-color: #999;
211
+ background: rgba(255,255,255,0.95);
212
+ }
213
+
214
+ .placeholder-icon {
215
+ font-size: 3rem;
216
+ margin-bottom: 1rem;
217
+ opacity: 0.7;
218
+ }
219
+
220
+ .placeholder-text {
221
+ font-weight: 600;
222
+ margin-bottom: 0.5rem;
223
+ color: #333;
224
+ }
225
+
226
+ .placeholder-path {
227
+ font-size: 0.9rem;
228
+ color: #666;
229
+ font-family: monospace;
230
+ background: rgba(0,0,0,0.05);
231
+ padding: 0.3rem 0.8rem;
232
+ border-radius: 20px;
233
+ }
234
+ </style>
235
+ """, unsafe_allow_html=True)
236
+
237
+ # Định nghĩa thông tin các agents
238
+ agents = [
239
+ {
240
+ "number": "1",
241
+ "name": "Informer Agent",
242
+ "icon": "🧠",
243
+ "gradient": "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
244
+ "color": "#667eea",
245
+ "role": "Chuyên gia giải toán với khả năng truy xuất thông tin thông minh",
246
+ "image": "images/informer_agent.png",
247
+ "features": [
248
+ "RAG Pipeline: Sử dụng Retrieval-Augmented Generation để tìm kiếm thông tin từ sách giáo khoa",
249
+ "Embedding Search: Tìm kiếm ngữ nghĩa thông minh với Vietnamese bi-encoder",
250
+ "Detailed Solutions: Sinh lời giải chi tiết, từng bước dễ hiểu",
251
+ "Context Awareness: Hiểu ngữ cảnh câu hỏi để đưa ra câu trả lời phù hợp"
252
+ ]
253
+ },
254
+ {
255
+ "number": "2",
256
+ "name": "Practice Agent",
257
+ "icon": "📝",
258
+ "gradient": "linear-gradient(135deg, #f093fb 0%, #f5576c 100%)",
259
+ "color": "#f093fb",
260
+ "role": "Chuyên gia tạo bài tập và đề xuất tài liệu học tập",
261
+ "image": "images/practice_agent.png",
262
+ "features": [
263
+ "Exercise Generation: Tạo bài tập mới phù hợp với điểm yếu của học sinh",
264
+ "Video Recommendation: Đề xuất video học tập từ knowledge base",
265
+ "Adaptive Difficulty: Điều chỉnh độ khó bài tập theo trình độ",
266
+ "Creative Problems: Soạn câu hỏi sáng tạo, không có trong sách"
267
+ ]
268
+ },
269
+ {
270
+ "number": "3",
271
+ "name": "Insight Agent",
272
+ "icon": "🔍",
273
+ "gradient": "linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)",
274
+ "color": "#4facfe",
275
+ "role": "Chuyên gia phân tích tâm lý và học tập của học sinh",
276
+ "image": "images/insight_agent.png",
277
+ "features": [
278
+ "Weakness Analysis: Phân tích điểm yếu từ lịch sử hội thoại",
279
+ "Sentiment Detection: Nhận diện cảm xúc và tâm trạng học sinh",
280
+ "Learning Pattern: Phát hiện patterns trong cách học của học sinh",
281
+ "Personalized Insights: Đưa ra những insight cá nhân hóa"
282
+ ]
283
+ },
284
+ {
285
+ "number": "4",
286
+ "name": "Verifier Agent",
287
+ "icon": "✅",
288
+ "gradient": "linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)",
289
+ "color": "#a8edea",
290
+ "role": "Chuyên gia kiểm tra chất lượng và tính chính xác",
291
+ "image": "images/verifier_agent.png",
292
+ "features": [
293
+ "Solution Verification: Kiểm tra tính đúng đắn của lời giải",
294
+ "Error Detection: Phát hiện và chỉ ra lỗi sai",
295
+ "Quality Assurance: Đảm bảo chất lượng câu trả lời",
296
+ "Correction Suggestions: Đưa ra gợi ý sửa lỗi"
297
+ ]
298
+ },
299
+ {
300
+ "number": "5",
301
+ "name": "Tutor Agent (Orchestrator)",
302
+ "icon": "🎯",
303
+ "gradient": "linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%)",
304
+ "color": "#fcb69f",
305
+ "role": "Trung tâm điều phối và quản lý toàn bộ hệ thống",
306
+ "image": "images/tutor_agent.png",
307
+ "features": [
308
+ "Intent Classification: Phân loại ý định người dùng (greeting, math_question, practice, stress, etc.)",
309
+ "Agent Orchestration: Điều phối các agent khác theo luồng phù hợp",
310
+ "Conversation Management: Quản lý bối cảnh và luồng hội thoại",
311
+ "Proactive Learning: Chủ động đề xuất bài tập khi phát hiện cơ hội",
312
+ "Emotional Support: Hỗ trợ tâm lý khi học sinh gặp khó khăn"
313
+ ]
314
+ }
315
+ ]
316
+
317
+ # Hiển thị từng agent
318
+ for i, agent in enumerate(agents):
319
+ # Container chính
320
+ st.markdown(f"""
321
+ <div class="agent-container">
322
+ <div class="agent-header" style="background: {agent['gradient']};">
323
+ <div class="agent-header-content">
324
+ <div class="agent-title">
325
+ <span class="agent-title-icon">{agent['icon']}</span>
326
+ <span>Agent {agent['number']}: {agent['name']}</span>
327
+ </div>
328
+ <div class="agent-role">
329
+ <strong>Vai trò:</strong> {agent['role']}
330
+ </div>
331
+ </div>
332
+ </div>
333
+ """, unsafe_allow_html=True)
334
+
335
+ # Body với layout 2 cột
336
+ col1, col2 = st.columns([2, 1])
337
+
338
+ with col1:
339
+ st.markdown(f"""
340
+ <div class="agent-body">
341
+ <div class="agent-features">
342
+ <div class="features-title">
343
+ <span style="margin-right: 0.5rem;">🔧</span>
344
+ <span>Chức năng chính</span>
345
+ </div>
346
+ <ul class="features-list">
347
+ """, unsafe_allow_html=True)
348
+
349
+ for feature in agent['features']:
350
+ parts = feature.split(': ', 1)
351
+ if len(parts) == 2:
352
+ st.markdown(f"""
353
+ <li class="feature-item">
354
+ <div class="feature-bullet" style="background: {agent['color']};"></div>
355
+ <div class="feature-text">
356
+ <span class="feature-name" style="color: {agent['color']};">{parts[0]}:</span>
357
+ <span>{parts[1]}</span>
358
+ </div>
359
+ </li>
360
+ """, unsafe_allow_html=True)
361
+ else:
362
+ st.markdown(f"""
363
+ <li class="feature-item">
364
+ <div class="feature-bullet" style="background: {agent['color']};"></div>
365
+ <div class="feature-text">{feature}</div>
366
+ </li>
367
+ """, unsafe_allow_html=True)
368
+
369
+ st.markdown("""
370
+ </ul>
371
+ </div>
372
+ </div>
373
+ """, unsafe_allow_html=True)
374
+
375
+ with col2:
376
+
377
+ try:
378
+ st.image(agent['image'], use_container_width=True, caption=f"Agent {agent['number']}: {agent['name']}")
379
+ except:
380
+ st.markdown(f"""
381
+ <div class="agent-body">
382
+ <div class="image-placeholder">
383
+ <div class="placeholder-icon" style="color: {agent['color']};">{agent['icon']}</div>
384
+ <div class="placeholder-text">Agent {agent['number']} Image</div>
385
+ <div class="placeholder-path">{agent['image']}</div>
386
+ </div>
387
+ </div>
388
+ """, unsafe_allow_html=True)
389
+
390
+ # Đóng container
391
+ st.markdown("</div>", unsafe_allow_html=True)
392
+
393
+ # Spacing giữa các agents
394
+ if i < len(agents) - 1:
395
+ st.markdown("<div style='margin: 3rem 0;'></div>", unsafe_allow_html=True)
396
+
397
+ def display_system_components():
398
+ """
399
+ Hiển thị các thành phần của hệ thống
400
+ """
401
+ st.markdown("## 🏗️ Các Thành phần Hệ thống")
402
+
403
+ # Orchestration Hub
404
+ with st.container():
405
+ st.markdown("""
406
+ <div style='background: linear-gradient(135deg, #56ab2f 0%, #a8e6cf 100%);
407
+ padding: 1.5rem;
408
+ border-radius: 10px;
409
+ margin-bottom: 1rem;'>
410
+ <h3 style='color: white; margin-bottom: 0.5rem;'>
411
+ 🎯 Orchestration Hub
412
+ </h3>
413
+ <p style='color: #f0f0f0; margin-bottom: 0;'>
414
+ Trung tâm điều phối và quản lý tất cả các tác nhân trong hệ thống
415
+ </p>
416
+ </div>
417
+ """, unsafe_allow_html=True)
418
+
419
+ # Hai flows chính
420
+ col1, col2 = st.columns(2)
421
+
422
+ with col1:
423
+ st.markdown("""
424
+ <div style='background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
425
+ padding: 1.5rem;
426
+ border-radius: 10px;
427
+ margin-bottom: 1rem;'>
428
+ <h3 style='color: #8B0000; margin-bottom: 1rem;'>
429
+ 📝 Flow A: Problem-Solving
430
+ </h3>
431
+ <div style='background: rgba(255,255,255,0.2); padding: 1rem; border-radius: 8px;'>
432
+ <h4 style='color: #8B0000; margin-bottom: 0.5rem;'>RAG & Verification</h4>
433
+ <ul style='color: #2F4F4F; margin-bottom: 0;'>
434
+ <li>Xử lý truy vấn RAG</li>
435
+ <li>Giải quyết yêu cầu</li>
436
+ <li>Xác thực và soạn thảo</li>
437
+ <li>Cung cấp câu trả lời cuối cùng</li>
438
+ </ul>
439
+ </div>
440
+ </div>
441
+ """, unsafe_allow_html=True)
442
+
443
+ with col2:
444
+ st.markdown("""
445
+ <div style='background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
446
+ padding: 1.5rem;
447
+ border-radius: 10px;
448
+ margin-bottom: 1rem;'>
449
+ <h3 style='color: #2F4F4F; margin-bottom: 1rem;'>
450
+ 🎯 Flow B: Personalization
451
+ </h3>
452
+ <div style='background: rgba(255,255,255,0.2); padding: 1rem; border-radius: 8px;'>
453
+ <h4 style='color: #2F4F4F; margin-bottom: 0.5rem;'>Learning Engine</h4>
454
+ <ul style='color: #2F4F4F; margin-bottom: 0;'>
455
+ <li>Phân tích thông tin người dùng</li>
456
+ <li>Gửi chủ đề phù hợp</li>
457
+ <li>Truy vấn dữ liệu</li>
458
+ <li>Tạo bài tập cá nhân hóa</li>
459
+ </ul>
460
+ </div>
461
+ </div>
462
+ """, unsafe_allow_html=True)
463
+
464
+ def display_workflow_details():
465
+ """
466
+ Hiển thị chi tiết quy trình làm việc
467
+ """
468
+ st.markdown("## 🔄 Quy trình Hoạt động")
469
+
470
+ # Workflow steps
471
+ workflow_steps = [
472
+ {
473
+ "step": "1",
474
+ "title": "Nhận câu hỏi từ học sinh",
475
+ "description": "Hệ thống nhận và phân tích câu hỏi từ người dùng",
476
+ "icon": "❓",
477
+ "color": "#FF6B6B"
478
+ },
479
+ {
480
+ "step": "2",
481
+ "title": "Orchestration Hub phân tích",
482
+ "description": "Trung tâm điều phối quyết định luồng xử lý phù hợp",
483
+ "icon": "🎯",
484
+ "color": "#4ECDC4"
485
+ },
486
+ {
487
+ "step": "3",
488
+ "title": "Xử lý song song",
489
+ "description": "Flow A giải quyết vấn đề, Flow B cá nhân hóa trải nghiệm",
490
+ "icon": "⚡",
491
+ "color": "#45B7D1"
492
+ },
493
+ {
494
+ "step": "4",
495
+ "title": "Cập nhật hồ sơ học sinh",
496
+ "description": "Hệ thống cập nhật thông tin học tập và điểm yếu",
497
+ "icon": "📊",
498
+ "color": "#96CEB4"
499
+ },
500
+ {
501
+ "step": "5",
502
+ "title": "Trả lời cuối cùng",
503
+ "description": "Cung cấp câu trả lời được xác thực và cá nhân hóa",
504
+ "icon": "✅",
505
+ "color": "#FECA57"
506
+ }
507
+ ]
508
+
509
+ for i, step in enumerate(workflow_steps):
510
+ # Tạo layout cho từng bước
511
+ col1, col2 = st.columns([1, 4])
512
+
513
+ with col1:
514
+ st.markdown(f"""
515
+ <div style='width: 80px;
516
+ height: 80px;
517
+ background: {step['color']};
518
+ border-radius: 50%;
519
+ display: flex;
520
+ align-items: center;
521
+ justify-content: center;
522
+ margin: 0 auto;'>
523
+ <span style='font-size: 2rem;'>{step['icon']}</span>
524
+ </div>
525
+ """, unsafe_allow_html=True)
526
+
527
+ with col2:
528
+ st.markdown(f"""
529
+ <div style='background: linear-gradient(135deg, {step['color']}20, {step['color']}10);
530
+ padding: 1rem;
531
+ border-radius: 10px;
532
+ margin-bottom: 1rem;
533
+ border-left: 4px solid {step['color']};'>
534
+ <h4 style='color: #333; margin-bottom: 0.5rem;'>
535
+ Bước {step['step']}: {step['title']}
536
+ </h4>
537
+ <p style='color: #666; margin-bottom: 0;'>
538
+ {step['description']}
539
+ </p>
540
+ </div>
541
+ """, unsafe_allow_html=True)
542
+
543
+ # Thêm mũi tên giữa các bước (trừ bước cuối)
544
+ if i < len(workflow_steps) - 1:
545
+ st.markdown("""
546
+ <div style='text-align: center; margin: 1rem 0;'>
547
+ <span style='font-size: 2rem; color: #ccc;'>⬇️</span>
548
+ </div>
549
+ """, unsafe_allow_html=True)
550
+
551
+ def display_technical_features():
552
+ """
553
+ Hiển thị các tính năng kỹ thuật
554
+ """
555
+ st.markdown("## 🛠️ Tính năng Kỹ thuật")
556
+
557
+ col1, col2 = st.columns(2)
558
+
559
+ with col1:
560
+ st.markdown("""
561
+ <div style='background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
562
+ padding: 1.5rem;
563
+ border-radius: 10px;
564
+ margin-bottom: 1rem;'>
565
+ <h4 style='color: white; margin-bottom: 1rem;'>
566
+ 🔍 RAG (Retrieval-Augmented Generation)
567
+ </h4>
568
+ <ul style='color: #f0f0f0; margin-bottom: 0;'>
569
+ <li>Truy xuất thông tin từ cơ sở dữ liệu</li>
570
+ <li>Tăng cường khả năng sinh text</li>
571
+ <li>Đảm bảo tính chính xác cao</li>
572
+ <li>Xác thực câu trả lời</li>
573
+ </ul>
574
+ </div>
575
+ """, unsafe_allow_html=True)
576
+
577
+ st.markdown("""
578
+ <div style='background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
579
+ padding: 1.5rem;
580
+ border-radius: 10px;
581
+ margin-bottom: 1rem;'>
582
+ <h4 style='color: white; margin-bottom: 1rem;'>
583
+ 🎯 Personalization Engine
584
+ </h4>
585
+ <ul style='color: #f0f0f0; margin-bottom: 0;'>
586
+ <li>Phân tích điểm yếu học sinh</li>
587
+ <li>Tạo bài tập cá nhân hóa</li>
588
+ <li>Theo dõi tiến độ học tập</li>
589
+ <li>Đề xuất nội dung phù hợp</li>
590
+ </ul>
591
+ </div>
592
+ """, unsafe_allow_html=True)
593
+
594
+ with col2:
595
+ st.markdown("""
596
+ <div style='background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
597
+ padding: 1.5rem;
598
+ border-radius: 10px;
599
+ margin-bottom: 1rem;'>
600
+ <h4 style='color: white; margin-bottom: 1rem;'>
601
+ 🧠 Adaptive Learning
602
+ </h4>
603
+ <ul style='color: #f0f0f0; margin-bottom: 0;'>
604
+ <li>Học thích ứng theo năng lực</li>
605
+ <li>Điều chỉnh độ khó tự động</li>
606
+ <li>Phản hồi thời gian thực</li>
607
+ <li>Tối ưu hóa trải nghiệm</li>
608
+ </ul>
609
+ </div>
610
+ """, unsafe_allow_html=True)
611
+
612
+ st.markdown("""
613
+ <div style='background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
614
+ padding: 1.5rem;
615
+ border-radius: 10px;
616
+ margin-bottom: 1rem;'>
617
+ <h4 style='color: white; margin-bottom: 1rem;'>
618
+ 📊 User Profile Management
619
+ </h4>
620
+ <ul style='color: #f0f0f0; margin-bottom: 0;'>
621
+ <li>Lưu trữ lịch sử học tập</li>
622
+ <li>Phân tích pattern học tập</li>
623
+ <li>Cập nhật thông tin real-time</li>
624
+ <li>Báo cáo tiến độ chi tiết</li>
625
+ </ul>
626
+ </div>
627
+ """, unsafe_allow_html=True)
628
+
629
+ def display_benefits():
630
+ """
631
+ Hiển thị lợi ích của hệ thống
632
+ """
633
+ st.markdown("## 🌟 Lợi ích của Hệ thống")
634
+
635
+ benefits = [
636
+ {
637
+ "icon": "🎯",
638
+ "title": "Học tập cá nhân hóa",
639
+ "description": "Mỗi học sinh nhận được trải nghiệm học tập được tùy chỉnh theo nhu cầu riêng",
640
+ "color": "#FF6B6B"
641
+ },
642
+ {
643
+ "icon": "⚡",
644
+ "title": "Phản hồi tức thì",
645
+ "description": "Hệ thống đa tác nhân cho phép xử lý song song, đưa ra phản hồi nhanh chóng",
646
+ "color": "#4ECDC4"
647
+ },
648
+ {
649
+ "icon": "🧠",
650
+ "title": "Học thích ứng thông minh",
651
+ "description": "AI phân tích và điều chỉnh phương pháp dạy theo tiến bộ của từng học sinh",
652
+ "color": "#45B7D1"
653
+ },
654
+ {
655
+ "icon": "📊",
656
+ "title": "Theo dõi tiến độ chi tiết",
657
+ "description": "Báo cáo và phân tích tiến độ học tập giúp tối ưu hóa quá trình học",
658
+ "color": "#96CEB4"
659
+ },
660
+ {
661
+ "icon": "🔍",
662
+ "title": "Độ chính xác cao",
663
+ "description": "Hệ thống RAG và xác thực đảm bảo thông tin chính xác và đáng tin cậy",
664
+ "color": "#FECA57"
665
+ },
666
+ {
667
+ "icon": "🌐",
668
+ "title": "Mở rộng dễ dàng",
669
+ "description": "Kiến trúc đa tác nhân cho phép mở rộng và thêm tính năng mới linh hoạt",
670
+ "color": "#FF9FF3"
671
+ }
672
+ ]
673
+
674
+ # Hiển thị benefits trong lưới 2x3
675
+ for i in range(0, len(benefits), 2):
676
+ col1, col2 = st.columns(2)
677
+
678
+ with col1:
679
+ if i < len(benefits):
680
+ benefit = benefits[i]
681
+ st.markdown(f"""
682
+ <div style='background: linear-gradient(135deg, {benefit['color']}20, {benefit['color']}10);
683
+ padding: 1.5rem;
684
+ border-radius: 10px;
685
+ margin-bottom: 1rem;
686
+ border-left: 4px solid {benefit['color']};
687
+ height: 150px;'>
688
+ <div style='display: flex; align-items: center; margin-bottom: 0.5rem;'>
689
+ <span style='font-size: 2rem; margin-right: 0.5rem;'>{benefit['icon']}</span>
690
+ <h4 style='color: #333; margin: 0;'>{benefit['title']}</h4>
691
+ </div>
692
+ <p style='color: #666; margin: 0; font-size: 0.9rem;'>
693
+ {benefit['description']}
694
+ </p>
695
+ </div>
696
+ """, unsafe_allow_html=True)
697
+
698
+ with col2:
699
+ if i + 1 < len(benefits):
700
+ benefit = benefits[i + 1]
701
+ st.markdown(f"""
702
+ <div style='background: linear-gradient(135deg, {benefit['color']}20, {benefit['color']}10);
703
+ padding: 1.5rem;
704
+ border-radius: 10px;
705
+ margin-bottom: 1rem;
706
+ border-left: 4px solid {benefit['color']};
707
+ height: 150px;'>
708
+ <div style='display: flex; align-items: center; margin-bottom: 0.5rem;'>
709
+ <span style='font-size: 2rem; margin-right: 0.5rem;'>{benefit['icon']}</span>
710
+ <h4 style='color: #333; margin: 0;'>{benefit['title']}</h4>
711
+ </div>
712
+ <p style='color: #666; margin: 0; font-size: 0.9rem;'>
713
+ {benefit['description']}
714
+ </p>
715
+ </div>
716
+ """, unsafe_allow_html=True)
717
+
718
+ def main():
719
+ """
720
+ Hàm chính của trang Multi-Agent System
721
+ """
722
+ # Hiển thị kiến trúc hệ thống
723
+ display_system_architecture()
724
+
725
+ # Hiển thị các tác nhân
726
+ display_agents()
727
+
728
+ # Hiển thị các thành phần hệ thống
729
+ display_system_components()
730
+
731
+ # Hiển thị quy trình hoạt động
732
+ display_workflow_details()
733
+
734
+ # Hiển thị tính năng kỹ thuật
735
+ display_technical_features()
736
+
737
+ # Hiển thị lợi ích
738
+ display_benefits()
739
+
740
+ # Footer
741
+ st.markdown("---")
742
+ st.markdown("""
743
+ <div style='text-align: center;
744
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
745
+ padding: 2rem;
746
+ border-radius: 15px;
747
+ margin-top: 2rem;'>
748
+ <h3 style='color: white; margin-bottom: 1rem;'>
749
+ 🚀 Trải nghiệm Hệ thống Multi-Agent ngay hôm nay!
750
+ </h3>
751
+ <p style='color: #f0f0f0; font-size: 1.1rem; margin-bottom: 0;'>
752
+ Hệ thống gia sư AI thông minh với kiến trúc đa tác nhân tiên tiến,
753
+ mang đến trải nghiệm học tập cá nhân hóa và hiệu quả nhất.
754
+ </p>
755
+ </div>
756
+ """, unsafe_allow_html=True)
757
+
758
+ if __name__ == "__main__":
759
+ main()
pages/profile.py ADDED
@@ -0,0 +1,467 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from datetime import datetime, timezone, timedelta
3
+ from supabase_utils import init_supabase_client, get_user_profile
4
+ import time
5
+
6
+ # Thiết lập page config
7
+ st.set_page_config(
8
+ page_title="Hồ sơ Học tập - Gia sư Toán AI",
9
+ page_icon="👤",
10
+ layout="wide"
11
+ )
12
+
13
+ def display_header(user_email: str, user_id: str, profile: dict):
14
+ """
15
+ Hiển thị header với thông tin người dùng
16
+ """
17
+ st.markdown("""
18
+ <div style='background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
19
+ padding: 2rem;
20
+ border-radius: 15px;
21
+ margin-bottom: 2rem;'>
22
+ <h1 style='color: white; margin-bottom: 1rem; font-size: 2.5rem; text-align: center;'>
23
+ 👤 Hồ sơ Học tập của bạn
24
+ </h1>
25
+ <p style='color: #f0f0f0; font-size: 1.2rem; text-align: center; margin-bottom: 0;'>
26
+ Theo dõi tiến trình và điểm yếu cần cải thiện
27
+ </p>
28
+ </div>
29
+ """, unsafe_allow_html=True)
30
+
31
+ # Thông tin người dùng trong cards
32
+ col1, col2 = st.columns(2)
33
+
34
+ with col1:
35
+ st.markdown(f"""
36
+ <div style='background: linear-gradient(135deg, #56ab2f 0%, #a8e6cf 100%);
37
+ padding: 1.5rem;
38
+ border-radius: 10px;
39
+ margin-bottom: 1rem;'>
40
+ <h3 style='color: white; margin-bottom: 0.5rem; display: flex; align-items: center;'>
41
+ <span style='font-size: 1.5rem; margin-right: 0.5rem;'>📧</span>
42
+ Email
43
+ </h3>
44
+ <p style='color: #f0f0f0; margin-bottom: 0; font-size: 1.1rem;'>
45
+ {user_email}
46
+ </p>
47
+ </div>
48
+ """, unsafe_allow_html=True)
49
+
50
+ with col2:
51
+ updated_time = "Chưa có dữ liệu"
52
+ if profile.get("updated_at"):
53
+ try:
54
+ updated_at_str = str(profile["updated_at"])
55
+ updated_dt = None
56
+
57
+ try:
58
+ if 'T' in updated_at_str and '+00:00' in updated_at_str:
59
+ if '.' in updated_at_str:
60
+ dt_part, tz_part = updated_at_str.split('+')
61
+ if '.' in dt_part:
62
+ main_dt, microsec = dt_part.split('.')
63
+ microsec = microsec[:6].ljust(6, '0')
64
+ clean_dt_str = f"{main_dt}.{microsec}+{tz_part}"
65
+ else:
66
+ clean_dt_str = f"{dt_part}+{tz_part}"
67
+ else:
68
+ clean_dt_str = updated_at_str
69
+ updated_dt = datetime.fromisoformat(clean_dt_str)
70
+ elif updated_at_str.endswith('Z'):
71
+ updated_dt = datetime.fromisoformat(updated_at_str.replace("Z", "+00:00"))
72
+ elif '+' in updated_at_str and ':' in updated_at_str[-6:]:
73
+ updated_dt = datetime.fromisoformat(updated_at_str)
74
+
75
+ elif '+' in updated_at_str:
76
+
77
+ updated_dt = datetime.strptime(updated_at_str.split('+')[0], '%Y-%m-%d %H:%M:%S')
78
+
79
+ else:
80
+ updated_dt = datetime.fromisoformat(updated_at_str)
81
+ except ValueError as ve:
82
+ print(f"DEBUG: [Profile] ISO parsing failed: {ve}")
83
+
84
+ try:
85
+ # Format: "2024-01-01 12:00:00"
86
+ updated_dt = datetime.strptime(updated_at_str, '%Y-%m-%d %H:%M:%S')
87
+ except ValueError:
88
+ # Format: "2024-01-01T12:00:00"
89
+ updated_dt = datetime.strptime(updated_at_str, '%Y-%m-%dT%H:%M:%S')
90
+
91
+ if updated_dt:
92
+ # Chuyển đổi từ UTC sang múi giờ Việt Nam (UTC+7)
93
+ if updated_dt.tzinfo is not None:
94
+ # Nếu có timezone info, chuyển sang UTC+7
95
+ vietnam_tz = timezone(timedelta(hours=7))
96
+ vietnam_time = updated_dt.astimezone(vietnam_tz)
97
+ updated_time = vietnam_time.strftime('%d/%m/%Y %H:%M:%S')
98
+ else:
99
+ # Nếu không có timezone info, giả sử đây là UTC và thêm 7 giờ
100
+ vietnam_time = updated_dt + timedelta(hours=7)
101
+ updated_time = vietnam_time.strftime('%d/%m/%Y %H:%M:%S')
102
+
103
+ print(f"DEBUG: [Profile] Original UTC: {updated_dt}")
104
+ print(f"DEBUG: [Profile] Vietnam time: {updated_time}")
105
+ else:
106
+ updated_time = "Không thể parse"
107
+
108
+ except Exception as e:
109
+ print(f"DEBUG: [Profile] Failed to parse updated_at: {e}")
110
+ # Fallback: Hiển thị raw value
111
+ updated_time = f"Raw: {str(profile['updated_at'])[:19]}"
112
+
113
+ st.markdown(f"""
114
+ <div style='background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
115
+ padding: 1.5rem;
116
+ border-radius: 10px;
117
+ margin-bottom: 1rem;'>
118
+ <h3 style='color: white; margin-bottom: 0.5rem; display: flex; align-items: center;'>
119
+ <span style='font-size: 1.5rem; margin-right: 0.5rem;'>🕒</span>
120
+ Cập nhật lần cuối
121
+ </h3>
122
+ <p style='color: #f0f0f0; margin-bottom: 0; font-size: 1.1rem;'>
123
+ {updated_time}
124
+ </p>
125
+ </div>
126
+ """, unsafe_allow_html=True)
127
+
128
+ def display_weakness_and_stats(profile: dict):
129
+ """
130
+ Hiển thị điểm yếu gần nhất và thống kê
131
+ """
132
+ col1, col2 = st.columns(2)
133
+
134
+ with col1:
135
+ st.markdown("## 🎯 Điểm yếu gần nhất")
136
+
137
+ if profile.get("last_weakness"):
138
+ st.markdown(f"""
139
+ <div style='background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
140
+ padding: 1.5rem;
141
+ border-radius: 10px;
142
+ margin-bottom: 1rem;'>
143
+ <h3 style='color: #8B0000; margin-bottom: 0.5rem; text-align: center;'>
144
+ {profile['last_weakness']}
145
+ </h3>
146
+ <p style='color: #2F4F4F; margin-bottom: 0; text-align: center; font-style: italic;'>
147
+ 💡 Hệ thống sẽ ưu tiên tạo bài tập về chủ đề này
148
+ </p>
149
+ </div>
150
+ """, unsafe_allow_html=True)
151
+ else:
152
+ st.markdown("""
153
+ <div style='background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
154
+ padding: 1.5rem;
155
+ border-radius: 10px;
156
+ margin-bottom: 1rem;
157
+ border: 2px dashed #ccc;'>
158
+ <h4 style='color: #666; text-align: center; margin-bottom: 0.5rem;'>
159
+ Chưa có dữ liệu phân tích
160
+ </h4>
161
+ <p style='color: #888; text-align: center; margin-bottom: 0;'>
162
+ Hãy chat với gia sư AI để hệ thống có thể phân tích điểm yếu của bạn!
163
+ </p>
164
+ </div>
165
+ """, unsafe_allow_html=True)
166
+
167
+ with col2:
168
+ st.markdown("## 📊 Thống kê tổng quan")
169
+
170
+ misunderstood_count = len(profile.get("misunderstood_concepts", []))
171
+
172
+ # Tạo màu động dựa trên số lượng
173
+ if misunderstood_count == 0:
174
+ color_gradient = "linear-gradient(135deg, #56ab2f 0%, #a8e6cf 100%)"
175
+ text_color = "#2F4F4F"
176
+ icon = "🎉"
177
+ elif misunderstood_count <= 3:
178
+ color_gradient = "linear-gradient(135deg, #f093fb 0%, #f5576c 100%)"
179
+ text_color = "#8B0000"
180
+ icon = "⚠️"
181
+ else:
182
+ color_gradient = "linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%)"
183
+ text_color = "#ffffff"
184
+ icon = "🔥"
185
+
186
+ st.markdown(f"""
187
+ <div style='background: {color_gradient};
188
+ padding: 1.5rem;
189
+ border-radius: 10px;
190
+ margin-bottom: 1rem;
191
+ text-align: center;'>
192
+ <div style='display: flex; align-items: center; justify-content: center; margin-bottom: 1rem;'>
193
+ <span style='font-size: 2rem; margin-right: 0.5rem;'>{icon}</span>
194
+ <h3 style='color: {text_color}; margin: 0;'>
195
+ Khái niệm cần cải thiện
196
+ </h3>
197
+ </div>
198
+ <div style='font-size: 3rem; font-weight: bold; color: {text_color}; margin-bottom: 0.5rem;'>
199
+ {misunderstood_count}
200
+ </div>
201
+ <p style='color: {text_color}; margin: 0; opacity: 0.9;'>
202
+ {'Tuyệt vời!' if misunderstood_count == 0 else 'Cần cải thiện' if misunderstood_count <= 3 else 'Cần tập trung cao'}
203
+ </p>
204
+ </div>
205
+ """, unsafe_allow_html=True)
206
+
207
+ def display_concepts_list(profile: dict):
208
+ """
209
+ Hiển thị danh sách khái niệm cần cải thiện
210
+ """
211
+ st.markdown("## 📝 Danh sách khái niệm cần cải thiện")
212
+
213
+ misunderstood_concepts = profile.get("misunderstood_concepts", [])
214
+
215
+ if misunderstood_concepts:
216
+ st.markdown("""
217
+ <div style='background: linear-gradient(135deg, #ffeaa7 0%, #fab1a0 100%);
218
+ padding: 1rem;
219
+ border-radius: 10px;
220
+ margin-bottom: 1.5rem;'>
221
+ <p style='color: #2d3436; margin: 0; text-align: center; font-weight: 500;'>
222
+ 📚 Dưới đây là những khái niệm mà hệ thống phát hi���n bạn còn gặp khó khăn
223
+ </p>
224
+ </div>
225
+ """, unsafe_allow_html=True)
226
+
227
+ # Hiển thị concepts trong grid
228
+ cols = st.columns(2)
229
+ for i, concept in enumerate(misunderstood_concepts):
230
+ col_idx = i % 2
231
+ with cols[col_idx]:
232
+ # Màu sắc xoay vòng cho từng concept
233
+ colors = [
234
+ "#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4",
235
+ "#FECA57", "#FF9FF3", "#54a0ff", "#5f27cd"
236
+ ]
237
+ color = colors[i % len(colors)]
238
+
239
+ st.markdown(f"""
240
+ <div style='background: linear-gradient(135deg, {color}20, {color}10);
241
+ padding: 1rem;
242
+ border-radius: 10px;
243
+ margin-bottom: 1rem;
244
+ border-left: 4px solid {color};'>
245
+ <div style='display: flex; align-items: center;'>
246
+ <span style='background: {color};
247
+ color: white;
248
+ border-radius: 50%;
249
+ width: 30px;
250
+ height: 30px;
251
+ display: flex;
252
+ align-items: center;
253
+ justify-content: center;
254
+ margin-right: 0.75rem;
255
+ font-weight: bold;'>
256
+ {i+1}
257
+ </span>
258
+ <h4 style='color: #333; margin: 0; flex: 1;'>
259
+ {concept}
260
+ </h4>
261
+ </div>
262
+ </div>
263
+ """, unsafe_allow_html=True)
264
+ else:
265
+ st.markdown("""
266
+ <div style='background: linear-gradient(135deg, #00b894 0%, #00cec9 100%);
267
+ padding: 2rem;
268
+ border-radius: 15px;
269
+ text-align: center;
270
+ margin-bottom: 1.5rem;'>
271
+ <div style='font-size: 4rem; margin-bottom: 1rem;'>🎉</div>
272
+ <h3 style='color: white; margin-bottom: 1rem;'>
273
+ Tuyệt vời! Chưa có khái niệm nào được đánh dấu là yếu.
274
+ </h3>
275
+ <p style='color: #dff9fb; margin-bottom: 1rem;'>
276
+ Điều này có thể có nghĩa là:
277
+ </p>
278
+ <div style='background: rgba(255,255,255,0.1);
279
+ padding: 1rem;
280
+ border-radius: 10px;
281
+ margin-bottom: 1rem;'>
282
+ <p style='color: #dff9fb; margin: 0;'>
283
+ • Bạn chưa chat đủ với gia sư AI để hệ thống phân tích<br>
284
+ • Bạn đang làm rất tốt với các bài toán đã thảo luận
285
+ </p>
286
+ </div>
287
+ <p style='color: #dff9fb; margin: 0;'>
288
+ 💡 <strong>Gợi ý:</strong> Hãy tiếp tục chat và hỏi nhiều câu hỏi toán học để gia sư AI có thể đưa ra các phân tích và đề xuất phù hợp nhé!
289
+ </p>
290
+ </div>
291
+ """, unsafe_allow_html=True)
292
+
293
+ def display_learning_suggestions(misunderstood_concepts: list):
294
+ """
295
+ Hiển thị gợi ý học tập
296
+ """
297
+ if misunderstood_concepts:
298
+ st.markdown("## 🎯 Gợi ý học tập")
299
+
300
+ suggestions = [
301
+ {
302
+ "icon": "✅",
303
+ "title": "Tạo bài tập luyện tập",
304
+ "description": "Yêu cầu gia sư AI tạo bài tập luyện tập cụ thể về các khái niệm yếu",
305
+ "color": "#00b894"
306
+ },
307
+ {
308
+ "icon": "🧠",
309
+ "title": "Giải thích lại khái niệm",
310
+ "description": "Hỏi gia sư AI giải thích lại các khái niệm khó hiểu bằng cách khác",
311
+ "color": "#6c5ce7"
312
+ },
313
+ {
314
+ "icon": "📹",
315
+ "title": "Xem video bài giảng",
316
+ "description": "Tham khảo các video bài giảng được đề xuất theo level phù hợp",
317
+ "color": "#fd79a8"
318
+ },
319
+ {
320
+ "icon": "📅",
321
+ "title": "Luyện tập đều đặn",
322
+ "description": "Dành 15-30 phút mỗi ngày để thực hành những khái niệm yếu",
323
+ "color": "#fdcb6e"
324
+ }
325
+ ]
326
+
327
+ cols = st.columns(2)
328
+ for i, suggestion in enumerate(suggestions):
329
+ col_idx = i % 2
330
+ with cols[col_idx]:
331
+ st.markdown(f"""
332
+ <div style='background: linear-gradient(135deg, {suggestion['color']}20, {suggestion['color']}10);
333
+ padding: 1.5rem;
334
+ border-radius: 10px;
335
+ margin-bottom: 1rem;
336
+ border-left: 4px solid {suggestion['color']};
337
+ height: 140px;'>
338
+ <div style='display: flex; align-items: center; margin-bottom: 0.5rem;'>
339
+ <span style='font-size: 1.5rem; margin-right: 0.5rem;'>{suggestion['icon']}</span>
340
+ <h4 style='color: #333; margin: 0;'>{suggestion['title']}</h4>
341
+ </div>
342
+ <p style='color: #666; margin: 0; font-size: 0.9rem;'>
343
+ {suggestion['description']}
344
+ </p>
345
+ </div>
346
+ """, unsafe_allow_html=True)
347
+
348
+ # Cách sử dụng
349
+ st.markdown("""
350
+ <div style='background: linear-gradient(135deg, #a29bfe 0%, #6c5ce7 100%);
351
+ padding: 1.5rem;
352
+ border-radius: 10px;
353
+ margin-top: 1rem;'>
354
+ <h4 style='color: white; margin-bottom: 1rem; text-align: center;'>
355
+ 💬 Cách sử dụng
356
+ </h4>
357
+ <div style='background: rgba(255,255,255,0.1);
358
+ padding: 1rem;
359
+ border-radius: 8px;'>
360
+ <p style='color: #ddd; margin: 0; text-align: center;'>
361
+ Quay lại trang chính và nói với gia sư AI:<br>
362
+ <strong style='color: white;'>"Tôi muốn luyện tập"</strong> hoặc
363
+ <strong style='color: white;'>"Cho tôi bài tập về [tên chủ đề]"</strong>
364
+ </p>
365
+ </div>
366
+ </div>
367
+ """, unsafe_allow_html=True)
368
+
369
+ def display_footer():
370
+ """
371
+ Hiển thị footer
372
+ """
373
+ st.markdown("---")
374
+
375
+ col1, col2, col3 = st.columns([1, 2, 1])
376
+ with col2:
377
+ if st.button("🔄 Làm mới dữ liệu", type="primary", use_container_width=True):
378
+ st.rerun()
379
+
380
+ st.markdown("""
381
+ <div style='background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
382
+ padding: 2rem;
383
+ border-radius: 15px;
384
+ text-align: center;
385
+ margin-top: 2rem;'>
386
+ <h3 style='color: white; margin-bottom: 1rem;'>
387
+ 💡 Về hồ sơ học tập
388
+ </h3>
389
+ <p style='color: #f0f0f0; margin-bottom: 0;'>
390
+ Dữ liệu được cập nhật tự động khi bạn chat với gia sư AI.<br>
391
+ Hồ sơ này giúp cá nhân hóa trải nghiệm học tập của bạn để đạt hiệu quả tốt nhất.
392
+ </p>
393
+ </div>
394
+ """, unsafe_allow_html=True)
395
+
396
+ def display_login_required():
397
+ """
398
+ Hiển thị thông báo cần đăng nhập
399
+ """
400
+ st.markdown("""
401
+ <div style='background: linear-gradient(135deg, #ff7675 0%, #fd79a8 100%);
402
+ padding: 2rem;
403
+ border-radius: 15px;
404
+ text-align: center;
405
+ margin: 2rem 0;'>
406
+ <div style='font-size: 4rem; margin-bottom: 1rem;'>⚠️</div>
407
+ <h2 style='color: white; margin-bottom: 1rem;'>
408
+ Bạn cần đăng nhập để xem hồ sơ học tập
409
+ </h2>
410
+ <p style='color: #ffeaa7; font-size: 1.2rem; margin-bottom: 0;'>
411
+ 👈 Vui lòng đăng nhập ở sidebar của trang chính
412
+ </p>
413
+ </div>
414
+ """, unsafe_allow_html=True)
415
+
416
+ def main():
417
+ """
418
+ Hàm chính của trang Hồ sơ học tập
419
+ """
420
+ # Kiểm tra xem người dùng đã đăng nhập chưa
421
+ if "user" not in st.session_state or st.session_state.user is None:
422
+ display_login_required()
423
+ st.stop()
424
+
425
+ # Khởi tạo Supabase client
426
+ supabase = init_supabase_client()
427
+
428
+ # Lấy thông tin người dùng hiện tại
429
+ user = st.session_state.user
430
+ user_email = user.email
431
+ user_id = user.id
432
+
433
+ # Lấy hồ sơ học tập
434
+ with st.spinner("Đang tải hồ sơ học tập..."):
435
+ # Thêm timestamp để force refresh data mỗi lần load trang
436
+ current_time = int(time.time())
437
+ profile = get_user_profile(supabase, user_id)
438
+
439
+ # Debug: In ra toàn bộ profile để kiểm tra
440
+ print(f"DEBUG: [Profile Page] Full profile data: {profile}")
441
+ print(f"DEBUG: [Profile Page] Current timestamp: {current_time}")
442
+
443
+ # Kiểm tra xem profile có dữ liệu không
444
+ if not profile:
445
+ st.error("Không thể tải hoặc tạo hồ sơ của bạn. Vui lòng thử lại.")
446
+ st.stop()
447
+
448
+ # Hiển thị header
449
+ display_header(user_email, user_id, profile)
450
+
451
+ # Hiển thị điểm yếu và thống kê
452
+ display_weakness_and_stats(profile)
453
+
454
+ st.markdown("---")
455
+
456
+ # Hiển thị danh sách khái niệm
457
+ display_concepts_list(profile)
458
+
459
+ # Hiển thị gợi ý học tập
460
+ misunderstood_concepts = profile.get("misunderstood_concepts", [])
461
+ display_learning_suggestions(misunderstood_concepts)
462
+
463
+ # Hiển thị footer
464
+ display_footer()
465
+
466
+ if __name__ == "__main__":
467
+ main()
requirements.txt CHANGED
@@ -1,3 +1,14 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
 
 
 
 
 
 
 
 
 
1
+ streamlit>=1.28.0
2
+ streamlit-chat>=0.1.1
3
+ haystack-ai>=2.0.0
4
+ sentence-transformers>=2.2.2
5
+ google-generativeai>=0.3.0
6
+ torch>=2.0.0
7
+ transformers>=4.30.0
8
+ numpy>=1.24.0
9
+ pandas>=2.0.0
10
+ python-dotenv>=1.0.0
11
+ supabase>=2.0.0
12
+ Pillow>=11.3.0
13
+ streamlit-audiorec==0.1.3
14
+ faster-whisper==1.1.1
src/streamlit_app.py DELETED
@@ -1,40 +0,0 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
- import streamlit as st
5
-
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
supabase_utils.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from supabase import create_client, Client
3
+ from datetime import datetime
4
+ import streamlit as st
5
+
6
+ @st.cache_resource
7
+ def init_supabase_client() -> Client:
8
+ """Khởi tạo và trả về Supabase client."""
9
+ url = os.getenv("SUPABASE_URL")
10
+ key = os.getenv("SUPABASE_KEY")
11
+ if not url or not key:
12
+ st.error("Không tìm thấy SUPABASE_URL hoặc SUPABASE_KEY.")
13
+ st.stop()
14
+ return create_client(url, key)
15
+
16
+ def get_user_profile(supabase: Client, user_id: str) -> dict:
17
+ """Lấy hồ sơ người dùng từ database. Nếu chưa có, tạo một hồ sơ mặc định."""
18
+ try:
19
+ response = supabase.table("user_profiles").select("*").eq("id", user_id).single().execute()
20
+ print(f"DEBUG: [Supabase] Retrieved profile: {response.data}")
21
+ print(f"DEBUG: [Supabase] updated_at value: {response.data.get('updated_at')} (type: {type(response.data.get('updated_at'))})")
22
+ return response.data
23
+ except Exception:
24
+ try:
25
+ default_profile = {
26
+ "id": user_id,
27
+ "misunderstood_concepts": [],
28
+ "last_weakness": None,
29
+ "created_at": datetime.now().isoformat(),
30
+ "updated_at": datetime.now().isoformat()
31
+ }
32
+ print(f"DEBUG: [Supabase] Creating default profile with updated_at: {default_profile['updated_at']}")
33
+ response = supabase.table("user_profiles").insert(default_profile).execute()
34
+ print(f"DEBUG: [Supabase] Created profile: {response.data[0]}")
35
+ return response.data[0]
36
+ except Exception as e:
37
+ st.error(f"Không thể tạo hồ sơ mặc định: {e}")
38
+ return {}
39
+
40
+ def update_user_profile(supabase: Client, user_id: str, profile_data: dict):
41
+ """
42
+ Cập nhật (hoặc chèn nếu chưa có) hồ sơ người dùng trong database.
43
+ """
44
+ if not user_id:
45
+ st.warning("Lỗi hệ thống: Đang cố gắng cập nhật hồ sơ mà không có User ID.")
46
+ return
47
+
48
+ try:
49
+ response = supabase.table("user_profiles").upsert({
50
+ "id": user_id,
51
+ **profile_data
52
+ }).execute()
53
+ print(f"DEBUG: [Supabase] Cập nhật profile thành công: {response.data}")
54
+ except Exception as e:
55
+ st.error(f"Lỗi khi cập nhật hồ sơ trên Supabase: {e}")
56
+ print(f"ERROR: [Supabase] Lỗi khi cập nhật profile: {e}")
videos.json ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "title": "Toán lớp 9 Bài 1: Phương trình quy về phương trình bậc nhất một ẩn | Cánh diều (HAY NHẤT)",
4
+ "duration": "35:51",
5
+ "related_sgk_chapter": "Chương 1: Phương trình và hệ phương trình bậc nhất",
6
+ "keywords": ["phương trình bậc nhất", "một ẩn", "phương trình chứa ẩn ở mẫu", "phương trình tích", "ax+b=0"],
7
+ "summary_for_llm": "Video này giảng về lý thuyết và cách giải các dạng phương trình có thể đưa về dạng bậc nhất một ẩn, đặc biệt là phương trình chứa ẩn ở mẫu và phương trình tích."
8
+ },
9
+ {
10
+ "title": "Toán lớp 9 Bài 2: Phương trình bậc nhất hai ẩn. Hệ hai phương trình bậc nhất hai ẩn | Cánh diều",
11
+ "duration": "35:14",
12
+ "related_sgk_chapter": "Chương 1: Phương trình và hệ phương trình bậc nhất",
13
+ "keywords": ["hệ phương trình", "hai ẩn", "phương trình bậc nhất hai ẩn", "nghiệm của hệ", "tập nghiệm"],
14
+ "summary_for_llm": "Video này giới thiệu khái niệm về phương trình và hệ phương trình bậc nhất hai ẩn, cách xác định nghiệm và minh họa tập nghiệm bằng đồ thị."
15
+ },
16
+ {
17
+ "title": "Toán lớp 9 Bài 3: Giải hệ hai phương trình bậc nhất hai ẩn | Cánh diều (DỄ HIỂU NHẤT)",
18
+ "duration": "40:56",
19
+ "related_sgk_chapter": "Chương 1: Phương trình và hệ phương trình bậc nhất",
20
+ "keywords": ["giải hệ phương trình", "phương pháp thế", "phương pháp cộng đại số"],
21
+ "summary_for_llm": "Video này hướng dẫn chi tiết hai phương pháp chính để giải hệ phương trình bậc nhất hai ẩn là phương pháp thế và phương pháp cộng đại số, kèm theo nhiều ví dụ."
22
+ },
23
+ {
24
+ "title": "Bài tập cuối chương 1 | Toán lớp 9 - Cánh diều (DỄ HIỂU NHẤT)",
25
+ "duration": "37:53",
26
+ "related_sgk_chapter": "Chương 1: Phương trình và hệ phương trình bậc nhất",
27
+ "keywords": ["ôn tập chương 1", "bài tập tổng hợp", "hệ phương trình", "giải bài toán bằng cách lập hệ"],
28
+ "summary_for_llm": "Video này tổng hợp và chữa các bài tập cuối chương 1, giúp học sinh ôn lại toàn bộ kiến thức về phương trình và hệ phương trình."
29
+ },
30
+ {
31
+ "title": "Toán lớp 9 Bài 1: Bất đẳng thức | Cánh diều (DỄ HIỂU NHẤT)",
32
+ "duration": "36:11",
33
+ "related_sgk_chapter": "Chương 2: Bất phương trình bậc nhất một ẩn",
34
+ "keywords": ["bất đẳng thức", "chứng minh bất đẳng thức", "bất đẳng thức Cô-si", "so sánh"],
35
+ "summary_for_llm": "Video này giới thiệu các khái niệm cơ bản về bất đẳng thức, các tính chất liên hệ và một số phương pháp chứng minh bất đẳng thức thường gặp."
36
+ },
37
+ {
38
+ "title": "Toán lớp 9 Bài 2: Bất phương trình bậc nhất một ẩn | Cánh diều (DỄ HIỂU NHẤT)",
39
+ "duration": "23:00",
40
+ "related_sgk_chapter": "Chương 2: Bất phương trình bậc nhất một ẩn",
41
+ "keywords": ["bất phương trình", "một ẩn", "tập nghiệm", "biểu diễn tập nghiệm"],
42
+ "summary_for_llm": "Video này hướng dẫn cách giải một bất phương trình bậc nhất một ẩn và cách biểu diễn tập nghiệm trên trục số."
43
+ },
44
+ {
45
+ "title": "Bài tập cuối chương 2 | Toán lớp 9 - Cánh diều (DỄ HIỂU NHẤT)",
46
+ "duration": "31:35",
47
+ "related_sgk_chapter": "Chương 2: Bất phương trình bậc nhất một ẩn",
48
+ "keywords": ["ôn tập chương 2", "bài tập tổng hợp", "bất phương trình"],
49
+ "summary_for_llm": "Video này tổng hợp và chữa các bài tập cuối chương 2, giúp học sinh ôn lại kiến thức về bất đẳng thức và bất phương trình."
50
+ },
51
+ {
52
+ "title": "Toán lớp 9 Bài 1: Căn bậc hai và căn bậc ba của số thực | Cánh diều (DỄ HIỂU NHẤT)",
53
+ "duration": "27:04",
54
+ "related_sgk_chapter": "Chương 3: Căn thức",
55
+ "keywords": ["căn bậc hai", "căn bậc ba", "số thực", "căn bậc hai số học", "so sánh căn"],
56
+ "summary_for_llm": "Video này giới thiệu lại các khái niệm về căn bậc hai, căn bậc ba của số thực và các tính chất cơ bản để so sánh."
57
+ },
58
+ {
59
+ "title": "Toán lớp 9 Bài 2: Một số phép tính về căn bậc hai của số thực | Cánh diều (DỄ HIỂU NHẤT)",
60
+ "duration": "36:51",
61
+ "related_sgk_chapter": "Chương 3: Căn thức",
62
+ "keywords": ["phép tính căn bậc hai", "khai phương một tích", "khai phương một thương", "nhân chia căn bậc hai"],
63
+ "summary_for_llm": "Video này hướng dẫn các quy tắc khai phương một tích, một thương và các phép tính nhân, chia các căn bậc hai."
64
+ },
65
+ {
66
+ "title": "Toán lớp 9 Bài 3: Căn thức bậc hai và căn thức bậc ba của biểu thức đại số | Cánh diều (HAY NHẤT)",
67
+ "duration": "22:00",
68
+ "related_sgk_chapter": "Chương 3: Căn thức",
69
+ "keywords": ["căn thức bậc hai", "biểu thức đại số", "điều kiện xác định", "hằng đẳng thức căn A bình"],
70
+ "summary_for_llm": "Video này tập trung vào khái niệm căn thức của biểu thức đại số, điều kiện để căn thức có nghĩa và hằng đẳng thức quan trọng."
71
+ },
72
+ {
73
+ "title": "Toán lớp 9 Bài 4: Một số phép biến đổi căn thức bậc hai của biểu thức đại số | Cánh diều (HAY NHẤT)",
74
+ "duration": "28:15",
75
+ "related_sgk_chapter": "Chương 3: Căn thức",
76
+ "keywords": ["biến đổi căn thức", "đưa thừa số ra ngoài dấu căn", "trục căn thức ở mẫu", "khử mẫu"],
77
+ "summary_for_llm": "Video này hướng dẫn các kỹ thuật biến đổi căn thức phức tạp hơn như đưa thừa số ra ngoài/vào trong dấu căn và trục căn thức ở mẫu."
78
+ },
79
+ {
80
+ "title": "Toán lớp 9 Bài 1: Tỉ số lượng giác của góc nhọn | Cánh diều (HAY NHẤT)",
81
+ "duration": "50:22",
82
+ "related_sgk_chapter": "Chương 4: Hệ thức lượng trong tam giác vuông",
83
+ "keywords": ["tỉ số lượng giác", "sin", "cos", "tan", "cot", "góc nhọn", "tam giác vuông"],
84
+ "summary_for_llm": "Video này định nghĩa chi tiết 4 tỉ số lượng giác sin, cos, tan, cot của một góc nhọn và mối liên hệ giữa chúng."
85
+ },
86
+ {
87
+ "title": "Toán lớp 9 Bài 2: Một số hệ thức về cạnh và góc trong tam giác vuông | Cánh diều (HAY NHẤT)",
88
+ "duration": "39:29",
89
+ "related_sgk_chapter": "Chương 4: Hệ thức lượng trong tam giác vuông",
90
+ "keywords": ["hệ thức lượng", "tam giác vuông", "cạnh góc vuông", "cạnh huyền", "đường cao", "hình chiếu"],
91
+ "summary_for_llm": "Video này giới thiệu các hệ thức lượng quan trọng liên hệ giữa cạnh, đường cao và hình chiếu trong tam giác vuông."
92
+ },
93
+ {
94
+ "title": "Toán lớp 9 Bài 3: Ứng dụng của tỉ số lượng giác của góc nhọn | Cánh diều (HAY NHẤT)",
95
+ "duration": "34:08",
96
+ "related_sgk_chapter": "Chương 4: Hệ thức lượng trong tam giác vuông",
97
+ "keywords": ["ứng dụng tỉ số lượng giác", "giải tam giác vuông", "bài toán thực tế", "đo chiều cao"],
98
+ "summary_for_llm": "Video này hướng dẫn cách áp dụng tỉ số lượng giác và hệ thức lượng để giải tam giác vuông và các bài toán đo đạc trong thực tế."
99
+ },
100
+ {
101
+ "title": "Toán lớp 9 Bài 1: Đường tròn. Vị trí tương đối của hai đường tròn | Cánh diều (HAY NHẤT)",
102
+ "duration": "50:56",
103
+ "related_sgk_chapter": "Chương 5: Đường tròn",
104
+ "keywords": ["đường tròn", "tâm", "bán kính", "vị trí tương đối hai đường tròn", "tiếp xúc trong", "tiếp xúc ngoài", "cắt nhau"],
105
+ "summary_for_llm": "Video này giới thiệu các khái niệm cơ bản về đường tròn và 3 vị trí tương đối của hai đường tròn cùng các tính chất liên quan."
106
+ },
107
+ {
108
+ "title": "Toán lớp 9 Bài 2: Vị trí tương đối của đường thẳng và đường tròn | Cánh diều (HAY NHẤT)",
109
+ "duration": "26:02",
110
+ "related_sgk_chapter": "Chương 5: Đường tròn",
111
+ "keywords": ["vị trí tương đối", "đường thẳng và đường tròn", "không giao nhau", "tiếp xúc", "cắt nhau", "tiếp tuyến", "cát tuyến"],
112
+ "summary_for_llm": "Video này xét 3 vị trí tương đối của một đường thẳng và một đường tròn, dựa vào khoảng cách từ tâm đến đường thẳng."
113
+ },
114
+ {
115
+ "title": "Toán lớp 9 Bài 3: Tiếp tuyến của đường tròn | Cánh diều (HAY NHẤT)",
116
+ "duration": "44:57",
117
+ "related_sgk_chapter": "Chương 5: Đường tròn",
118
+ "keywords": ["tiếp tuyến", "dấu hiệu nhận biết tiếp tuyến", "tính chất hai tiếp tuyến cắt nhau"],
119
+ "summary_for_llm": "Video này trình bày định nghĩa, tính chất vuông góc và các dấu hiệu nhận biết một đường thẳng là tiếp tuyến của đường tròn."
120
+ },
121
+ {
122
+ "title": "Toán lớp 9 Bài 4: Góc ở tâm. Góc nội tiếp | Cánh diều (HAY NHẤT)",
123
+ "duration": "50:00",
124
+ "related_sgk_chapter": "Chương 5: Đường tròn",
125
+ "keywords": ["góc ở tâm", "góc nội tiếp", "số đo cung", "cung bị chắn", "hệ quả góc nội tiếp"],
126
+ "summary_for_llm": "Video này giới thiệu hai loại góc quan trọng trong đường tròn là góc ở tâm, góc nội tiếp và mối liên hệ giữa góc và cung bị chắn."
127
+ },
128
+ {
129
+ "title": "Toán lớp 9 Bài 5: Độ dài cung tròn diện tích hình quạt tròn diện tích hình vành khuyên | Cánh diều",
130
+ "duration": "32:27",
131
+ "related_sgk_chapter": "Chương 5: Đường tròn",
132
+ "keywords": ["độ dài cung tròn", "diện tích hình quạt tròn", "hình vành khuyên", "công thức tính"],
133
+ "summary_for_llm": "Video này cung cấp các công thức để tính độ dài của một cung tròn, diện tích của hình quạt tròn và hình vành khuyên."
134
+ },
135
+ {
136
+ "title": "Toán lớp 9 Bài 1: Mô tả và biểu diễn dữ liệu trên các bảng, biểu đồ | Cánh diều | Tập 2 (HAY NHẤT)",
137
+ "duration": "1:09:51",
138
+ "related_sgk_chapter": "Chương 6: Thống kê và Xác suất",
139
+ "keywords": ["thống kê", "bảng dữ liệu", "biểu đồ cột", "biểu đồ đoạn thẳng", "biểu đồ quạt tròn"],
140
+ "summary_for_llm": "Video này hướng dẫn cách thu thập, mô tả và biểu diễn dữ liệu bằng các loại bảng và biểu đồ thông dụng như biểu đồ cột, biểu đồ quạt."
141
+ },
142
+ {
143
+ "title": "Toán lớp 9 Bài 4: Phép thử ngẫu nhiên và không gian mẫu. Xác suất của biến cố | Chương 6 | Cánh diều",
144
+ "duration": "34:10",
145
+ "related_sgk_chapter": "Chương 6: Thống kê và Xác suất",
146
+ "keywords": ["xác suất", "biến cố", "không gian mẫu", "phép thử ngẫu nhiên", "xác suất cổ điển"],
147
+ "summary_for_llm": "Video này giới thiệu các khái niệm cơ bản của xác suất như phép thử, không gian mẫu, biến cố và cách tính xác suất của một biến cố."
148
+ },
149
+ {
150
+ "title": "Toán lớp 9 Bài 1: Hàm số y = ax^2 (a ≠ 0) | Cánh diều (HAY NHẤT)",
151
+ "duration": "41:29",
152
+ "related_sgk_chapter": "Chương 7: Hàm số y = ax^2. Phương trình bậc hai một ẩn",
153
+ "keywords": ["hàm số bậc hai", "y=ax^2", "parabol", "đồ thị hàm số", "đồng biến", "nghịch biến"],
154
+ "summary_for_llm": "Video này giảng về các tính chất (đồng biến, nghịch biến) và cách vẽ đồ thị của hàm số bậc hai dạng y = ax^2, hay còn gọi là parabol."
155
+ },
156
+ {
157
+ "title": "Toán lớp 9 Bài 2: Phương trình bậc hai một ẩn | Cánh diều (HAY NHẤT)",
158
+ "duration": "58:05",
159
+ "related_sgk_chapter": "Chương 7: Hàm số y = ax^2. Phương trình bậc hai một ẩn",
160
+ "keywords": ["phương trình bậc hai", "công thức nghiệm", "delta", "biệt thức", "công thức nghiệm thu gọn"],
161
+ "summary_for_llm": "Video này hướng dẫn chi tiết cách giải phương trình bậc hai một ẩn bằng công thức nghiệm tổng quát (delta) và công thức nghiệm thu gọn."
162
+ },
163
+ {
164
+ "title": "Toán lớp 9 Bài 3: Định lí Viète | Cánh diều (DỄ HIỂU NHẤT)",
165
+ "duration": "29:23",
166
+ "related_sgk_chapter": "Chương 7: Hàm số y = ax^2. Phương trình bậc hai một ẩn",
167
+ "keywords": ["định lý Vi-ét", "Viète", "tổng và tích các nghiệm", "nhẩm nghiệm", "tìm hai số"],
168
+ "summary_for_llm": "Video này trình bày hệ thức Vi-ét (tổng và tích các nghiệm) và các ứng dụng quan trọng như nhẩm nghiệm, tìm hai số khi biết tổng và tích."
169
+ },
170
+ {
171
+ "title": "Toán lớp 9 Bài 2: Tứ giác nội tiếp đường tròn | Cánh diều (HAY NHẤT)",
172
+ "duration": "36:08",
173
+ "related_sgk_chapter": "Chương 5: Đường tròn",
174
+ "keywords": ["tứ giác nội tiếp", "dấu hiệu nhận biết", "tính chất", "tổng hai góc đối"],
175
+ "summary_for_llm": "Video này giới thiệu định nghĩa, tính chất về tổng hai góc đối và các dấu hiệu để nhận biết một tứ giác là tứ giác nội tiếp."
176
+ },
177
+ {
178
+ "title": "Toán lớp 9 Bài 1: Đa giác đều. Hình đa giác đều trong thực tiễn | Cánh diều (HAY NHẤT)",
179
+ "duration": "32:43",
180
+ "related_sgk_chapter": "Chương 8: Hình học phẳng",
181
+ "keywords": ["đa giác", "đa giác lồi", "đa giác đều", "tam giác đều", "hình vuông", "lục giác đều"],
182
+ "summary_for_llm": "Video này giới thiệu về khái niệm đa giác, đa giác lồi, đa giác đều và các ví dụ về hình đa giác đều trong thực tiễn."
183
+ },
184
+ {
185
+ "title": "Toán lớp 9 Bài 2: Phép quay | Cánh diều (DỄ HIỂU NHẤT)",
186
+ "duration": "20:51",
187
+ "related_sgk_chapter": "Chương 8: Hình học phẳng",
188
+ "keywords": ["phép quay", "tâm quay", "góc quay", "biến hình", "bảo toàn khoảng cách"],
189
+ "summary_for_llm": "Video này giới thiệu về phép biến hình quay trong mặt phẳng, bao gồm tâm quay, góc quay và các tính chất của nó."
190
+ },
191
+ {
192
+ "title": "Toán lớp 9 Bài 1: Hình trụ | Cánh diều (DỄ HIỂU NHẤT)",
193
+ "duration": "34:30",
194
+ "related_sgk_chapter": "Chương 9: Hình học không gian",
195
+ "keywords": ["hình trụ", "diện tích xung quanh", "diện tích toàn phần", "thể tích hình trụ"],
196
+ "summary_for_llm": "Video này cung cấp các công thức và ví dụ về cách tính diện tích xung quanh, diện tích toàn phần và thể tích của hình trụ."
197
+ },
198
+ {
199
+ "title": "Toán lớp 9 Bài 2: Hình nón | Cánh diều (HAY NHẤT)",
200
+ "duration": "34:59",
201
+ "related_sgk_chapter": "Chương 9: Hình học không gian",
202
+ "keywords": ["hình nón", "hình nón cụt", "diện tích xung quanh", "thể tích hình nón", "đường sinh"],
203
+ "summary_for_llm": "Video này cung cấp các công thức và ví dụ về cách tính diện tích xung quanh, diện tích toàn phần và thể tích của hình nón, hình nón cụt."
204
+ },
205
+ {
206
+ "title": "Toán lớp 9 Bài 3: Hình cầu | Cánh diều (HAY NHẤT)",
207
+ "duration": "25:22",
208
+ "related_sgk_chapter": "Chương 9: Hình học không gian",
209
+ "keywords": ["hình cầu", "mặt cầu", "diện tích mặt cầu", "thể tích hình cầu", "vị trí tương đối"],
210
+ "summary_for_llm": "Video này cung cấp công thức tính diện tích mặt cầu và thể tích của hình cầu, kèm theo các ví dụ minh họa."
211
+ }
212
+ ]