콘텐츠로 이동

hossam.code_checker

hossam.code_checker

제출 코드 대조 모듈

수업에서 배포한 원본 모듈(my_logit, my_ols 등)을 학생이 직접 타이핑해 제출했을 때, 제출 파일이 원본과 어디에서 어떻게 갈라지는지 찾아 준다.

대조 기준이 되는 원본은 다음 순서로 찾는다.

1) `source_dir` 인자가 가리키는 폴더
   -> 강사가 `helpers` 를 고치는 중일 때 재배포 없이 즉시 반영된다.
2) 설치된 `hossam` 패키지 안의 같은 이름 모듈
   -> `helpers` 의 내용이 배포 시점에 패키지로 동기화되므로, 학생이
      `pip install -U hossam` 하면 최신 원본이 기준이 된다.
3) 패키지에 동봉된 지문 파일(`_fingerprints/*.py.json`)
   -> 원본 모듈을 배포에서 빼는 경우를 위한 대비책.

보고서에는 제출한 코드만 실린다. 어느 함수의 어느 줄이 갈라지는지를 학생 본인의 코드로 짚어 주되, 그 자리에 들어가야 할 원본 코드는 싣지 않는다. 따라서 학생은 고쳐야 할 지점을 정확히 알면서도 정답을 받아 적을 수는 없다. (3)번 경로는 해시만 담기므로 원본 복원 자체가 불가능하다.

대조는 세 가지를 본다.

1) 시그니처 · 기본값   `backward=False` 를 `backward=True` 로 적는 유형의 사고.
                      호출부에서 인자를 넘기지 않는 경우 조용히 결과가 달라지므로
                      가장 먼저, 가장 크게 보고한다.
2) 본문 구조          주석 · 문서화 문자열 · 공백 · 따옴표 종류를 모두 지우고
                      AST 로 정규화한 뒤 비교한다. 손으로 옮겨 적은 코드는 표기가
                      제각각이므로, 정규화 없이는 diff 가 의미를 갖지 못한다.
3) 임포트             원본이 가져오는 이름이 제출에 빠져 있는지 확인한다.

본문 차이는 다시 두 가지로 나뉜다.

구조 차이   코드의 모양 자체가 다르다. 실행 결과가 달라질 가능성이 높다.
문자열 차이 코드 모양은 같고 문자열 내용만 다르다. 대개 표기 문제지만,
            딕셔너리 키나 비교 대상 문자열이면 실행에 영향을 준다.

사용 방법 (학생)

from hossam import code_checker

r = code_checker.diff("my_logit", "1.py")   # 대조 결과를 보고서로 출력
r.show("fit_pipeline")                        # 특정 함수만 자세히 보기
r.defaults                                    # 기본값 불일치 표 (DataFrame)
r.functions                                   # 함수별 판정 표 (DataFrame)

노트북에서는 HTML 보고서로, 그 밖에서는 글자 보고서로 자동 전환된다. 형식을 직접 고르거나 파일로 남기려면 다음을 쓴다.

r.report("markdown")                          # 마크다운으로 출력
open("결과.md", "w").write(r.to_markdown())    # 파일로 저장
open("결과.html", "w").write(r.to_html())

사용 방법 (강사)

# 아직 배포되지 않은 helpers 의 최신 내용을 기준으로 점검
code_checker.diff("my_logit", "1.py", source_dir="./helpers")

# 원본 모듈을 배포에서 빼는 경우에만 필요한 지문 생성
code_checker.build("./helpers")

CompareResult

제출 파일과 원본을 대조한 결과를 담는 객체.

Attributes:

Name Type Description
module str

원본 모듈 이름.

path str

제출 파일 경로.

origin str

대조 기준으로 삼은 원본이 어디에서 왔는지.

defaults DataFrame

기본값이 다른 파라미터 표.

params DataFrame

이름 · 순서가 다른 파라미터 표.

functions DataFrame

함수별 판정 표.

imports DataFrame

임포트 불일치 표.

details dict

함수별 본문 불일치 위치 목록.

source list

제출 파일의 줄 목록. 문제 지점의 코드를 보여 줄 때 쓴다.

force bool

문자열 내용만 다른 곳까지 담았는지 여부.

suppressed int

문자열 차이라서 보고서에서 뺀 곳의 수.

total property

total

int: 원본에 들어 있는 함수의 수.

matched property

matched

int: 원본과 일치하는 함수의 수.

ok property

ok

bool: 모든 항목이 원본과 일치하는지 여부.

problems property

problems

int: 본문에서 발견된 불일치 지점의 총 개수.

report

report(format=None, functions=None)

대조 결과를 보고서로 출력한다.

Parameters:

Name Type Description Default
format str

'html' · 'markdown' · 'text' 중 하나. None 이면 노트북에서는 'html', 그 밖에서는 'text' 를 쓴다 (기본값: None).

None
functions list

보고서에 담을 함수 이름 목록. None 이면 전체 (기본값: None).

None

show

show(name, format=None)

특정 함수의 불일치 내역만 자세히 출력한다.

Parameters:

Name Type Description Default
name str

확인할 함수 이름.

required
format str

출력 형식 (기본값: None → 자동).

None

to_html

to_html(functions=None)

대조 결과를 HTML 문자열로 만든다.

Parameters:

Name Type Description Default
functions list

보고서에 담을 함수 이름 목록 (기본값: None → 전체).

None

Returns:

Name Type Description
str

HTML 문자열. 파일로 저장하거나 IPython.display.HTML 로 표시한다.

to_markdown

to_markdown(functions=None)

대조 결과를 마크다운 문자열로 만든다.

Parameters:

Name Type Description Default
functions list

보고서에 담을 함수 이름 목록 (기본값: None → 전체).

None

Returns:

Name Type Description
str

마크다운 문자열.

to_text

to_text(functions=None)

대조 결과를 터미널용 글자 보고서로 만든다.

Parameters:

Name Type Description Default
functions list

보고서에 담을 함수 이름 목록 (기본값: None → 전체).

None

Returns:

Name Type Description
str

보고서 문자열.

analyze_source

analyze_source(source, module=None)

파이썬 소스코드를 읽어 지문 딕셔너리를 만든다.

소스코드를 실행하지 않고 구문만 해석하므로, 임포트가 깨져 있거나 실행에 부작용이 있는 파일도 안전하게 분석할 수 있다.

Parameters:

Name Type Description Default
source str

분석할 파이썬 소스코드.

required
module str

지문에 기록할 모듈 이름 (기본값: None).

None

Returns:

Name Type Description
dict

지문 딕셔너리. 함수별 시그니처 · 해시 · 문장 해시를 담는다.

Raises:

Type Description
SyntaxError

소스코드에 구문 오류가 있는 경우.

analyze_file

analyze_file(path, module=None)

파이썬 파일을 읽어 지문 딕셔너리를 만든다.

Parameters:

Name Type Description Default
path str

분석할 파이썬 파일 경로.

required
module str

지문에 기록할 모듈 이름. None 이면 파일명을 사용한다 (기본값: None).

None

Returns:

Name Type Description
dict

지문 딕셔너리.

Raises:

Type Description
FileNotFoundError

파일이 없는 경우.

build

build(src, out=None, modules=None, verbose=True)

원본 폴더의 모듈들을 훑어 지문 파일을 생성한다.

helpers 의 모듈이 패키지로 동기화되어 배포된다면 이 단계는 필요하지 않다. 설치된 모듈 자체가 대조 기준이 되기 때문이다. 원본 모듈을 배포에서 빼야 하는 경우에만 사용한다. 생성되는 것은 해시와 시그니처뿐이라 원본 코드는 담기지 않는다.

Parameters:

Name Type Description Default
src str

원본 모듈이 들어 있는 폴더 경로 (예: './helpers').

required
out str

지문을 저장할 폴더. None 이면 패키지 안의 _fingerprints (기본값: None).

None
modules list

지문을 만들 모듈 이름 목록. None 이면 my_*.py 전체 (기본값: None).

None
verbose bool

진행 내역 출력 여부 (기본값: True).

True

Returns:

Name Type Description
list

생성된 지문 파일 경로의 목록.

Raises:

Type Description
NotADirectoryError

원본 폴더가 없는 경우.

load_fingerprint

load_fingerprint(module, source_dir=None)

대조 기준이 되는 원본의 지문을 불러온다.

원본은 원본 폴더 → 설치된 패키지 모듈 → 동봉 지문 순서로 찾는다. 앞의 두 경로는 소스에서 그 자리에 지문을 만들어 쓰므로, helpers 를 고치고 배포하면 별도의 지문 생성 없이 그대로 반영된다.

Parameters:

Name Type Description Default
module str

원본 모듈 이름 (예: 'my_logit'). 'hossam.my_logit' 처럼 패키지 이름이 붙어 있어도 된다.

required
source_dir str

원본 폴더 경로. 지정하면 이 폴더를 최우선으로 참조한다 (기본값: None).

None

Returns:

Name Type Description
dict

지문 딕셔너리. 어느 경로에서 왔는지가 origin 키에 담긴다.

Raises:

Type Description
FileNotFoundError

어느 경로에서도 원본을 찾지 못한 경우.

list_modules

list_modules()

대조할 수 있는 모듈 이름의 목록을 돌려준다.

설치된 패키지의 my_*.py 모듈과 동봉된 지문을 합쳐서 돌려준다.

Returns:

Name Type Description
list

대조 가능한 모듈 이름 목록.

diff

diff(
    module,
    path,
    source_dir=None,
    report=True,
    progress=True,
    force=False,
)

제출 파일을 원본 모듈의 지문과 대조한다.

제출 파일은 실행하지 않고 구문만 해석하므로, 임포트가 깨져 있거나 실행 시 부작용이 있는 파일도 안전하게 대조할 수 있다.

Parameters:

Name Type Description Default
module str

원본 모듈 이름 (예: 'my_logit', 'my_ols').

required
path str

제출한 파이썬 파일의 경로.

required
source_dir str

원본 폴더 경로. 지정하면 동봉 지문 대신 이 폴더를 실시간으로 참조한다. 강사용 (기본값: None).

None
report bool

대조 결과를 바로 출력할지 여부 (기본값: True).

True
progress bool

진행률 표시줄을 보여 줄지 여부 (기본값: True).

True
force bool

문자열 내용만 다른 곳까지 함께 보고할지 여부 (기본값: False). 대부분은 출력 문구의 표기 차이라 실행에 영향이 없으므로 기본으로는 빼고 보여 준다. 딕셔너리 키나 비교 대상 문자열까지 훑어보려면 True. 시그니처의 기본값은 이 설정과 무관하게 항상 대조한다.

False

Returns:

Name Type Description
CompareResult

대조 결과 객체.

Raises:

Type Description
FileNotFoundError

제출 파일이나 모듈 지문이 없는 경우.

SyntaxError

제출 파일에 구문 오류가 있는 경우.