In [1]:
# 정규표현식( 텍스트 => 텍스트에서 의미 있는 데이터만 뽑아내는)
# 하나의 언어라고 보면 된다. 사실 엄청나게 복잡한 분야이다.
# 정규표현식으로 들어가기 위한 개요
# 테스팅 개요

In [2]:
def double(x):
    """x를 받아서 2배 불려주는 좋은 함수입니다."""
    return x * 2

In [3]:
double?

In [4]:
# 테스트 코드(넓은 의미의)
if not double(2) == 4:
    raise Exception()
if not double(10) == 20:
    raise Exception()

In [5]:
def double(x):
    return x * 2 + 1
if not double(2) == 4:
    raise Exception()
# 이렇게 하면 오류


---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-5-51e8d76e517c> in <module>()
      2     return x * 2 + 1
      3 if not double(2) == 4:
----> 4     raise Exception()
      5 # 이렇게 하면 오류

Exception: 

In [ ]:
#테스크 코드 조금 더 쉽게 하기 위해서 assert라는 것이 있다.
assert double(5) is 10

In [6]:
assert double(10) == 20


---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-6-f40e74cb31ec> in <module>()
----> 1 assert double(10) == 20

AssertionError: 
  • 이 자체로 훌륭한 테스트 코드라고 말하는 것은 어렵다.
  • 주피터 노트북용 테스트 코드였다.
  • python에서는 테스트 코드를 작성할 수 있는 unittest 모듈을 제공한다.

In [7]:
# 우선 형태만 보면
# class TestDoubleFunction(unittest.TestCase):  
#     def test_5_should_return_10(self):
#         self.assertEqual(double(5), 10)   # 이거랑 동일 assert double(5) == 10
# 주피터노트북에서는 이러한 형태로 테스트 못한다. 그래서 일단 pass

In [8]:
# 우선 hello.py라는 txt파일을 만든다. 안에 내용은
# def hello(name):
#     print("hello, {name}".format(name=name))
    
# hello("kimkipoy")
# hello("김기표")

In [9]:
%run hello.py


hello, kimkipoy
hello, 김기표
개발 프로세스를 살펴보면
  • TDD => 테스트 주도 개발 ( Test Driven Development )
  • 왜 중요할까요?
  • 테스트 > 코드 => "테스트 코드가 원래 코드보다 더 많으니까 개발 시간이 일단 오래 걸려요"
  • 프로젝트가 커지면 커질수록, 의존성++
  • 테스트 코드 (X) => 유지보수 하기가 굉장히 어렵다.
  • 조그마한 기능 단위로 테스팅을 무조건 시작해야합니다. ( unit test ) => 통합 테스트 ( integration test )
테스트 주도 개발을 시작하는 방법
  • 유닛 테스트를 합니다.
    • 테스트 시나리오 => 일련의 기능들을 어떤 순서와 방법으로 여러 형태를 테스트를 해보는 프로세스를 정한다.
  • TDD Cycle을 아래 3개처럼 부른다.
    • RED => 경고. 테스트가 실패 합니다.
    • GREEN => 테스트가 성공하도록 코드를 변경함
    • Refactor => 계속 성공하면서, 코드를 더 예쁘게 리팩토링 합니다.

In [10]:
# 직접 해 볼 양식
# "김기표, 010-6235-3317, 주소\"
# def preprocess_user_information(information):
#     pass
# "김기표, 010-6235-****"

#함수를 짜기 전에 먼저 테스트 코드를 짠다.

In [11]:
def preprocess_user_information(information):
    return information[:-4] + "****"

assert preprocess_user_information("김기표, 010-6235-3317") == "김기표, 010-6235-****"
assert preprocess_user_information("김기정, 010-6666-3317") == "김기정, 010-6666-****"
assert preprocess_user_information("김기, 010-1111-5736") == "김기, 010-1111-****"

In [ ]:


In [12]:
#root폴더에다가 txt파일을 만들어라. 아래와 같은 양식으로
# 김기표, 880518-1111111
# 김기표일, 880518-222222
# 김기표이, 880518-333333
# 김기표삼, 880518-444444
# 김사, 880518-555555

In [13]:
def get_information(file_name):
    with open(file_name, "r", encoding='utf8') as f:
        return f.read()

In [14]:
get_information("info.txt")


Out[14]:
'김기표, 880518-1111111\n김기표일, 880518-222222\n김기표이, 880518-333333\n김기표삼, 880518-444444\n김사, 880518-555555'

In [15]:
info_file = get_information("info.txt")
informations = info_file.split("\n")
informations
# information = f.readlines()


Out[15]:
['김기표, 880518-1111111',
 '김기표일, 880518-222222',
 '김기표이, 880518-333333',
 '김기표삼, 880518-444444',
 '김사, 880518-555555']

In [16]:
# 프린트를 테스팅하는 것은 불가능
# 프린트 하기 전에 이것을 별로 만들어주는 함수를 만들고 그것을 테스트
def preprocess(information):
    return information[:-7] + "*" * 7

assert preprocess("김기표, 880518-1111111") == "김기표, 880518-*******"
assert preprocess("김기표일, 880518-2222222") == "김기표일, 880518-*******"

In [17]:
[
    preprocess(information)
    for information
    in informations
]


Out[17]:
['김기표, 880518-*******',
 '김기표일, 880518*******',
 '김기표이, 880518*******',
 '김기표삼, 880518*******',
 '김사, 880518*******']

In [18]:
# 정규표현식 ( = Regular Expression; Regex )
# 기본 원리만 알면 => 다 적용할 수 있습니다. ( 기본 원리가 아주 많은 문법 )

info_file


Out[18]:
'김기표, 880518-1111111\n김기표일, 880518-222222\n김기표이, 880518-333333\n김기표삼, 880518-444444\n김사, 880518-555555'

In [19]:
import re   #re라는 패키지에서 정규표현식 제공

In [20]:
pattern = re.compile("(?P<birth>\d{6})[-]\d{7}")
# 940223-1701234  => birth == "940223"   (birth는 변수명)

In [21]:
pattern.sub("\g<birth>-*******", info_file)


Out[21]:
'김기표, 880518-*******\n김기표일, 880518-222222\n김기표이, 880518-333333\n김기표삼, 880518-444444\n김사, 880518-555555'