코드 리뷰 과정에서 주로 다른 팀원들의 코드를 리뷰하는 데에 포커스를 맞추었고, 제 코드는 코드 리뷰를 통해 변경된 부분이 없었습니다. 이후 등장하는 내용은 기존에 수업에서 받은 test3_4.py 파일에서 달라진 주요한 부분들을 간단히 서술합니다. 만약, 정확하게 diff 된 내용을 보고 싶으시다면 아래의 링크에 접속하여 Files changed 탭에서 확인하실 수 있습니다.
종류 | 변경 전 | 변경 후 | 설명 |
---|---|---|---|
함수명 | readScoreDB | read_score_db | 함수명에는 camelCase 대신 헝가리안 표기법을 적용 |
" | writeScoreDB | write_score_db | " |
" | doScoreDB | do_score_db | " |
" | showScoreDB | print_score_db | ", show는 다의어이므로 명확하게 print를 사용 |
변수명 | dbfilename | db_file_name | 변수명에는 camelCase 대신 헝가리안 표기법을 적용 |
" | inputstr | input_str | " |
" | sortKey | sort_key | " |
" | parse | parsed_input | 함수가 아닌 변수명에는 동사보다는 명사를 사용. 다소 긴게 흠이긴 함 |
" | fH | f | fH는 작명이유가 불명확하고 굳이 고수할 필요가 없어보여 f를 사용 |
-
indentation : tab 으로 들여쓰기 되어 있던 것을 모두 스페이스 4개로 바꾸었습니다.
-
python style : 불필요한 괄호를 삭제하였습니다.
#전 while (True): #후 while True: #전 inputstr = (input("Score DB > ")) #후 input_str = input("Score DB > ").strip()
-
with :
file
객체를 그냥open
한 후close
하는 패턴이 아니라with
구문을 사용하였습니다. -
functional approach :
iterable
자료구조에 대해 빈번히 등장하는 매우 일반적인 처리 - 여기서는 '검색' - 에 대해 전통적인 반복문을 쓰기 보다는 함수형 프로그래밍의 접근 방법을 취했습니다. 다음은 인자로 필드 명과 필드 값을 주어서 일치하는 record 를 모두 찾는 함수입니다.filter
타입의 객체를 반환하고,filter
타입 역시iterable
이어서 반복처리, 또는 다른iterable
타입으로 변환하기 용이합니다.def find_by_field(scdb, field_name, field_val): return filter(lambda p: p[field_name] == field_val, scdb)
-
유연한 명령문
-
space-safe command : 사용자의 입력값의 시작과 끝에 포함된 공백문자를 제거합니다. 다음과 같이 rstrip과 lstrip 함수의 효과를 모두 가지는 strip 함수를 사용하였습니다.
input_str = input("Score DB > ").strip()
-
case-insensitive command :
add
,show
,find
,del
,inc
,quit
과 같은 명령어에 대해서 대소문자를 구별하지 않고 동작합니다. 예를 들어,show Name
,Show Name
,ShoW Name
,SHOW Name
등은 모두 같은 명령어로 인식됩니다. 이를 구현하기 위해 다음과 같이 lower() 함수를 사용해 그 값을 cmd 라는 변수에 담고, 이후 cmd 의 값이 "add"인지, "show" 인지 등을 검사합니다.cmd = parsed_input[0].lower()
-
-
print 형식 재사용 : find 명령어를 입력하거나 show 명령어를 입력시 record 를 같은 형식으로 출력합니다. 때문에 print 하는 부분을 재사용하였습니다.
# records를 iterable한 자료구조로 입력받아 정해진 형식으로 출력한다. def print_score_db(records, keyname): try: sorted_records = sorted(records, key=lambda person: person[keyname]) except KeyError: raise InvalidFieldError() def print_record(record): for attr in sorted(record): print(attr + "=" + str(record[attr]), end=" ") print() for p in sorted_records: print_record(p) # ... 중략 ... # find 명령어에 대한 실행 : 이름이 일치하는 record들만 인자로 건네준다 elif cmd == "find": # (중략) records = find_by_field(scdb, "Name", parsed_input[1]) print_score_db(records, "Name") # ... 중략 ... # show 명령어에 대한 실행 : scdb를 인자로 건네준다 elif cmd == 'show': # (중략) try: print_score_db(scdb, sort_key) except InvalidFieldError: print("찾으려는 필드가 존재하지 않습니다.")
-
유효성 검사 : 사용자가 입력하는 명령어에 대한 유효성 검사를 실시합니다. 만일 유효하지 않은 형식의 명령어가 입력되면 명령어에 알맞은 경고 메세지를 출력합니다. 예시는 다음과 같습니다.
# 유효성 검사 예시 if len(parsed_input) != 4: print("add 의 인자는 이름, 나이, 성적 순서대로 단 3개이어야 합니다.") continue
-
예외처리 : 사용자가 어떤 명령어를 입력하여도 중간에 에러가 발생하는 일 없이 유연하게 동작하도록 하였습니다.
-
del 기능 : 인덱스를 뒤에서부터 검색해 모든 record 가 정상적으로 검사 받고 삭제될 수 있도록 하였습니다.
for i in reversed(range(len(scdb))): if scdb[i]['Name'] == parsed_input[1]: del scdb[i]