[Do it! 점프 투 파이썬-스터디 노트] 06장 파이썬 프로그래밍, 어떻게 시작해야할까?(06-4~06-6)

2021. 4. 21. 17:13PYTHON/Do it! 점프 투 파이썬

 

06장 파이썬 프로그래밍, 어떻게 시작해야할까?

 

 

06-4 간단한 메모장 만들기

 

Q. 원하는 메모를 파일에 저장하고 추가 및 조회가 가능한 간단한 메모장 만들기

 

가장 먼저 할 일은 메모를 추가하는 것이다. 다음 명령을 실행했을 때 메모를 추가할 수 있도록 만들어보자.

python memo.py -a "Life is too short!"

memo.py는 작성할 파이썬 프로그램 이름이고 -a는 이 프로그램의 실행 옵션, "Life is too short!"는 추가할 메모 내용이다.

 

1. 우선 다음과 같이 입력으로 받은 옵션과 메모를 출력하는 코드를 작성해보자.

#C:/doit/memo.py
import sys

option=sys.argv[1]
memo=sys.argv[2]

print(option)
print(memo)

sys.argv는 프로그램을 실행할 때 입력된 값을 읽어들일 수 있는 파이썬 라이브러리다. sys.argv[0]는 입력받은 값 중에서 파이썬 프로그램 이름인 memo.py이므로 우리가 만들려는 기능에는 필요 없는 값이다. 그리고 순서대로 sys.argv[1]은 프로그램 실행 옵션 값이 되고 sys.argv[2]는 메모 내용이 된다.

 

2. memo.py를 작성했다면 다음 명령을 수행해보자. 입력으로 전달한 옵션과 메모 내용이 그대로 출력되는 것을 확인할 수 있다.

C:\doit>python memo.py -a "Life is too short"
-a
Life is too short

 

3. 이제 입력으로 받은 메모를 파일에 쓰도록 코드를 변경해보자.

#C:/doit/memo.py
import sys

option=sys.argv[1]

if option=='-a'"
    memo=sys.argv[2]
    f=open('memo.txt', 'a')
    f.write(memo)
    f.write('\n')
    f.close()

옵션이 -a인 경우에만 memo 값을 읽어 memo.txt 파일에 그 값을 쓰도록 코드를 작성했다. 여기에서 메모는 항상 새로운 내용이 작성되는 것이 아니라 한 줄씩 추가되어야 하므로 파일 열기 모드를 a로 했다. 그리고 메모를 추가할 때마다 다음 줄에 저장되도록 줄바꿈 문자(\n)도 추가로 파일에 쓰게 했다.

 

4. 이제 다음 명령을 수행해보자.

C:\doit>python memo.py -a "Life is too short"
C:\doit>python memo.py -a "You need python"

그리고 파일에 정상적으로 메모가 기입되었는지 확인해보자.

C:\doit>type memo.txt
Life is too short
You need python

 

5. 이번에는 작성한 메모를 출력하는 부분을 만들 차례이다. 메모 출력은 다음과 같이 동작하도록 만들어보자.

python memo.py -v

메모 추가는 -a 옵션을 사용하고 메모 출력은 -v 옵션을 사용한다.

 

이제 메모 출력을 위해 다음과 같이 코드를 변경해보자.

#C:/doit/memo.py
import sys

option=sys.argv[1]

if option=='-a':
    memo=sys.argv[2]
    f=open('memo.txt', 'a')
    f.write(memo)
    f.write('\n')
    f.close()
elif option=='-v':
    f=open('memo.txt')
    memo=f.read()
    f.close()
    print(memo)

옵션으로 -v가 들어온 경우 memo.txt 파일을 읽어서 출력한다.

 

6. 코드를 수정한 후 다음과 같은 명령을 수행하면 입력한 메모가 그대로 출력되는 것을 확인할 수 있다.

C:\doit>python memo.py -v
Life is too short
You need python

 

 

 

 

 

06-5 탭을 4개의 공백으로 바꾸기

 

Q. 문서 파일을 읽어서 그 문서 파일 안에 있는 탭(tab)을 공백(space) 4개로 바꾸어주는 스트립트 작성하기

 

python tabto4.py src dst

tabto4.py는 우리가 작성해야할 파이썬 프로그램 이름이고 src는 탭을 포함하고 있는 원본 파일 이름이다. dst는 파일 안의 탭을 공백 4개로 변환한 결과를 저장할 파일 이름이다.

 

예를 들어 a.txt 파일에 있는 탭을 4개의 공백으로 바꾸어 b.txt 파일에 저장하고 싶다면 다음과 같이 수행해야 한다.

python tabto4.py a.txt b.txt

 

1. 우선 다음과 같이 tabto4.py 파일을 작성해보자.

#C:/doit/tabto4.py
import sys

src=sys.argv[1]
dst=sys.argv[2]

print(src)
print(dst)

sys.argv를 사용하여 입력값을 확인하도록 만든 코드이다.

 

2. 다음과 같이 수행했을 때 입력값이 정상적으로 출력되는지 확인해보자.

C:\doit>python tabto4.py a.txt b.txt
a.txt
b.txt

 

3. 테스트를 위한 원본 파일(탭을 포함하는 파일)인 a.txt를 다음과 같이 작성한다. 각 단어는 탭(\t) 문자로 분리되도록 입력해야 한다.

Life    is    too    short

You    need    python

 

4. 이제 탭 문자를 포함한 a.txt 파일을 읽어서 탭을 공백 4개로 변환할 수 있도록 코드를 변경해보자.

C:/doit/tabto4.py
import sys

src=sys.argv[1]
dst=sys.argv[2]

f=open(src)
tab_content=f.read()
f.close()

space_content=tab_content.replace("\t", " "*4)
print(space_content)

위 코드는 src에 해당되는 입력 파일을 읽어서 그 내용을 tab_content라는 변수에 저장한 후 문자열의 replace 함수를 사용하여 탭(\t)을 4개의 공백으로 변경하는 코드이다.

 

5. tabto4.py를 위와 같이 변경한 후 다음과 같은 명령을 수행해보자.

C:\doit>python tabto4.py a.txt b.txt

Life    is    to    short

You    need    python

 

6. 이제 변경된 내용을 b.txt 파일에 저장할 수 있도록 다음과 같이 프로그램을 변경해보자.

#C:/doit/tabto4.py
import sys

src=sys.argv[1]
dst=sys.argv[2]

f=open(src)
tab_content=f.read()
f.close()
space_content=tab_content.replace("\t", " "*4)

f=open(dst, 'w')
f.write(space_content)
f.close()

탭이 공백으로 변경된 space_content를 출력 파일인 dst에 쓰도록 코드를 수정하였다.

 

7. 프로그램을 실행하기 위해 다음 명령을 수행한다.

C:\doit>python tabto4.py a.txt b.txt

위 명령을 수행하면 b.txt 파일이 C:\doit 디렉터리에 생성된다. 에디터로 b.txt 파일을 열어서 탭이 4개의 공백 문자로 변경되었는지 확인할 수 있다.

 

 

 

 

 

 

06-6 하위 디렉터리 검색하기

 

특정 디렉터리부터 시작해서 그 하위 모든 파일 중 파이썬 파일(*.py)만 출력해주는 프로그램 만들기

 

1. 다음과 같이 sub_dir_search.py 파일을 작성한다. search 함수를 만들고 시작 디렉터리를 입력받도록 코드를 작성한다.

#C:/doit/sub_dir_search.py

def search(dirname):
    print(dirname)
    
search("C:/")

 

2. 이 디렉터리에 있는 파일을 검색할 수 있도록 소스를 변경한다.

#C:/doit/sub_dir_search.py
import os

def search(dirname):
    filenames=os.listdir(dirname)
    for filename in filenames:
        full_filename=os.path.join(dirname, filename)
        print(full_filename)
        
search("C:/")

os.listdir를 사용하면 해당 디렉터리에 있는 파일들의 리스트를 구할 수 있다. 여기에서 구하는 파일 리스트는 파일 이름만 포함되어 있으므로 경로를 포함한 파일 이름을 구하기 위해서는 입력으로 받은 dirname을 앞에 덧붙여 주어야한다. os 모듈에는 디렉터리와 파일 이름을 이어주는 os.path.join 함수가 있으므로 이 함수를 사용하면 디렉터리를 포함한 전체 경로를 구할 수 있다.

 

3. 이제 C:/ 디렉터리에 있는 파일들 중 확장자가 .py인 파일만을 출력하도록 코드를 변경한다.

#C:/doit/sub_dir_search.py
import os

def search(dirname):
    filenames=os.listdir(dirname)
    for filename in filenames:
        full_filename=os.path.join(dirname, filename)
        ext=os.path.splitext(full_filename)[-1]
        if ext==' .py':
            print(full_filename)
            
search("C:/")

파일 이름에서 확장자만 추출하기 위해 os 모듈의 os.path.splitext 함수를 사용하였다. os.path.splitext는 파일 이름을 확장자를 기준으로 두 부분으로 나누어준다. 따라서 os.path.splitext(full_filename)[-1]은 해당 파일의 확장자 이름이 된다. 위 코드는 확장자 이름이 .py인 경우만을 출력하도록 작성했다. C:/디렉터리에 파이썬 파일이 없다면 아무것도 출력되지 않을 것이다.

 

4. C:/디렉터리 바로 밑에 있는 파일뿐만 아니라 그 하위 디렉터리(sub_directory)를 포함한 모든 파이썬 파일을 검색하기 위해서 다음과 같이 코드를 변경해야 한다.

#C:/doit/sub_dir_search.py
import os

def search(dirname):
    try:
        filenames=os.listdir(dirname)
        for filename in filenames:
            full_filename=os.path.join(dirname, filename)
            if os.path.isdir(full_filename):
                search(full_filename)
            else:
                ext=os.path.splitext(full_filename)[-1]
                if ext==' .py':
                    print(full_filename)
    except PermissionError:
        pass
        
search("C:/")

try...except PermissionError 로 함수 전체를 감싼 이유는 os.listdir를 수행할 때 권한이 없는 디렉터리에 접근하더라도 프로그램이 오류로 종료되지 않고 그냥 수행되도록 하기 위해서이다.

full_filename이 디렉터리인지 파일인지 구별하기 위하여 os.path.isdir 함수를 사용하였고 디렉터리일 경우 해당 경로를 입력받아 다시 search 함수를 호출하였다. 이렇게 해당 디렉터리의 파일이 디렉터리일 경우 다시 search 함수를 호출해나가면(재귀 호출) 해당 디렉터리의 하위 파일을 다시 검색하기 시작하므로 결국 모든 파일들을 검색할 수 있따.

위 코드를 수행하면 C:/디렉터리에 있는 모든 파이썬 파일이 출력될 것이다.

 

 

 

 

하위 디렉터리 검색을 쉽게 해주는 os.walk

os.walk는 시작 디렉터리부터 시작하여 그 하위 모든 디렉터리를 차례대로 방문하게 해주는 함수이다.

import os

for (path, dir, files) in os.walk("C:/"):
    for filename is files:
        ext = os.path.splitext(filename)[-1]
        if ext==' .py':
            print("%s/%s" %(path, filename))