Merge branch 'main' of https://repo.teamsf.co.kr/g-zero/HWP-Scoring
This commit is contained in:
63
score5.py
63
score5.py
@@ -15,6 +15,12 @@ class XMLScorer:
|
||||
def __init__(self, scoring_criteria_path):
|
||||
# 채점 기준 로드
|
||||
self.scoring_criteria = self._load_scoring_criteria(scoring_criteria_path)
|
||||
|
||||
def set_typo_score(self, score):
|
||||
self.typo_score = score
|
||||
|
||||
def get_typo_score(self):
|
||||
return self.typo_score
|
||||
|
||||
# 채점 기준파일 로드(JSON 파일)
|
||||
def _load_scoring_criteria(self, file_path):
|
||||
@@ -37,9 +43,7 @@ class XMLScorer:
|
||||
return result
|
||||
else:
|
||||
return result
|
||||
# result = root.xpath(second_xpath)
|
||||
# print(f'result : {result}')
|
||||
# return result
|
||||
|
||||
except ET.XPathEvalError as e:
|
||||
return None
|
||||
else:
|
||||
@@ -141,6 +145,7 @@ class XMLScorer:
|
||||
|
||||
previous_first_digit = first_digit
|
||||
|
||||
id = criterion_id
|
||||
xpath = criterion['path']
|
||||
xpath2 = criterion['path2']
|
||||
search_value = criterion['searchValue']
|
||||
@@ -190,16 +195,19 @@ class XMLScorer:
|
||||
actual_answer = int(result[0])
|
||||
else:
|
||||
actual_answer = result[0]
|
||||
|
||||
|
||||
if "오타감점" in category:
|
||||
points = self.get_typo_score()
|
||||
|
||||
scoring = {
|
||||
'id': id,
|
||||
'category': category, # 채점 분류
|
||||
'item': item, # 채점 항목
|
||||
'right_answer': right_answer, # 정답
|
||||
'actual_answer': actual_answer, # 실제 작성 답안
|
||||
'points': 0,
|
||||
'points': points,
|
||||
'deductions': [] # 각 기준별 감점 내역
|
||||
}
|
||||
scoring['points'] = points
|
||||
|
||||
# 점수 차감 조건
|
||||
# 1. 정답이 실수형으로 반환받은 경우는 채점항목의 부분점수 합산 결과이므로
|
||||
@@ -210,8 +218,8 @@ class XMLScorer:
|
||||
scoring['points'] = actual_answer
|
||||
|
||||
elif type(actual_answer) is int:
|
||||
# 오차범위 5 이상이면 감점
|
||||
if abs(actual_answer - right_answer) > 5:
|
||||
# 오차범위 3 이상이면 감점
|
||||
if abs(actual_answer - right_answer) > 3:
|
||||
scoring['points'] -= points
|
||||
else:
|
||||
# right_answer(JSON파일 내 valuer값) null일 경우 점수감점 없이 진행
|
||||
@@ -244,8 +252,6 @@ class XMLScorer:
|
||||
}
|
||||
|
||||
def binary_to_chartxml(self, xml_path):
|
||||
|
||||
print(f'binary_to_chartxml {xml_path}')
|
||||
tree = ET.parse(xml_path)
|
||||
root = tree.getroot()
|
||||
|
||||
@@ -344,24 +350,25 @@ class XMLScorer:
|
||||
|
||||
# result_diff 배열의 길이를 맨 앞에 저장
|
||||
temp = 40 - min(len(result_diff)*2, 40)
|
||||
self.set_typo_score(temp)
|
||||
|
||||
result_diff.insert(0, temp)
|
||||
return result_diff
|
||||
|
||||
# XML 파일 채점
|
||||
def score_directory(self, xml_directory, answer_path):
|
||||
|
||||
# xml 파일 불러오기
|
||||
xml_files = Path(xml_directory).glob('*.hml')
|
||||
|
||||
# 결과 저장할 리스트
|
||||
results = []
|
||||
|
||||
|
||||
for xml_file in xml_files:
|
||||
result = {}
|
||||
chart_xml = self.binary_to_chartxml(xml_file)
|
||||
result['score'] = self._score_xml_file(xml_file, chart_xml)
|
||||
result['typo'] = self.typo_check(answer_path, xml_file)
|
||||
result['score'] = self._score_xml_file(xml_file, chart_xml)
|
||||
# result['score']['score_results'][2]['points'] = result['typo'][0]
|
||||
results.append(result)
|
||||
return results
|
||||
|
||||
@@ -373,6 +380,7 @@ class XMLScorer:
|
||||
number = match.group(1)
|
||||
name = match.group(2)
|
||||
return number, name
|
||||
|
||||
return None, None
|
||||
|
||||
def export_to_excel(self, results, output_path=None):
|
||||
@@ -405,29 +413,46 @@ class XMLScorer:
|
||||
else:
|
||||
detail_row = {'채점항목':f"{number}-{name}"}
|
||||
|
||||
for i, scoring in enumerate(result['score_results']):
|
||||
# detail_row[scoring['item']] = scoring['points']
|
||||
detail_row[f'{i+1}'] = scoring['points']
|
||||
section_num = None
|
||||
partial_idx = 0
|
||||
for i, score_result in enumerate(result['score_results']):
|
||||
current_section = int(score_result['id'].split('-')[0])
|
||||
if section_num is None:
|
||||
section_num = current_section
|
||||
|
||||
if current_section != section_num:
|
||||
# 이전 섹션의 부분합을 출력
|
||||
detail_row[f'[{section_num}]합계'] = result['partial_scores'][partial_idx]['score']
|
||||
partial_idx += 1
|
||||
section_num = current_section
|
||||
|
||||
detail_row[f'{i+1}'] = score_result['points']
|
||||
|
||||
# 마지막 섹션의 부분합을 출력
|
||||
if section_num is not None and partial_idx < len(result['partial_scores']):
|
||||
detail_row[f'[{section_num}]합계'] = result['partial_scores'][partial_idx]['score']
|
||||
|
||||
detail_row['총점'] = result.get('total_score', 0)
|
||||
detail_data.append(detail_row)
|
||||
|
||||
summary_df = pd.DataFrame(summary_data)
|
||||
detail_df = pd.DataFrame(detail_data).transpose()
|
||||
|
||||
# detail_df = pd.DataFrame(detail_data)
|
||||
|
||||
for temp in results:
|
||||
result = temp['typo']
|
||||
typo_data.append(result)
|
||||
|
||||
type_df = pd.DataFrame(typo_data).transpose()
|
||||
typo_df = pd.DataFrame(typo_data).transpose()
|
||||
# detail_df = pd.DataFrame(detail_data)
|
||||
|
||||
# detail_df.iloc[3] = typo_df.iloc[0]
|
||||
|
||||
# ExcelWriter 객체 생성
|
||||
with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
|
||||
summary_df.to_excel(writer, sheet_name='채점결과요약', index=False)
|
||||
detail_df.to_excel(writer, sheet_name='채점상세내역', index=False)
|
||||
type_df.to_excel(writer, sheet_name='오타내역', index=False)
|
||||
typo_df.to_excel(writer, sheet_name='오타내역', index=False)
|
||||
|
||||
# 열 너비 자동 조정
|
||||
# for sheet_name in writer.sheets:
|
||||
|
||||
Reference in New Issue
Block a user