평소 RSS를 통해 구독하고 있던 OK 괜찮아 다 잘 될거야 에
오늘 초보개발자의 알고리즘 도전이라는 포스트가 올라와서 유심히 보던중 +_+
테스트 케이스부터 만들고 시작하는것을 보고

Python 작성에 TDD를 실제 적용해보고자 하던차에 잘됬다고 생각하고 저도 한번 해보았습니다.
퀴즈문제는 초보 개발자 코드 트레이닝, Part 알고리즘과 성능 이 링크에 있습니다.

우선 TDD를 적용하고자 했던 만큼 테스트 코드를 먼저 만들었습니다.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import unittest
from ArrayEiBo import *


class ArrayTest(unittest.TestCase):
    def testeither (self):
        listA = [1,3,4,5,6,9,7]
        listB = [4,5,8,9,10,15,-1]
        ar = ArrayEiBo()
        self.assertEquals(ar.either(listA, listB), [4,5,9])


    def testboth (self):
        listA = [1,3,4,5,6,9,7]
        listB = [4,5,8,9,10,15,-1]
        ar = ArrayEiBo()
        self.assertEquals(ar.both(listA, listB), [-1,1,3,4,5,6,7,8,9,10,15])


    def testisSubstring (self):
        first = (‘a’, ‘b’, ‘c’)
        second = (‘a’, ‘c’ , ‘b’, ‘c’)
        third = (‘a’, ‘a’, ‘b’, ‘c’)
        ar = ArrayEiBo()
        self.assertEquals(ar.isSubstring(first, second), False)
        self.assertEquals(ar.isSubstring(first, third), True)


    def testmatch (self):
        first = (‘(‘, ‘[', '<', '{', '}', '>', ']‘, ‘)’)
        second = (‘(‘, ‘[', '<', '{', '>', '}', ']‘, ‘)’)
        third = (‘(‘, ‘a’, ‘c’, ‘)’, ‘[', '{', '}', ']‘)
        fourth = (‘<’, ‘[', '<', '{', '}', '>', ']‘, ‘)’)
        fifth = (‘a’, ‘[', '<', '{', 'a' ,'}', '>', ']‘)
        sixth = (‘a’, ‘[', '>')
        ar = ArrayEiBo()
        self.assertEquals(ar.match(first), True)
        self.assertEquals(ar.match(second), False)
        self.assertEquals(ar.match(third), True)
        self.assertEquals(ar.match(fourth), False)
        self.assertEquals(ar.match(fifth), True)
        self.assertEquals(ar.match(sixth), False)


if __name__ == '__main__':
    unittest.main()

테스트 코드는 퀴즈에 나왔던 기본적인 것 이외에도
예외적으로 테스트해야되겠다 싶은것 몇개를 추가했습니다.
이렇게 테스트코드를 만드는 방식이 맞는지 모르겠네요

저는 both 와 either 을 실행함에 있어서 최종결과에서 정렬을 했습니다.

퀴즈문제의 포스트에 나와있던 시간체크나 성능 최적화에는 신경을 쓰지 못한점이 아쉽지만,
TDD 를 실천해보고 재미있다는 느낌을 얻은게 큰 소득이랄까요?
리팩토링할때도 테스트 코드가 있으니 좀더 명확하고 코드에 자신감이 생기더군요

마지막 match 함수의 경우에는
너무 긴 함수가 제작된게 아닌가 싶어서 리팩토링도 해주어야 할듯 싶구요

앞으로 코드 골프나 퀴즈문제를 더 많이 풀어보면서
알고리즘을 최적화하는 방식을 더 공부해야겠다는 생각이 들었습니다.

제가 작성한 소스 코드는 아래 첨부합니다.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

class ArrayEiBo:
       
    def __init__ (self):
        pass


    def either (self, listA, listB):
        eitherList = []
        for item in listA:
            if item in listB:
                eitherList.append(item)
        eitherList.sort()
        return eitherList
       
    def both (self, listA, listB):
        noeitherList = []
        for item in listA:
            if item not in listB:
                noeitherList.append(item)
        bothList = noeitherList + listB
        bothList.sort()
        return bothList


    def isSubstring (self, listA, listB):
        isSub = False
        for startNum in range(len(listB)-len(listA)+1):
            if listA == listB[startNum:startNum+len(listA)]:
                isSub = True
                break
        return isSub


    def match (self, listA):
        isMatch = False
        dicDefBracket = {‘<’:'>’,’[':']‘,’{‘:’}',’(‘:’)'}
        listOnlyBracket = []


        for item in listA:
            if (item in dicDefBracket) or (item in dicDefBracket.values()):
                listOnlyBracket.append(item)
       
        adjustCount = 0
        for count in range(len(listOnlyBracket)):
            count += adjustCount
            if listOnlyBracket[count] in dicDefBracket:
                continue
            elif (count-1 >= 0) and (dicDefBracket[listOnlyBracket[count-1]] == listOnlyBracket[count]):
                listOnlyBracket.pop(count-1)
                listOnlyBracket.pop(count-1)
                adjustCount -= 2
            else:
                break


        if len(listOnlyBracket) == 0:
            isMatch = True
       
        return isMatch