U E D R , A S I H C RSS

TFP예제/Wiki Page Gather


1. 프로그램 개요

집�서 모�모�� �리다가 전� ��해�었었� MindMap � ��� 났다. Page간 관계들� 대한 Navigation� 위한. 무작정 코딩부터 하려고 했는� 머릿�� 정리가 �질 않았다. 연습장� �리저리 쓰고 그리고 했지만. -_-; '너는 왜 공부하고 실천� 안하는 것�야!' 공부란 머리로 절반, 몸으로 절반� �힌다. 컴공�서 '백견� 불여�타' 란 �� 괜히 나오는 것� 아니리�.

파��� 실행시켰다.

2. 프로그래� 중 �낀�

  • 'ìƒ�ê°�í•  수 있는 가장 단순한 것부터 ìƒ�ê°�하ë�¼.' ë””ìž�ì�¸ì�€ TFP 와 Refactoringì�˜ 과정만으로 ì–´ëŠ�ì •ë�„ 보장ì�´ ë�œë‹¤. TFPì�„ 추구하는 ì�´ìƒ� 기능와 ì�˜ë�„ì—� ì�˜í•œ 모듈화가 기본ì �으로 ì�´ë£¨ì–´ì§„다. (여태ê»�ì�˜ 경험 -- 그래봤ìž� 3번째지만 -- ì—� ì�˜í•˜ë©´, TFP를 하면서 LongMethod 냄새가 난 ì �ì�´ 없었다. (LongMethod와 Bad Smell ì—� 대해서는 BadSmellsInCode를 참조하ë�¼.) ë§Œì�¼ 중복코드 등ì�˜ 문제가 ë°œìƒ�하ë�”ë�¼ë�„ 기존ì�˜ 막무가내ì‹� ë°©ì‹�ì—� 비해 ê·¸ 빈ë�„ê°€ ì �다. ë§Œì�¼ Bad Smell ì�´ 난다면 Refactoring ì�„ 하면 ë�œë‹¤. (참고로 ë°‘ì�˜ 소스는 Refactoringì�˜ 과정ì�€ 거치지 않았다.)

  • Python ì�´ë�¼ëŠ” 툴ì�´ ì°¸ 재미있는 ë…€ì„�ì�´ë�¼ ìƒ�ê°�한다. ë°©ì‹�ì�´ì•¼ basicì—�서ì�˜ 그것ì�´ê² ì§€ë§Œ, 'ì�¸í„°í”„리터언어ë�¼ëŠ” 것ì�´ 쉽고 편하다' ì�˜ ì�´ìœ ë¥¼ 다시 ìƒ�ê°�하게 해준 계기가 ë�˜ì—ˆë‹¤. ì�¼ë°˜ì �으로 우리가 프로그래ë°�ì�„ í•  때는 (여기서는 C++ì�´ë�¼ 하ìž�) Visual C++ ì�„ 하나만 ë�„어놓고 프로그래ë°� 하는 경우가 별로 없다. 보통 product code 를 위한 하나, 해당 함수 기능ì�˜ 부분구현 (임시코드 구현)ì�„ 위한 하나. 서버-í�´ë�¼ì�´ì–¸íЏ 프로그래ë°�ì�¸ 경우ì—�는 3개를 ë�„우는 경우ë�„ 다반사ì�´ë‹¤. Python ì�˜ shell ì�€ 임시코드를 구현하는ë�° 매우 편리한 ë�„구ì�´ë‹¤. (한편 ì�´ì¯¤ë�˜ë©´ 검문ì�´ 필요하다. VS 2-3ê°œ ë�„우는 ê±°ëž‘ python IDLEì�„ 2-3ê°œ ë�„우는 ê±°ëž‘ 다를바가 ë­�ëƒ�.. --; ë‚´ê°€ ë§�하고 ì‹ì�€ 것ì�€ C++ì�´ë‚˜ PHPì—� 파ì�´ì�¬ì²˜ëŸ¼ 공통 ì�¸í„°í”„리터 쉘ì�´ 있었으면 하는 것. -_a í��í��..) 암튼. 나는 모ì�¸ëª¨ì�¸ì†ŒìŠ¤ë¥¼ 보면서 제목 검색 관련 ì�¼ë¶€ 코드를 짤ë�¼ì„œ 쉘ì—�서 간단히 실행해보고 검토하고 실제 소스ì—� ì �용해볼 수 있었다.


3. WikiPageGatherTestCase.py

~cpp 
import unittest
from WikiPageGather import *

class WikiPageGatherTestCase (unittest.TestCase):
    def setUp (self):
        self.pageGather = WikiPageGather ()

    def tearDown (self):
        self.pageGather = None
    
    def testConvertWikiPageNameToMoinFileName (self):
        self.assertEquals (self.pageGather.WikiPageNameToMoinFileName ('''한글테스트'''), '''_c7_d1_b1_db_c5_d7_bd_ba_c6_ae''')
        self.assertEquals (self.pageGather.WikiPageNameToMoinFileName ("FrontPage"), "FrontPage")

    def testGetPageNamesFromPage (self):
        self.pageGather.SetPage ("FrontPage")
        self.assertEquals (self.pageGather.GetPageNamesFromPage (), ["LearningHowToLearn", "ActiveX", "Python", "XPInstalled", "TestFirstProgramming", "한글테스트", "PrevFrontPage"])

    def testGetPageNamesFromString (self):
        strings = "Test First In TestFirstIn TesF TestFi guuweo StringIn"
        self.assertEquals (self.pageGather.GetPageNamesFromString (strings), ["TestFirstIn", "TestFi", "StringIn"])
        strings = '''["Testing"] ["Testing The Program"] higu TestFirst twet'''
        self.assertEquals (self.pageGather.GetPageNamesFromString (strings), ["Testing", "Testing The Program", "TestFirst"])

    def testIsHeadTagLine (self):
        strings = "== testing =="
        self.assertEquals (self.pageGather.IsHeadTagLine (strings), 1)
        strings = "tese ewfe ewfw"
        self.assertEquals (self.pageGather.IsHeadTagLine (strings), 0)

    def testRemoveHeadLine (self):
        strings = '''=== ExtremeProgramming ===\ntesting.. -_-a\n== TestFirst Programmin ==\nfwe\n'''
        self.assertEquals (self.pageGather.RemoveHeadLine (strings), "testing.. -_-a\nfwe\n")
        

    def testGetWikiPage(self):
        self.assertEquals (self.pageGather.GetWikiPage ("FrontPage"), '=== Reading ===\n' +
                           '["LearningHowToLearn"]\n\n\n=== C++ ===\n["ActiveX"]\n\n' +
                           '[[Include(ActiveX,Test,1)]]\n\n=== Python ===\n["Python"]\n\n' +
                           '=== ExtremeProgramming ===\n * ["XPInstalled"]\n * TestFirstProgramming\n'+
                           ' * ["ÇѱÛÅ׽ºƮ"]\n\n----\n["PrevFrontPage"]\n\n----\n')

suite = unittest.makeSuite (WikiPageGatherTestCase, "test")

runner = unittest.TextTestRunner ()
runner.run (suite)

4. WikiPageGather.py

~cpp 
import string, urllib, re

class WikiPageGather:
    def __init__(self):
        self.pagePath = "f:\web\wiki-moinmoin\data\text\"
        self.pagename = ''

    def WikiPageNameToMoinFileName (self,pagename):
        safe = string.letters + string.digits
        res = list(pagename)
        for i in range(len(res)):
            c = res[i]
            if c not in safe:
                res[i] = '_%02x' % ord(c)
        return string.joinfields(res, '')

    def SetPage (self, pagename):
        self.pagename = pagename
     
    def GetWikiPage (self, pagename):
        fullpathname = self.pagePath + self.WikiPageNameToMoinFileName (pagename)
        pagefile = open (fullpathname, 'r')
        lines = pagefile.readlines ()

        page = ''
        for line in lines:
            page += line

        pagefile.close()

        return page

    def RemoveHeadLine (self, lines):
        lines = string.split (lines, "\n")

        resultText = ''
        for line in lines:
            if self.IsHeadTagLine (line):
                continue
            elif line == '':
                continue
            resultText += line + "\n"

        return resultText
        
    def IsHeadTagLine (self, strings):
        try:
            if strings[0] == '=':
                return 1
            elif strings[0:2] == '==':
                return 1
            elif strings[0:3] == '===':
                return 1
            else:
                return 0
        except IndexError:
            return 0

    def GetPageNamesFromPage (self):
        page = self.GetWikiPage (self.pagename)
        page = self.RemoveHeadLine (page)
        pagenamelist = []
        pagenamelist += self.GetPageNamesFromString (page)

        return pagenamelist
        
    def GetPageNamesFromString (self, strings):
        PageNameRegularStr = '''(([A-Z][a-z0-9]+){2,})|(\[".*?"\])'''
        PageNameReg = re.compile (PageNameRegularStr)
        PageNameReg.findall (strings)

        pagenamelist = []
        for pagename in PageNameReg.findall (strings):
            if pagename[0] != '':
                pagenamelist.append (pagename[0])
            elif pagename[2] != '':
                realname = string.replace (pagename[2], '''["''', '')
                realname = string.replace (realname, '''"]''', '')
                pagenamelist.append (realname)

        return pagenamelist
    
    def main (self):
        self.SetPage ("FrontPage")
        for pagename in self.GetPageNamesFromPage ():
            print "pagename : " + pagename
            print "filename : " + self.WikiPageNameToMoinFileName (pagename)
        

if __name__ == "__main__":
    pageGather = WikiPageGather ()
    pageGather.main ()

5. 실행 결과

집�서 �리고 있는 모�모� 디렉토리 기준임. (Python shell � IDLE 한글 패치를 해주지 않아서 그런지 �래는 한글� 깨져서 나온다. 약간 편집했�.)

~cpp 
pagename : LearningHowToLearn
filename : LearningHowToLearn
pagename : ActiveX
filename : ActiveX
pagename : Python
filename : Python
pagename : XPInstalled
filename : XPInstalled
pagename : TestFirstProgramming
filename : TestFirstProgramming
pagename : 한글테스트
filename : _c7_d1_b1_db_c5_d7_bd_ba_c6_ae
pagename : PrevFrontPage
filename : PrevFrontPage

6. 문제�

위ì�˜ 예ì—�서는 해당 모듈ì—�서 FrontPage í™”ì�¼ì�„ ì§�ì ‘ open 했다. 위키ì—�서 FrontPageê°€ 바뀌었ì�„ 경우ì—�는 해당 알고리즘ì�´ 올바르다 하ë�”ë�¼ë�„ 테스트 코드ì—�서 ì—�러를 유발할 것ì�´ë‹¤. - 테스트를 위한 FrontPage í™”ì�¼ì�„ 따로 ë¹¼ë‘�는 방법ì�´ 있겠군. -_-; (문제를 명확하게 í•´ë‘�ë©´ 해결방법ì�´ ë�„ìœë�˜ê¸° 쉽다. ^^;)


Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:28:10
Processing time 0.0202 sec