Python

[Python] Naming Rule을 적용하여 로또 생성 및 등수 측정 프로그램 작성

SeungbeomKim 2023. 6. 19. 16:06

Naming Rule(네이밍 규칙) 이란?

다양한 사람들과 협업을 할 시, 코드의 가독성과 일관성을 유지하기 위해 만들어진 규칙입니다. 

(변수, 상수, 함수 클래스 등 이름에 권장되는 규칙입니다)

 

저는 클래스를 적용하지 않고, 메서드, 변수, 상수만 사용했기에 기존 코드에 다음과 같은 규칙을 적용하였습니다.

# 메서드명(소문자 + 밑줄(의미 단위로 밑줄 나누기))
# 변수명(소문자 + 밑줄(의미 단위로 밑줄 나누기))
# 전역 변수명(g + 밑줄 + 변수명)
# 상수명(모두 대문자로 사용)

<참고>

http://pythonstudy.xyz/python/article/511-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%BD%94%EB%94%A9-%EC%8A%A4%ED%83%80%EC%9D%BC

 

예제로 배우는 파이썬 프로그래밍 - 파이썬 코딩 스타일

PEP 8 파이썬 코딩 스타일 Python Enhancement Proposal 8 (PEP 8)은 파이썬 코딩 스타일에 대한 가이드를 제시하고 있다. PEP 8은 2001년 귀도 반 로썸에 의해 처음 제안되었으며, python.org 의 PEP 링크에 자세히

pythonstudy.xyz

 

네이밍 규칙을 적용한 코드를 보여드리고, 코드에 대한 내용을 하나씩 설명드리겠습니다. 

 

<코드>

# Python's Naming Rule(네이밍 규칙)(변수, 상수, 함수, 클래스 등의 이름에 권장되는 규칙)
# 메서드명(소문자 + 밑줄(의미 단위로 밑줄 나누기))
# 변수명(소문자 + 밑줄(의미 단위로 밑줄 나누기))
# 전역 변수명(g + 밑줄 + 변수명)
# 상수명(모두 대문자로 사용)

import random

LOTTO_FIRST_NUMBER = 1
LOTTO_LAST_NUMBER = 45
ONE_LOTTO_LENGTH = 6
ALPHA_INDEX = ['A', 'B', 'C', 'D', 'E']
GAME_START_MESSAGE = '로또 게임을 시작합니다.'
INVALID_COMMAND_MESSAGE = '잘못된 명령을 입력하였습니다.'
GAME_OVER_MESSAGE = '게임을 종료합니다.'
MESSAGE_ASKING_IF_YOU_WANT_TO_START_THE_GAME = '로또 게임을 시작하시겠습니까 ? (y/n)'
MESSAGE_ASKING_IF_YOU_WANT_TO_RESTART_THE_GAME = '로또 게임을 다시 진행하실건가요 ? (c/q)'
NUMBER_OF_LOTTO_TICKETS_TO_BUY = '구매할 로또 장 수: '


def get_winning_lotto_numbers_list():
    winning_numbers_list = set()
    while len(winning_numbers_list) < ONE_LOTTO_LENGTH:
        winning_numbers_list.add(random.randint(LOTTO_FIRST_NUMBER, LOTTO_LAST_NUMBER))
    return sorted(winning_numbers_list)


def get_user_lotto_numbers_list():
    user_lotto_numbers_list = set()
    while len(user_lotto_numbers_list) < ONE_LOTTO_LENGTH:
        user_lotto_numbers_list.add(random.randint(1, 45))
    return sorted(user_lotto_numbers_list)


def print_user_lotto_numbers_list(user_lotto_numbers_list):
    for number in user_lotto_numbers_list:
        print(number, end='  ')


def get_bonus_number():
    return random.randint(LOTTO_FIRST_NUMBER, LOTTO_LAST_NUMBER)


def compare_lotto_numbers(user_lotto_numbers, winning_numbers, bonus_number):
    count = 0
    bonus_count = 0

    for number in user_lotto_numbers:
        if number in winning_numbers:
            count += 1

    if bonus_number in user_lotto_numbers:
        bonus_count += 1

    return [count, bonus_count]


def get_matching_numbers(user_lotto_numbers, winning_numbers, bonus_number):
    matching_numbers_list = []
    for number in user_lotto_numbers:
        if number in winning_numbers:
            matching_numbers_list.append(number)

    if bonus_number in user_lotto_numbers:
        matching_numbers_list.append(bonus_number)
    return matching_numbers_list


def print_matching_numbers(match_numbers_list):
    if not match_numbers_list:
        print('당첨 번호가 하나도 없습니다.', end=' ')
    else:
        print(f'당첨 번호 : ', end=' ')
        for number in match_numbers_list:
            if number == bonus_number:
                print(f', 보너스 넘버 {number}', end=' ')
            else:
                print(f'{number}', end=' ')


def print_rank(count_list):
    if count_list[0] == 6:
        print(f'일치하는 개수: {count_list[0]}, 1등')
    elif count_list[0] == 5:
        if count_list[1]:
            print(f'일치하는 개수: {count_list[0]} + 보너스 넘버, 2등')
        else:
            print(f'일치하는 개수: {count_list[0]}, 3등')
    elif count_list[0] == 4:
        print(f'일치하는 개수: {count_list[0]}, 4등')
    elif count_list[0] == 3:
        print(f'일치하는 개수: {count_list[0]}, 5등')
    else:
        print(f'일치하는 개수 3개 이하 꽝 !')


def ask_whether_to_play_a_game():
    return input(f'{MESSAGE_ASKING_IF_YOU_WANT_TO_START_THE_GAME}')


def ask_whether_to_continue_playing_a_game():
    return input(f'{MESSAGE_ASKING_IF_YOU_WANT_TO_RESTART_THE_GAME}')


def ask_how_many_lotto_tickets_to_buy():
    return int(input(f'{NUMBER_OF_LOTTO_TICKETS_TO_BUY}'))


print(f'{GAME_START_MESSAGE}')
while True:
    command = ask_whether_to_play_a_game()
    if command == 'y':
        user_buying_lotto_ticket_count = ask_how_many_lotto_tickets_to_buy()
        # 로또 당첨 번호
        winning_lotto_numbers_list = get_winning_lotto_numbers_list()
        bonus_number = get_bonus_number()

        for j in range(0, user_buying_lotto_ticket_count):
            # 사용자가 구매한 번호
            for i in range(0, 5):
                print(f'{ALPHA_INDEX[i]}  자 동 ', end=' ')
                user_lotto_numbers_list = get_user_lotto_numbers_list()
                print_user_lotto_numbers_list(user_lotto_numbers_list)
                print_rank(compare_lotto_numbers(user_lotto_numbers_list, winning_lotto_numbers_list, bonus_number))
                match_numbers_list = get_matching_numbers(user_lotto_numbers_list, winning_lotto_numbers_list, bonus_number)
                print_matching_numbers(match_numbers_list)
                print()

        print(f'로또 당첨 번호: {winning_lotto_numbers_list}')
        print(f'보너스 번호: {bonus_number}')

        restart_game_option = ask_whether_to_continue_playing_a_game()
        if restart_game_option == 'c':
            continue
        elif restart_game_option == 'q':
            break
        else:
            print(f'{INVALID_COMMAND_MESSAGE}')
    elif command == 'n':
        break
    else:
        print(f'{INVALID_COMMAND_MESSAGE}')

print(f'{GAME_OVER_MESSAGE}')

다음과 같이 변수, 상수, 함수에 의미가 있는 부분을 (밑줄)_로 구분하였고, 함수명도 최대한 코드를 본 사람들이 직관적으로 이해할 수 있도록 작성하였습니다.

 

상수, 변수, 함수의 의미를 하나씩 설명드리겠습니다. 

 

상수(Constant) (문자열 부분 생략)

  1. LOTTO_FIRST_NUMBER, LOTTO_LAST_NUMBER : 로또의 첫 번째 숫자(1), 마지막 숫자(45)
  2. ONE_LOTTO_LENGTH : 로또의 길이 : 6 (6개의 숫자를 맞춰야 하므로 생성되는 로또 하나의 길이는 6, 보너스 숫자는 별도)
  3. ALPHA_INDEX : 인덱스를 숫자로 하지 않고, 알파벳으로 설정 (로또 5000원을 구매하면 인덱스가 A, B, C, D, E로 나오기 때문)

변수(Variable)

  1. user_buying_lotto_ticket_count : 구매할 로또 장 수 (로또 1장당 로또 티켓이 5장(6*5) 생성되도록 설계)
  2. match_numbers_list : 당첨번호와 일치한 유저번호 리스트 
  3. winning_lotto_numbers_list, bonus_number : 로또 당첨 번호, 보너스 번호(random 모듈을 사용해 randint() 메서드를 적용하여 로또 당첨 번호 6개, 보너스 번호 생성)

함수(Function)

  1. get_winning_lotto_numbers_list() : 로또 당첨 번호 리스트 반환
  2. get_user_lotto_numbers_list() : 구매한 랜덤 번호 리스트 반환 
  3. print_user_lotto_numbers_list() : 구매한 랜덤 번호 리스트 출력
  4. get_bonus_number() : 보너스 번호 반환
  5. compare_lotto_numbers() : 구매한 랜덤 번호와 로또 당첨 번호를 비교하고, 각각 맞춘 개수를 반환
  6. get_matching_numbers_list() : 맞춘 로또 번호 리스트 반환
  7. print_matching_numbers_list() : 맞춘 로또 번호 리스트 출력
  8. print_rank() : 순위 출력

<결과 화면>

 

다음과 같이, 3장을 입력하면 1장당 5개의 로또 티켓이 생성되도록 설계하였기에, 총 15장이 생성되었음을 확인할 수 있고 마지막에 로또 당첨 번호와 보너스 번호를 출력하여 직관적으로 확인할 수 있도록 하였습니다. 네이밍 규칙(Naming Rule)을 적용해서 가독성 좋게 로또 생성 및 등수 출력 프로그램을 만들어 볼 수 있었습니다. 

 

<참고 자료>

http://pythonstudy.xyz/python/article/507-%ED%8C%8C%EC%9D%BC%EA%B3%BC-%EB%94%94%EB%A0%89%ED%86%A0%EB%A6%AC

 

예제로 배우는 파이썬 프로그래밍 - 파일과 디렉토리

파이썬에서 파일과 디렉토리 경로 다루기 파이썬에서 디렉토리와 파일경로를 다루는 주요 함수들에 대해 알아보자. 디렉토리 및 파일 경로에 대한 함수들은 os 모듈에 있으므로, os 모듈을 import

pythonstudy.xyz

https://dowtech.tistory.com/38

 

파이썬 Naming Rule

프로그램을 작성함에 있어 변수나 파일의 이름을 짓는게 힘든 경우가 많다. 아마 프로그래밍 경험이 적거나 습관이 되지 않아서 일 것이다. Naming Rule(네이밍 룰)은 코드의 가독성 및 일관성, 여

dowtech.tistory.com