Skip to content

Instantly share code, notes, and snippets.

@jjangga0214
Last active September 19, 2017 00:47
Show Gist options
  • Save jjangga0214/21f1c0dcdd3e8d6482fca7a6acf5e90d to your computer and use it in GitHub Desktop.
Save jjangga0214/21f1c0dcdd3e8d6482fca7a6acf5e90d to your computer and use it in GitHub Desktop.

이 문서는 기존코드에서 변경, 또는 추가된 부분을 기술합니다

코드 리뷰 과정에서 주로 다른 팀원들의 코드를 리뷰하는 데에 포커스를 맞추었고, 제 코드는 코드 리뷰를 통해 변경된 부분이 없었습니다. 이후 등장하는 내용은 기존에 수업에서 받은 test3_4.py 파일에서 달라진 주요한 부분들을 간단히 서술합니다. 만약, 정확하게 diff 된 내용을 보고 싶으시다면 아래의 링크에 접속하여 Files changed 탭에서 확인하실 수 있습니다.

https://github.com/sw-proj-2-2017/class-1-jjanggaK/compare/cc8508e58c9e2723add946d764d9bcf176b6b387...4c456c3f92ee89ed22e1a7770ba4ba88dd7f9b38

Demo

demo

Semantics

종류 변경 전 변경 후 설명
함수명 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를 사용

Syntaxes and Approaches

  • 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)

Logics

  • 유연한 명령문

    • 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]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment