[PYTHON] 파일 읽고 쓰기(과제 : 코딩에 빠진 닭, 단어장만들기, 단어퀴즈, 고급단어장)

2020. 12. 26. 19:37IT/PYTHON

korean_word = vocab[english_word]

파일 읽기

파일을 읽기 위해서는 with open 이라는 예약어를 사용합니다. 'r'은 read의 약자입니다. 즉 읽기만 하겠다는거죠.

with open('data/chicken.txt', 'r') as f:
	for line in f:
    	print(line)

strip

strip은 화이트 스페이스를 없애주는 역할을 해줍니다. 아래와 같이 " ", "\t", "\n" 같은 쓰래기 데이터를 자동으로 삭제해주는거죠.

with open('data/chicken.txt', 'r') as f:
	for line in f:
    	print(line.strip())

 

split

어떤 기호를 기준으로 나눠서 리스트에 저장시켜준다.

my_string = "1. 2. 3. 4. 5. 6"
print(my_string.split("."))

 

Q1. 밑에 나와 있는 chicken.txt 파일을 보세요. 제가 운영하는 치킨집 '코딩에빠진닭(이하 코빠닭)'의 12월 매출이 정리되어 있습니다.

1일: 453400
2일: 388600
3일: 485300
4일: 477900
5일: 432100
6일: 665300
7일: 592500
8일: 465200
9일: 413200
10일: 523000
11일: 488600
12일: 431500
13일: 682300
14일: 633700
15일: 482300
16일: 391400
17일: 512500
18일: 488900
19일: 434500
20일: 645200
21일: 599200
22일: 472400
23일: 469100
24일: 381400
25일: 425800
26일: 512900
27일: 723000
28일: 613600
29일: 416700
30일: 385600
31일: 472300

:의 왼쪽에는 해달 월의 며칠인지, 그리고 오른쪽에는 그 날의 매출이 적혀 있습니다. 

data 폴더의 chicken.txt 파일을 읽어 들이고, strip과 split을 써서 12월 코빠닭의 하루 평균 매출을 출력하세요. 평균을 구하기 위해서는 총 매출을 총 일수로 나누면 됩니다. 

참고로 현재 제공된 파일에는 31일이 있지만, 어떤 달은 31일이 아닐 수도 있습니다. 이 점을 고려해서 확장성 있는 코드를 작성해 주시길 바랍니다. 

출력 결과는 아래와 같습니다.

# 내 답안
days = 0
my_income = 0

with open('data/chicken.txt', 'r') as f:
    for line in f:
        line = line.strip()
        line = line.split(' ')
        my_income = my_income + int(line[1])
        days = days + 1

print(f"{my_income / days}")



# 모범 답안
with open('data/chicken.txt', 'r') as f:
    total_revenue = 0
    total_days = 0
    
    for line in f:
        data = line.strip().split(": ")
        revenue = int(data[1])  # 그날의 매출

        total_revenue += revenue
        total_days += 1

    print(total_revenue / total_days)

 

파일 쓰기

위에서 파일 읽기를 할때 with open으로 파라미터로 'r'을 써주었는데 파일 쓰기에서는 'w' 또는 'a'를 써줍니다. 'w'은 write 의 약자입니다. 즉 파일을 쓴다는 말입니다. 파일을 쓸때는 항상 기존 파일을 삭제하고 새로 작성을 합니다. 만약 로그파일을 만든다고 하면 이전 기록을 볼 수 없어서 좀 거시기 합니다. 로그 파일을 만들때는 'w'를 쓰는것이 아니라 'a'를 써줍니다. append라는 뜻으로 'w'와 달리 기존 파일은 삭제하지 않고 추가를 시켜줍니다. 리눅스에서 보면 '>'요게 있고 '>>' 요게 있죠? 같은 의미입니다.

#Write
with open('new_file.txt', 'w') as f:
	f.write(Hello world!\n")
    f.write("My name is KURUGAI.\n")

#Append
with open('new_file.txt', 'a') as f:
	f.write(Hello world!\n")
    f.write("My name is KURUGAI.\n")

Q2. 영어 강사 Coy는 학생들의 단어 암기를 위해 단어장 프로그램을 만들려고 합니다. 이 프로그램은 콘솔로 영어 단어와 한국어 뜻을 받고, vocabulary.txt 라는 새로운 텍스트 파일에 단어와 뜻을 정리하는데요. 사용자가 새로운 단어와 뜻을 입력할 때마다 vocabulary.txt 에 작성되는 것입니다. 사용자는 반복적으로 단어와 뜻을 입력하는데, 단어나 뜻으로 q를 입력하는 순간 프로그램은 즉시 종료됩니다. 사용자가 q를 입력하고 나면 파일은 더 이상 바뀌지 않아야 합니다.

프로그램 예시 

동작 프로그램의 예시 동작은 아래와 같습니다.

영어 단어를 입력하세요:

영어 단어를 입력하세요: cat
한국어 뜻을 입력하세요:

영어 단어를 입력하세요: cat
한국어 뜻을 입력하세요: 고양이
영어 단어를 입력하세요:

영어 단어를 입력하세요: cat
한국어 뜻을 입력하세요: 고양이
영어 단어를 입력하세요: apple
한국어 뜻을 입력하세요:

영어 단어를 입력하세요: cat
한국어 뜻을 입력하세요: 고양이
영어 단어를 입력하세요: apple
한국어 뜻을 입력하세요: 사과
영어 단어를 입력하세요:

이런 식으로 단어를 여덟 개 입력했다고 가정합시다.

영어 단어를 입력하세요: cat
한국어 뜻을 입력하세요: 고양이
영어 단어를 입력하세요: apple
한국어 뜻을 입력하세요: 사과
영어 단어를 입력하세요: church
한국어 뜻을 입력하세요: 교회
영어 단어를 입력하세요: temple
한국어 뜻을 입력하세요: 절
영어 단어를 입력하세요: wallet
한국어 뜻을 입력하세요: 지갑
영어 단어를 입력하세요: backpack
한국어 뜻을 입력하세요: 책가방
영어 단어를 입력하세요: soap
한국어 뜻을 입력하세요: 비누
영어 단어를 입력하세요: bicycle
한국어 뜻을 입력하세요: 자전거
영어 단어를 입력하세요: q

사용자가 q를 입력하면 프로그램이 종료되고, vocabulary.txt에 다음과 같이 단어들이 정리되어 있어야 합니다.

cat: 고양이
apple: 사과
church: 교회
temple: 절
wallet: 지갑
backpack: 책가방
soap: 비누
bicycle: 자전거
# 내 답안
def input_word(eword, kword):
    with open("vocabulary.txt", "a") as f:
        f.write(f"{eword}: {kword}\n")


while (True):
    eword =input("영어 단어를 입력하세요 : ")
    if eword == 'q':
        break

    kword = input("한국어 뜻을 입력하세요 : ")
    if kword == 'q':
        break

    input_word(eword, kword)

with open("vocabulary.txt", 'r') as f:
    for line in f:
        line = line.strip()
        print(f"{line}", end='\n')
        
# 모범 답안
with open('vocabulary.txt', 'w') as f:
    while True:
        english_word = input('영어 단어를 입력하세요: ')    
        if english_word == 'q':
            break
        
        korean_word = input('한국어 뜻을 입력하세요: ')
        if korean_word == 'q':
            break
        
        f.write('{}: {}\n'.format(english_word, korean_word))

 

Q3. 앞선 Q2에서 vocabulary.txt 라는 파일을 만들었죠? 이 파일에는 우리가 암기하고 싶은 단어들이 정리되어 있는데요. 이번에는 이 파일의 단어들을 가지고 학생들에게 문제를 내 주는 프로그램을 만들려고 합니다. 프로그램은 콘솔에 한국어 뜻을 알려 줄 것이고, 사용자는 그에 맞는 영어 단어를 입력해야 합니다. 사용자가 입력한 영어 단어가 정답이면 "맞았습니다!"라고 출력하고, 틀리면 "아쉽습니다. 정답은 OOO입니다."가 출력되어야 합니다. 문제를 내는 순서는 vocabulary.txt에 정리된 순서입니다.

# 내 답안
with open("vocabulary.txt", 'r') as f:
    for line in f:
        line = line.strip()
        line = line.split(':')
        answer = input(f"{line[1]} : ")
        if answer == line[0]:
            print(f"맞았습니다.", end='\n')
        else:
            print(f"아쉽습니다. 정답은 {line[0]}입니다.")

# 모범답안
ith open('vocabulary.txt', 'r') as f:
    for line in f:
        data = line.strip().split(": ")
        english_word, korean_word = data[0], data[1]
        
        # 유저 입력값 받기
        guess = input("{}: ".format(korean_word))
        
        # 정답 확인하기
        if guess == english_word:
            print("정답입니다!\n")
        else:
            print("아쉽습니다. 정답은 {}입니다.\n".format(english_word))

 

Q4. 고급 단어장

지난 실습 과제에서 단어장 퀴즈 프로그램을 만들었는데요. 학생들이 문제의 순서가 매번 똑같아서 재미가 없다고 합니다. 이번에는 random 모듈과 사전(dictionary)을 이용해서 vocabulary.txt 의 단어들을 랜덤한 순서로 내도록 프로그램을 바꿔 보세요.

같은 단어를 여러번 물어봐도 괜찮고, 프로그램은 사용자가 알파벳 q를 입력할때까지 계속 실행됩니다.

 

답안해설

1. 사전 정리

우선 vocabulary.txt 파일을 읽고, 파이썬 사전을 채워 넣겠습니다.

vocab = {}
with open('vocabulary.txt', 'r') as f:
    for line in f:
        data = line.strip().split(": ")
        english_word, korean_word = data[0], data[1]
        vocab[english_word] = korean_word

이렇게 하면 파일에 있는 단어와 뜻이 모두 vocab 사전에 정리되겠죠?

2. 문제 내기 

문제를 내는 부분은 코드가 조금 더 복잡합니다. 이 중에서도 가장 헷갈릴 만한 부분은 랜덤한 문제를 받아오는 것입니다. 우선 한국어 단어는 배제하고 생각해 봅시다. 영어 단어 목록을 받아오려면 파이썬 사전의 keys를 사용하면 되는데요. 여기서 랜덤한 영어 단어를 뽑고 싶은 거죠. random 모듈의 randint 함수를 이용해서 랜덤한 인덱스를 받는다. 그 랜덤한 인덱스를 통해 vocab.keys()리스트에서 단어를 받는다. 코드로 표현하면 이렇습니다.

keys = list(vocab.keys())
index = random.randint(0, len(keys) - 1)
english_word = keys[index]

그리고 이제 이에 해당하는 한국어 뜻을 받아오는 것은 너무 쉽습니다.

korean_word = vocab[english_word]

나머지 부분은 앞선 실습 과제랑 거의 똑같습니다. 유저에게 단어를 입력 받는다. 만약 유저가 q를 입력했으면 프로그램을 종료한다. 유저가 입력한 영어 단어가 정답인지 확인한다.

# 모범답안
import random

# 사전 만들기
vocab = {}
with open('vocabulary.txt', 'r') as f:
    for line in f:
        data = line.strip().split(": ")
        english_word, korean_word = data[0], data[1]
        vocab[english_word] = korean_word

# 문제 내기
while True:
    # 랜덤한 문제 받아오기
    keys = list(vocab.keys())
    index = random.randint(0, len(keys) - 1)
    english_word = keys[index]
    korean_word = vocab[english_word]
    
    # 유저 입력값 받기
    guess = input("{}: ".format(korean_word))
    
    # 프로그램 끝내기
    if guess == 'q':
        break
    
    # 정답 확인하기
    if guess == english_word:
        print("정답입니다!\n")
    else:
        print("아쉽습니다. 정답은 {}입니다.\n".format(english_word))