You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
5.5 KiB

5 months ago
import os
5 months ago
import re
5 months ago
from typing import Iterator
from openai import OpenAI
5 months ago
from Config import *
5 months ago
class EnglishEssayAnalyzer:
def __init__(self):
self.client = OpenAI(
5 months ago
api_key=MODEL_API_KEY,
5 months ago
base_url=MODEL_API_URL
5 months ago
)
def _build_prompt(self, essay: str) -> str:
return f"""你是一位专业的英语教师,请分析以下英文作文:
{essay}
请按以下顺序指出问题
1. 语法错误标注行号
2. 用词不当
3. 逻辑结构问题
4. 改进建议
用中文回答保持专业但易懂的语气"""
def analyze_stream(self, essay: str) -> Iterator[str]:
5 months ago
"""流式分析作文(新增关键方法)"""
5 months ago
try:
stream = self.client.chat.completions.create(
5 months ago
model=MODEL_NAME,
5 months ago
messages=[{
"role": "user",
"content": self._build_prompt(essay)
}],
temperature=0.3,
stream=True
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
5 months ago
yield chunk.choices[0].delta.content
5 months ago
except Exception as e:
yield f"\n分析中断:{str(e)}"
def full_analysis(self, essay: str) -> dict:
"""完整分析并返回结构化结果"""
analysis = {
"grammar_errors": [],
"vocabulary_issues": [],
"structure_problems": [],
"suggestions": []
}
current_category = None
5 months ago
buffer = ""
5 months ago
category_pattern = re.compile(r'(\d+\.\s)(.*?)()') # 更精确的匹配模式
5 months ago
for chunk in self.analyze_stream(essay):
5 months ago
print(chunk, end='', flush=True)
5 months ago
buffer += chunk
5 months ago
# 改进的分类检测逻辑支持跨chunk匹配
while True:
match = category_pattern.search(buffer)
if not match:
break
5 months ago
5 months ago
# 提取分类信息
current_category = match.group(2).strip()
buffer = buffer[match.end():] # 移除已处理部分
# 初始化当前分类
5 months ago
if '语法' in current_category:
analysis['grammar_errors'].append('')
elif '用词' in current_category:
analysis['vocabulary_issues'].append('')
elif '逻辑' in current_category:
analysis['structure_problems'].append('')
elif '改进' in current_category:
analysis['suggestions'].append('')
5 months ago
# 内容填充逻辑处理剩余buffer
5 months ago
if current_category:
if '语法' in current_category:
5 months ago
analysis['grammar_errors'][-1] += buffer
5 months ago
elif '用词' in current_category:
5 months ago
analysis['vocabulary_issues'][-1] += buffer
5 months ago
elif '逻辑' in current_category:
5 months ago
analysis['structure_problems'][-1] += buffer
5 months ago
elif '改进' in current_category:
5 months ago
analysis['suggestions'][-1] += buffer
buffer = ""
5 months ago
5 months ago
# 后处理增强
5 months ago
for key in analysis:
5 months ago
# 分割条目并清理格式
5 months ago
cleaned = []
for text in analysis[key]:
5 months ago
# 按数字编号分割子项
items = re.split(r'(?=\d+\.\s)', text)
cleaned.extend([
item.strip().replace('\n', ' ')
for item in items
if item.strip()
])
5 months ago
analysis[key] = cleaned
5 months ago
return analysis
5 months ago
def save_markdown_report(self, analysis: dict, filename: str) -> None:
"""生成Markdown格式报告"""
with open(filename, 'w', encoding='utf-8') as f:
f.write("# 英文作文分析报告\n\n")
sections = [
('grammar_errors', '语法错误'),
('vocabulary_issues', '用词问题'),
('structure_problems', '结构问题'),
('suggestions', '改进建议')
]
for key, title in sections:
if analysis[key]:
f.write(f"## {title}\n")
for i, item in enumerate(analysis[key], 1):
f.write(f"{i}. {item}\n")
f.write("\n")
5 months ago
if __name__ == "__main__":
# 示例用法
essay = """
Dear Peter Knowing that you have won the first prize in The Chinese Chess NetworkChallengeCompetition I feel very delighted. I'm writing to offer my warmest congratulations to you. From my perspective you derseve what you gained What lead to your success is your diligence and go all out for the contest making me admire you. On top of this It's real encouragement to me to see your effors pay off. How I marvel at your perfect performance which inspires my passion on Chinese Chess and other traditional skills I would appreciate if you could share with me your experience on learn it. Looking forward to your early reply Your sincerely
"""
analyzer = EnglishEssayAnalyzer()
print("🔍 开始分析作文...\n")
result = analyzer.full_analysis(essay)
5 months ago
# 保存Markdown报告
analyzer.save_markdown_report(result, "analysis_report.md")
5 months ago
print("\n\n✅ 分析结果已保存至 analysis_report.md")