[바로바로 파이썬 10] 메모장 프로그램 만들어보기
지금까지는 파일을 쓰는 방법, 파일을 읽는 방법, 파일을 한 줄씩 처리하는 방법을 각각 따로 배웠습니다. 하지만 실제 프로그램에서는 보통 하나의 기능만 사용하지 않습니다. 사용자에게 값을 입력받고, 그 값을 파일에 저장하고, 저장된 내용을 다시 읽어 화면에 보여주는 식으로 여러 기능이 함께 동작합니다. 이번에는 지금까지 배운 내용을 활용해 간단한 메모장 프로그램을 만들어보겠습니다.
메모장 프로그램의 흐름 생각하고 만들기
바로 코드를 작성하기 전에 먼저 메모장 프로그램이 어떤 흐름으로 동작하는지 생각해보겠습니다. 우리가 만들 메모장 프로그램에는 대략 다음과 같은 기능이 필요합니다.
1. 사용자에게 메모를 입력받습니다.
2. 입력받은 메모를 파일에 저장합니다.
3. 저장된 메모를 다시 읽어 화면에 출력합니다.
이 기능을 지금까지 배운 내용과 연결하면 다음과 같이 정리할 수 있습니다.
1. 사용자 입력 : input( ) 함수를 사용합니다.
2. 파일 저장 : open( ) 함수와 write( ) 메서드를 사용합니다.
3. 저장된 내용을 다시 읽기 : read( ) 또는 readline( )을 사용합니다.
그럼 이 구성에 맞게 기능을 하나씩 추가하면서 메모장 프로그램을 만들어봅시다.
먼저 가장 기본적인 기능부터 만들어보겠습니다. 사용자에게 메모 한 줄을 입력받아 파일에 저장하는 기능입니다.
➊ memo = input("메모를 입력하세요: ")는 사용자에게 메모를 입력받는 코드입니다. 사용자가 입력한 문자열은 memo 변수에 저장됩니다. 예를 들어 "장보기 목록 정리하기"를 입력하면 그 문장이 memo 변수에 저장됩니다.
➋ with open(...)은 memo.txt 파일을 쓰기 모드로 여는 코드입니다. 앞에서 살펴봤듯이 "w" 모드는 파일이 없으면 새로 만들고, 이미 있다면 기존 내용을 지운 뒤 새로 씁니다. 이어서 memo_file.write(memo)를 실행해 사용자가 입력한 메모를 파일에 저장합니다.
➌ 파일 저장이 끝났다는 안내 메시지를 출력합니다. 화면에 아무것도 나오지 않으면 사용자가 현재 상태를 알기 어렵기 때문에 이런 부분도 챙겨줘야 합니다.
정리하면 ➊ 사용자에게 메모를 입력받고, ➋ 입력받은 메모를 파일에 저장한 뒤, ➌ 저장이 완료되었다는 메시지를 출력했습니다. 이것이 메모장 프로그램의 가장 기본적인 저장 기능입니다.
메모를 파일에 저장했으니 이번에는 저장된 내용을 다시 읽어보겠습니다.
이번에는 저장한 메모를 읽어 오는 코드를 붙입니다. 파일을 읽을 때는 읽기 모드인 "r"을 사용하며, 저장된 파일 전체 내용을 한 번에 읽으려면 read( ) 메서드를 사용하면 됩니다.
➊ 앞에서 만든 메모 저장 기능입니다.
➋ with open(...)은 memo.txt 파일을 읽기 모드로 엽니다. 이어서 read( ) 메서드로 파일 전체 내용을 하나의 문자열로 읽어 온 다음, 그 결과를 saved_memo 변수에 저장합니다.
➌ print(f"저장된 메모: {saved_memo}")는 파일에서 읽어 온 내용을 화면에 출력합니다.
이제 메모장 프로그램은 사용자가 입력한 내용을 파일로 저장한 뒤, 저장된 내용을 다시 읽어 확인할 수 있게 되었습니다. 하지만 실제 메모장이라면 메모를 한 줄만 저장하는 것보다 여러 줄을 입력할 수 있는 편이 더 유용할 것입니다. 이번에는 반복문을 추가해보겠습니다.
이번에는 사용자가 메모를 계속 입력하고, "끝"이라고 입력하면 저장을 마치는 프로그램을 만들어보겠습니다. "끝"이라는 조건이 나왔을 때 입력을 마치려면 반복문과 조건문을 결합해야 합니다.
➊ memo.txt 파일을 쓰기 모드로 엽니다. 이번 예제에서는 새 메모장을 만든다고 생각하고 "w" 모드를 사용합니다. 따라서 기존에 같은 파일이 있다면 이전 내용은 지워지고 새로 입력한 메모가 저장됩니다.
➋ memo = input("메모 입력(끝 입력 시 종료): ")를 while 문 코드 블록 안쪽 맨 위에 작성했습니다. 이렇게 하면 반복문이 실행될 때마다 input( )이 다시 실행되므로 사용자에게 메모를 반복해서 입력받을 수 있습니다.
➌ 메모를 하나 입력받을 때마다 if memo == "끝":으로 사용자가 "끝"을 입력했는지 확인합니다. "끝"이 입력되었다면 break를 실행해 while 반복문을 종료합니다.
➍ 입력한 값이 "끝"이 아니라면 memo_file.write(memo + "\n")으로 입력받은 내용을 파일에 저장합니다. memo 뒤에 "\n"을 붙였으므로 메모 하나를 저장할 때마다 줄이 바뀝니다. 따라서 여러 번 입력한 메모가 파일에 한 줄씩 저장됩니다.
정리하면 ➊ 파일을 열고, ➋ 메모를 반복해서 입력받았습니다. ➌ "끝"이 입력되면 반복을 종료하고, ➍ 그전까지 입력한 메모는 파일에 한 줄씩 저장했습니다. 이제 제법 메모장다운 모습이 되었습니다. 여러 줄을 저장할 수 있게 되었으니 이어서 파일에서 필요한 한 줄만 읽는 방법도 활용해보겠습니다.
앞에서는 read( )를 사용해 파일 전체 내용을 읽었습니다. 이번에는 잠시 별도 예제로 readline( )을 사용해 첫 줄 읽기를 연습한 뒤, 앞의 메모장 프로그램 만들기로 돌아가겠습니다. readline( )은 현재 읽기 위치에서 한 줄을 읽어 오는 메서드이므로 메모 파일의 첫 번째 메모만 확인하는 데 사용할 수 있습니다.
➊ memo.txt 파일에 세 줄의 메모를 저장합니다.
➋ first_memo = memo_file.readline( ).strip( )으로 파일의 첫 번째 줄을 읽어 first_memo 변수에 저장합니다. 이때 readline( )의 결과에 바로 strip( )을 이어서 사용해 문자열 앞뒤의 공백 문자를 정리했습니다. 따라서 예제에서 줄 끝에 들어 있던 \n도 제거됩니다. 이처럼 어떤 메서드의 실행 결과에 이어서 또 다른 메서드를 사용하는 방식을 메서드 체이닝method chaining이라고 합니다. 여기서는 readline( )으로 얻은 문자열에 곧바로 strip( )을 적용한 것입니다.
➌ first_memo를 화면에 출력합니다. 파일에는 세 줄의 메모가 들어 있지만 readline( )을 한 번만 실행했으므로 첫 번째 줄만 읽어 출력합니다.
정리하면 ➊ 여러 줄의 메모를 파일에 저장하고, ➋ readline( )으로 첫 번째 줄만 읽은 뒤 ➌ 그 결과를 화면에 출력했습니다. 이처럼 파일 전체가 아니라 일부만 읽고 싶을 때 readline( )을 사용할 수 있습니다.
지금까지 저장, 읽기, 반복 입력 기능을 하나씩 만들어봤습니다. 이제 이 기능들을 연결해 메모장 프로그램을 완성해보겠습니다.
앞에서 만든 기능을 모두 합치면, 사용자가 여러 줄의 메모를 입력해 파일에 저장하고 저장이 끝난 뒤 파일 전체 내용을 다시 읽어 화면에 보여주는 프로그램이 됩니다. 이제 메모장 프로그램을 완성해봅시다.
➊ 첫 번째 with 블록에서는 사용자가 "끝"을 입력할 때까지 while 반복문을 실행합니다. 입력받은 값이 "끝"이 아니라면 메모 뒤에 \n을 붙여 memo.txt 파일에 한 줄씩 저장합니다.
➋ 두 번째 with 블록에서는 ➊에서 저장한 memo.txt 파일을 읽기 모드로 엽니다. 파일 전체 내용을 한꺼번에 읽기 위해 read( ) 메서드를 사용하고, 읽어 온 문자열을 all_memos 변수에 저장합니다.
➌ print(all_memos)는 저장된 메모 전체를 화면에 출력합니다. 파일에 메모를 저장할 때 각 메모 뒤에 \n을 붙였으므로, 출력할 때 메모가 줄 단위로 나뉘어 보입니다.
이제 우리가 배운 여러 문법이 하나의 프로그램 안에서 함께 동작합니다. input( )으로 값을 입력받고, while 문과 if 문으로 입력 과정을 제어하고, write( )로 파일에 저장한 뒤, read( )로 다시 읽어 print( )로 결과를 보여줍니다.
프로그램은 처음부터 거창할 필요가 없습니다. 사용자가 입력한 값을 저장하고, 저장한 값을 다시 보여주는 작은 코드도 하나의 목적을 수행하는 프로그램입니다. 중요한 것은 배운 문법을 각각 외우는 데서 끝내지 않고 하나의 목적을 이루도록 서로 연결해보는 것입니다.
