#11기문과생도AI
안녕하세요. 바호입니다. 11기엔 청강생으로 [문과생도 AI]에 함께 하게 되었습니다.
지난 캠프에 이어, 이번에도 저는 개인 연구비서를 만들어 내려는 시도를 계속하고 있습니다.
지난 시도 참고: #개인 연구비서 만들기! - 검색해서 데이터 긁어와...
바호의 연구 비서 만들기 프로젝트 제2탄!!
텍스트를 교감하는 봇을 만들기!!
저는 한문 텍스트 자료를 주로 취급하는데요. 자주 하는 작업 중 하나가 특정 책의 여러 판본을 비교하는 것입니다. 전문 용어로 ‘교감’한다고 하는데요.
특정 책의 어떤 구절에 대해, 그 책의 여러 판본들에 해당 구절이 어떻게 실려 있는지 검토하는 것입니다.
A판본이랑 B판본을 비교해보니, 같은 문장인데 요 글자는 다르게 썼더라.. 이 글자랑 저 글자 순서가 바뀌었더라.. 등등 체크하는 작업을 하다보면, 눈이 빠집니다…
인간이 하는 일인지라 열심히 본다고 보는데도 결국 찾아내지 못하는 차이들도 많구요..
[원고 내 원문]과 [ctext], [사고전서], [사부비요]라는 서로 다른 판본 상의 원문을 비교하는 작업입니다. 다른 글자 빨간 표시한 거 보이시죠… 이런 작업 무한 반복~~
교감봇이 해주었으면 하는 것
제가 엑셀 파일을 올리고, 두 개의 열을 지정해주면(예컨대, [원고 내 원문]과 [사고전서])
해당 열의 모든 행에 대해서 각각의 셀에 담긴 문자열을 비교해서
차이가 없으면 그냥 두고, 하나라도 차이가 있으면 해당 행을 노란색으로 칠해주는 것!!
그러면 제가 노란색으로 색칠된 행에 대해서만 무엇이 다른지 꼼꼼히 살펴보면 되니까 요.
예를 들어, 빨간칸끼리 비교, 파란칸끼리 비교해서, 글자가 하나라도 다르면 셀을 노랗게 칠해주는 거죠.
이때, 띄어쓰기나 구두점 등은 무시하기를 원했습니다. 저한테는 글자들의 모양과 순서의 차이만 중요하거든요.
Grimore를 이용해서 파이썬 코드를 짜기
#10기문과생도AI 에서 파이썬 수업을 들었어서, 대강 ‘문자열’ 개념은 알고 있었습니다. 그래서 각 행의 문장들을 문자열로 만들어서 비교해달라고 했어요.
인풋과 아웃풋 정보를 정확하게 넣으려고 했고
예시를 들어주기도 했습니다.
이렇게 요구하고 한 번 코드를 받은 뒤에, 두 가지 사항을 추가 요청했습니다.
1) 열의 정보를 숫자로 안 넣고 알파벳으로 넣을 수도 있다. C열과 E열 이런식으로.
2) 비교해야 하는 문자들이 꼭 알파벳이 아닐 수도 있다. 주로 고전 중국어나 한국어를 대상으로 작업할 거다.
그랬더니 아래와 같은 코드를 짜주었습니다.
import pandas as pd
import openpyxl
from openpyxl.styles import PatternFill, Font
import re
def clean_string(s):
return ''.join(re.findall(r'\w', s))
def column_letter_to_index(col):
col = col.upper()
index = 0
for char in col:
index = index * 26 + (ord(char) - ord('A')) + 1
return index - 1 # Convert to 0-based index
def highlight_differences(file_path, x_col, y_col, output_path):
# Load the Excel file
df = pd.read_excel(file_path)
# Convert column names to indices if necessary
if isinstance(x_col, str):
x_col = column_letter_to_index(x_col)
if isinstance(y_col, str):
y_col = column_letter_to_index(y_col)
# Load the workbook and the active worksheet
wb = openpyxl.load_workbook(file_path)
ws = wb.active
# Iterate over the rows
for index, row in df.iterrows():
x_str = clean_string(str(row.iloc[x_col]))
y_str = clean_string(str(row.iloc[y_col]))
# Compare characters in the strings
if x_str != y_str:
# Highlight the row in y_col
cell = ws.cell(row=index+2, column=y_col+1)
cell.fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")
# Highlight differences in red
for i, (x_char, y_char) in enumerate(zip(x_str, y_str)):
if x_char != y_char:
if i < len(cell.value):
new_value = list(cell.value)
new_value[i] = f"{y_char}"
cell.value = ''.join(new_value)
else:
cell.value += f"{y_char}"
cell.font = Font(color="FF0000")
# Save the modified workbook
wb.save(output_path)
# Example usage
input_file_path = 'input.xlsx' # Replace with your input file path
output_file_path = 'output.xlsx' # Replace with your output file path
x_column = 'A' # Replace with the index or letter of the x column
y_column = 'B' # Replace with the index or letter of the y column
highlight_differences(input_file_path, x_column, y_column, output_file_path)
이걸 실행했더니 아래와 같은 파일을 만들어주었어요.
정확도야 인간보다 정확한… 그건 만족했구요. (가끔 같은 글자인데도 다르다고 표시하는 경우는 있었는데, 아마 인간 눈엔 유사해보이지만 미세하게 글자체가 달라서 그런게 아닌가 싶었습니다. 다른 글자인데 같다고 표시하는 경우는 아직 한번도 없었습니다. 제가 랜덤 체크 해본 결과..)
x열과 y열 비교해서, 서로 내용 다르면 y열에만 노란 배경 칠해달라고 했는데, 그것도 잘 반영되었구요.
다만 x열에서와 다른 글자만!!! 빨갛게 표시해달라고 했는데, 보시다시피 해당 셀의 모든 글자를 붉게 칠해주더라구요. 이것이 문제상황(1) 이었습니다. 이걸 어떻게 해결했는지는 뒤에서 자세히 써볼게요.
그리고 x열이나 y열 중 어느 한 쪽이 아예 비어 있는 행들이 있는데(해당 판본에 원문이 없는 경우), 그 경우에도 비교를 진행하고는 문자열의 차이가 있다고 노랗게 칠해주더라구요. 어느 한 쪽이라도 셀이 비어 있으면 해당 행에 대해서는 비교를 진행하지 않도록 만들고 싶었습니다. 이것이 문제상황(2). 이것도 어떻게 해결했는지 뒤에 쓸게요.