목적
학원 알바를 하면서 C++, python 전용 채점기를 하나 만들었다.
기능은 크게 아래 3가지이다.
1. g++ 컴파일
2. 실행파일 삭제
3. 정답 여부 체크 (C++ , Python)
이때 3. 정답 여부 체크의 구조는
checkCpp() / checkPy()에서
1. 폴더 이름 가져오기
2. argv 개수에 따라 수행
2-1 argv 개수가 2개이면 전체 채점
2-2 argv 개수가 3개이면 적힌 파일만 채점
(이때, 정답 개수와 틀린 문제는 checkInputCPP / Py가 검사함)
checkInputCpp() / checkInputPy()
-> path명만 다르고 전체 동작은 동일함
기능이 겹치는게 많아서 매개변수로 경로명 같은걸 전달하면 코드가 더 깔끔해질거 같다
이전 코드
def checkCpp():
folder_name = os.listdir(f'{path}/file')
folder_name.sort(key= lambda x: int(x.split('.')[0]))
length = len(sys.argv)
if(length == 2):
for i in range(1, 31):
folder = folder_name[i-1]
cnt, wrong = checkInputCPP(folder, i)
printResult(folder, cnt, wrong)
elif(length == 3):
file = int(sys.argv[2])
cnt, wrong = checkInputCPP(folder_name[file-1], file)
printResult(folder_name[file-1], cnt, wrong)
def checkPy():
folder_name = os.listdir(f'{path}/file')
folder_name.sort(key= lambda x: int(x.split('.')[0]))
length = len(sys.argv)
if(length == 2):
for i in range(1, 31):
folder = folder_name[i-1]
cnt, wrong = checkInputPy(folder, i)
printResult(folder, cnt, wrong)
elif(length == 3):
file = int(sys.argv[2])
cnt, wrong = checkInputPy(folder_name[file-1], file)
printResult(folder_name[file-1], cnt, wrong)
def printResult(file, cnt, wrong):
print(f'{file:30s}\t: {cnt} SUCCESS', end='')
if(wrong): print(' - ', end='')
for i in wrong:
print(i, end=' ')
print()
def checkInputCPP(folder, file):
cnt = 0
wrong = []
for i in range(1, 6):
f = open(f"{path}/file/{folder}/in{i}.txt", 'r')
lines = f.readlines()
f.close()
result = subprocess.run([f'{path}/cpp/{file}'], \
input=''.join(lines), text=True, capture_output=True).stdout.strip()
f = open(f"{path}/file/{folder}/out{i}.txt", 'r')
lines = ''.join(f.readlines()).strip()
if(result == lines):
cnt += 1
else:
wrong.append(i)
return cnt, wrong
def checkInputPy(folder, file):
cnt = 0
wrong = []
for i in range(1, 6):
f = open(f"{path}/file/{folder}/in{i}.txt", 'r')
lines = f.readlines()
f.close()
result = subprocess.run(['/usr/bin/python3', f'{path}/py/{file}.py'], \
input=''.join(lines), text=True, capture_output=True).stdout.strip()
f = open(f"{path}/file/{folder}/out{i}.txt", 'r')
lines = ''.join(f.readlines()).strip()
if(result == lines):
cnt += 1
else:
wrong.append(i)
return cnt, wrong
수정 코드
main에서 check 함수를 실행할 때, argv의 값에 따라 type에 'py' / 'cpp' 둘 중 하나를 넘겨주어 구분할 수 있도록 고쳤다.
checkInput은 파일 종류에 따라 subprocess.run 함수의 매개변수 값이 달라지므로 type에 따라 command를 지정해주었다.
def check(type):
folder_name = os.listdir(f'{path}/file')
folder_name.sort(key= lambda x: int(x.split('.')[0]))
length = len(sys.argv)
if(length == 2):
for i in range(1, 31):
folder = folder_name[i-1]
cnt, wrong = checkInput(type, folder, i)
printResult(folder, cnt, wrong)
elif(length == 3):
file = int(sys.argv[2])
cnt, wrong = checkInput(type, folder_name[file-1], file)
printResult(folder_name[file-1], cnt, wrong)
def checkInput(type, folder, file):
cnt = 0
wrong = []
for i in range(1, 6):
f = open(f"{path}/file/{folder}/in{i}.txt", 'r')
lines = f.readlines()
f.close()
command = []
if type == 'py':
command = [f'{path}/cpp/{file}']
elif type == 'cpp':
command = ['/usr/bin/python3', f'{path}/py/{file}.py']
result = subprocess.run(command, \
input=''.join(lines), text=True, capture_output=True).stdout.strip()
f = open(f"{path}/file/{folder}/out{i}.txt", 'r')
lines = ''.join(f.readlines()).strip()
if(result == lines):
cnt += 1
else:
wrong.append(i)
return cnt, wrong
def printResult(file, cnt, wrong):
print(f'{file:30s}\t: {cnt} SUCCESS', end='')
if(wrong): print(' - ', end='')
for i in wrong:
print(i, end=' ')
print()
아쉬운 점
폴더까지 처리하고 싶었는데 채점을 실제로 하는 시간보다 채점기를 만드는 시간이 배로 드는거 같아서 생략했다.
>> 230124 명령어에 경로 받아서 처리하도록 수정함
'개발 > 기타' 카테고리의 다른 글
사이드 프로젝트:: 자동 메일링 서비스 (0) | 2025.03.22 |
---|---|
DB:: DB 설계 고민 (1) | 2023.11.12 |
Flutter:: 참고 문서 (1) | 2022.09.08 |
Flutter:: 갤러리에서 이미지 가져오기 (0) | 2022.08.10 |
Windows :: 윈도우에 등록된 와이파이 비번 알아내기 (0) | 2022.05.05 |