본문 바로가기
Python/점프 투 파이썬

[04] 12345라는 숫자를 12,345처럼 바꾸기

by 가므자 2012. 4. 23.

[04] 12345라는 숫자를 12,345처럼 바꾸기

이 스크립트는 숫자를 나타내는 문자열을 입력받아서 읽기 편한 형식인 123,456처럼 콤마가 섞인 숫자로 바꾸어서 돌려주는 함수이다.

 

# commanumber.py

import string

def comma_number(number):

    if number[0] in ['+', '-']:

        sign_mark, number = number[:1], number[1:] #처음 요소부터 첫번째 요소까지, 첫번째 요소부터 끝까지

    else:

        sign_mark = ''

    try:

        tmp = string.split(number, '.')

        num = tmp[0]; decimal = '.' + tmp[1]

    except:

        num = number; decimal = ''

    head_num = len(num) % 3

    result = ''

    for pos in range(len(num)):

        if pos == head_num and head_num:

            result = result + ','

        elif (pos - head_num) % 3 == 0 and pos:

            result = result + ','

        result = result + num[pos]

    return sign_mark + result + decimal

 

print comma_number("12345678.345678")


결과값: 12,345,678.345678


제일 먼저 '+', '-'가 있는지를 조사하여 있으면 sign_mark라는 변수에 그 기호값을 넣는다. 다음에 '.'이 포함되어 있으면 앞부분과 뒷부분으로 나누어서 앞부분은 ','가 들어갈 숫자부분이고 뒷부분은 소수점 부분이므로 뒷부분을 decimal 변수에 넣는다.

    head_num = len(num) % 3


'.'
앞부분 즉 콤마가 들어갈 숫자의 개수를 세어서 3으로 나눈 나머지 값을 말한다.

    for pos in range(len(num)):     #1-8

        if pos == head_num and head_num:

            result = result + ','

        elif (pos - head_num) % 3 == 0 and pos:

            result = result + ','

        result = result + num[pos]

 

부분이 핵심이 되는 알고리즘이다. 소수점 앞의 숫자의 길이를 세어서 3으로 나눈 나머지 값을 이용해서 맨 처음 나오는 ',' 앞에 몇 개의 숫자가 들어갈지 알 수 있다. 콤마가 들어갈 숫자(num)의 첫 번째 요소부터 끝까지 for문을 통해 들어오면 그 개수를 세어서 head_num, 즉 총 숫자 개수를 3으로 나눈 나머지값의 갯수와 일치하고 head_num 0이 아닌 값이면 ','를 삽입한다. 그런 다음에 3개 간격으로 ','를 추가한다. 위의 알고리즘은 얼핏보면 잘 이해가 가지 않는다. 곰곰히 생각해 보도록 하자.


한참 후에 이 코드를 다시 보고 설명을 읽어도 무슨 내용인지 이해가 가지 않았다. 독자들은 위와 같은 코드를 작성하지 말기 바란다. 누가 보아도 알기 쉽고 당연한 코드를 작성할 수 있도록 노력 해야 한다. 그렇다면 어떻게 이 프로그램을 좀 더 Simple하게 작성할 수 있을까?

그것은 독자의 몫으로 남길까 한다.
이곳에 댓글로 자신의 코드를 남겨보는 것은 어떨까?

(at 2008.02 by 박응용)

import unittest

def comma_number(no):

    t = no.split(".")

    decimal = t[0]

    sosu = ""

    if len(t) > 1: sosu = t[1]

    if sosu:

        return comma(decimal) + "." + sosu

    else:

        return comma(decimal)

 

def comma(no):

    result = []

    numbers = list(str(no))

    numbers.reverse()

    for i, n in enumerate(numbers):

        if i%3 == 0 and i: result.insert(0, ",")

        result.insert(0, n)

    return "".join(result)

 

class CommaTest(unittest.TestCase):

    def test1(self):

        self.assertEquals("", comma_number(""))

        self.assertEquals("1", comma_number("1"))

        self.assertEquals("12", comma_number("12"))

        self.assertEquals("123", comma_number("123"))

        self.assertEquals("1,234", comma_number("1234"))

        self.assertEquals("1,234.02", comma_number("1234.02"))

        self.assertEquals("3,312,345.3234", comma_number("3312345.3234"))

 

if __name__ == "__main__":

    unittest.main()

 

출처 : wikidocs 점프 투 파이썬

'Python > 점프 투 파이썬' 카테고리의 다른 글

[05] 하위디렉토리 검색  (0) 2012.04.23
리스트  (0) 2012.04.23
[03] tab을 4개의 space로 바꾸기  (0) 2012.04.20
[02] 간단한 메모장  (0) 2012.04.20
[01] 내가 프로그램을 만들 수 있을까?  (0) 2012.04.20

댓글