'전체 글'에 해당되는 글 584건

  1. 2025.11.17 English Vocabulary 영어 단어 학습기
반응형

파이썬으로 간단한 영어 단어 학습기를 만들어 보자.

 

import glob
import random
import os
import time

# 컬러 코드 및 커서 이동 코드
code = {
    'RED': '\033[31m',
    'GREEN': '\033[32m',
    'YELLOW': '\033[33m',
    'BLUE': '\033[34m',
    'MAGENTA': '\033[35m',
    'CYAN': '\033[36m',
    'WHITE': '\033[37m',
    'RESET': '\033[0m',
    'UP': '\033[A',    
    'DOWN': '\033[B',
    'UP_FRONT': '\033[F',
    'DOWN_FRONT': '\033[E'
}

Continue = True
os.system('cls')
print(f"\n\t[ 영어 단어 퀴즈 프로그램 ]")

while Continue:
	# 데이터 파일 목록 출력
	files = glob.glob('data/Eng*.txt')
	files.sort(key=len)  # 파일 이름 길이 기준 정렬
	print("\n 사용 가능한 Unit 목록:")	
	print(f" {code['GREEN']}[", end='')
	for file in files:
		print(f" {file[8:-4]}", end='')
	print(f" ]{code['RESET']}")

	unit = input("\n 몇 번째 Unit을 테스트 할까요? : ")
	unit = unit.upper().strip()
	reverse = input(" [한-영]으로 테스트 하시겠습니까? (y/n) : ")

	# 테스트 모드 설정
	test_mode = False
	if unit is not '' and unit == '1004':
		test_mode = True
		if reverse.lower() == 'y':
			kor = ['boy', 'girl', 'house', 'car', 'tree', 'pen', 'paper']
			eng = ['소년', '소녀', '집', '자동차', '나무', '펜', '종이']
		else:
			eng = ['boy', 'girl', 'house', 'car', 'tree', 'pen', 'paper']
			kor = ['소년', '소녀', '집', '자동차', '나무', '펜', '종이']
	else:
		# 데이터 파일 불러오기
		try:			
			with open('data/Eng' + unit + '.txt', 'r', encoding='utf-8') as file:
				if reverse.lower() == 'y':
					kor = [line.strip() for line in file.readlines()]
				else:
					eng = [line.strip() for line in file.readlines()]
			with open('data/Kor' + unit + '.txt', 'r', encoding='utf-8') as file:
				if reverse.lower() == 'y':
					eng = [line.strip() for line in file.readlines()]
				else:
					kor = [line.strip() for line in file.readlines()]
		except FileNotFoundError:
			print(f"\n [Eng{unit}.txt] 또는 [Kor{unit}.txt] 파일이 존재하지 않습니다.\n 다시 선택해 주세요.")
			continue

	# 데이터 유효성 검사
	total = len(eng) if len(eng) == len(kor) else 0
	if total == 0:
		print(" 데이터 파일에 오류가 있습니다. 다시 확인해 주세요.")
		input("\n 끝내려면 Enter 키를 누르세요...")
		exit()
	
	if test_mode:
		name = "TEST MODE"
	else:
		name = input(" 당신의 이름은 무엇인가요? : ")

	total_list = list(range(total))
	random.shuffle(total_list)
	correct_answers = 0
	wrong_answers = []

	# 퀴즈 시작
	for num, i in enumerate(total_list, 1):
		os.system('cls')
		print(f"\n\t[ {unit}강 {'한영' if reverse.lower() == 'y' else '영한'} 단어 퀴즈 ]\n")
		print(f" 총 {total}문제입니다. 각 문제마다 알맞은 뜻을 고르세요.\n")
		print("-" * 50, "\n")
		
		# 보기 생성
		choices = []
		while len(choices) < 4:
			rand_index = random.randint(0, len(eng) - 1)
			if rand_index != i and kor[rand_index] not in choices:
				choices.append(kor[rand_index])
		# 정답 추가 및 섞기
		choices.append(kor[i])
		random.shuffle(choices)
		# 문제 출력
		print(f" {num}. 다음 단어의 뜻은?\n")
		print(f"\t{code['GREEN']}[ {eng[i]} ]\n{code['RESET']}")
		# 보기 출력
		for j in range(5):
			print(f" {j + 1}) {choices[j]}")

		# 답 입력 및 정답 확인
		correct_index = choices.index(kor[i]) + 1
		answer = input("\n 답: ")
		print("\n" + "-" * 50)
		# 정답 처리
		if answer == str(correct_index):
			print(f"{code['UP'] * (4 + 6 - correct_index)}", end='')
			print(f" {code['GREEN']}{correct_index}) {choices[correct_index-1]}{code['RESET']}", end='')
			print(f"{code['DOWN_FRONT'] * (4 + 6 - correct_index)}", end='')

			print(f" {code['BLUE']}정답입니다!{code['RESET']}\n")
			print(f" {code['GREEN']}해설: '{eng[i]}'는(은) '{kor[i]}'라는 뜻입니다.{code['RESET']}")
			correct_answers += 1
		# 오답 처리
		else:
			print(f"{code['UP'] * (4 + 6 - correct_index)}", end='')
			print(f" {code['GREEN']}{correct_index}) {choices[correct_index-1]}{code['RESET']}", end='')
			print(f"{code['DOWN_FRONT'] * (4 + 6 - correct_index)}", end='')

			print(f" {code['RED']}틀렸습니다.{code['RESET']}\n")
			print(f" 정답은 {code['BLUE']}{correct_index}번 [{choices[correct_index-1]}]{code['RESET']} 입니다\n")
			print(f" {code['GREEN']}해설: '{eng[i]}'는(은) '{kor[i]}'라는 뜻입니다.{code['RESET']}")
			
			wrong_answers.append((eng[i], kor[i]))
		# 현재 점수 출력 및 계속하기 대기
		print("-" * 50)
		print(f" [현재 점수: {correct_answers} / {total}]")
		input("\n 계속하려면 Enter 키를 누르세요...")

	# 퀴즈 종료 및 결과 출력
	os.system('cls')
	print(f"\n\t[ {unit}강 {'한영' if reverse.lower() == 'y' else '영한'} 단어 퀴즈가 모두 끝났습니다!! ]\n")
	print(f" {code['GREEN']}{name}님, 총 {total}문제 중 {code['RED']}{correct_answers}{code['GREEN']}문제 맞추셨습니다.{code['RESET']}\n")
	# 틀린 문제 목록 출력
	if wrong_answers:
		print(f" {code['YELLOW']}틀린 문제 목록:{code['RESET']}\n")
		for eng_word, kor_word in wrong_answers:
			print(f" - {code['CYAN']}{eng_word}{code['RESET']} : {kor_word}")
		# 결과 파일로 저장
		try:
			result_file = f"[{time.localtime().tm_year}년 {time.localtime().tm_mon:02d}월 {time.localtime().tm_mday:02d}일 {time.localtime().tm_hour:02d}시 {time.localtime().tm_min:02d}분] {name} Unit {unit} 오답 리스트.txt"
			with open(result_file, 'w', encoding='utf-8') as file:
				file.write(f"{name}님의 {'한영' if reverse.lower() == 'y' else '영한'} 단어 퀴즈 결과\n")
				file.write(f"총 {total}문제 중 {correct_answers}문제 맞춤\n\n")
				file.write("틀린 문제 목록:\n")
				for eng_word, kor_word in wrong_answers:
					file.write(f"- {eng_word} : {kor_word}\n")
				print(f"\n {code['GREEN']}틀린 문제 목록이 [ {result_file} ] 파일로 저장되었습니다.{code['RESET']}")

			# 통계용 파일 저장
			stats_file = f"stats/{time.localtime().tm_year}{time.localtime().tm_mon:02d}{time.localtime().tm_mday:02d}{time.localtime().tm_hour:02d}{time.localtime().tm_min:02d} {name} {unit}.csv"
			with open(stats_file, 'w', encoding='utf-8') as file:
				if reverse.lower() == 'y':
					for eng_word, kor_word in wrong_answers:
						file.write(f"{kor_word};{eng_word}\n")
				else:
					for eng_word, kor_word in wrong_answers:
						file.write(f"{eng_word};{kor_word}\n")

		except Exception as e:
					print(f"\n {code['RED']}결과 파일 저장 중 오류가 발생했습니다: {e}{code['RESET']}")
	else:
		print(f" {code['GREEN']}모든 문제를 맞추셨습니다! 정말 대단해요!{code['RESET']}")

	# 다시 할지 여부 묻기
	while True:
		ans = input("\n 다시 하려면 y, 종료 하려면 n을 입력하세요(y/n) : ")
		if ans.lower() == 'y':
			break
		elif ans.lower() == 'n':
			Continue = False
			input("\n 끝내려면 Enter 키를 누르세요...")
			break
		else:
			print(" 올바른 입력이 아닙니다. 다시 입력해 주세요.")

 

단어 목록은 아래 데이터 파일과 같은 형태로 만들면 된다.

data.zip
0.02MB

데이터 파일

 

 

 

 

 

 

 

영어 퀴즈를 풀며 생성된 데이터를 분석하는 통계 프로그램을 만들어 보자.

 

import glob
import pandas as pd
import os
import matplotlib.pyplot as plt

# 컬러 코드 및 커서 이동 코드
code = {
    'RED': '\033[31m',
    'GREEN': '\033[32m',
    'YELLOW': '\033[33m',
    'BLUE': '\033[34m',
    'MAGENTA': '\033[35m',
    'CYAN': '\033[36m',
    'WHITE': '\033[37m',
    'RESET': '\033[0m',
    'UP': '\033[A',
    'DOWN': '\033[B',
    'UP_FRONT': '\033[F',
    'DOWN_FRONT': '\033[E'
}

os.system('cls')
# 컬러 코드 사용시 윈도우 터미널에서 작동하지 않는 경우가 있어 cls 명령어로 초기화

# 전체 통계 데이터프레임 생성
df = pd.DataFrame()
files = glob.glob('stats/*.csv')

# 데이터 불러오기 및 전처리
try:
	for file in files:	
		temp_df = pd.read_csv(file, names=['Eng', 'Kor'], sep=';')
		f = os.path.basename(file).split()	
		temp_df['Name'] = ''.join(f[1:-1])  # 파일 이름에서 사용자 이름 추출
		temp_df['Date'] = f[0]  # 파일 이름에서 날짜 추출
		temp_df['Date'] = pd.to_datetime(temp_df['Date'], format='%Y%m%d%H%M')  # Pandas 날짜형식으로 변환
		temp_df['SimpleDate'] = pd.to_datetime({'year': temp_df['Date'].dt.year, 'month': temp_df['Date'].dt.month, 'day': temp_df['Date'].dt.day})  # 시분초 제거
		df = pd.concat([df, temp_df], ignore_index=True)
except Exception as e:
	print("통계 파일을 불러오는 중 오류가 발생했습니다:", e)
	exit()

df = df.reindex(columns=['SimpleDate', 'Eng', 'Kor', 'Name', 'Date'])
#print(df)

print(f"\t{code['GREEN']}[ 가장 많이 틀린 영단어 Top 5 ]{code['RESET']}")
top = df['Eng'].value_counts().nlargest(5)  # value_counts(), nlargest()는 series 반환
for word, count in top.items():
	print(f" {code['YELLOW']}{word}{code['RESET']}: {count}회")
# for index in top.index:
# 	print(f"{index}: {top[index]}회")

# 날짜별 영어 단어 수 시각화
answer = input("\n 틀린 영단어 날짜별 통계를 시각화 하시겠습니까? (y/n): ")
if answer.lower() != 'y':
	exit()
else:
	count = df.groupby('SimpleDate')['Eng'].count()  # 날짜별로 영어 단어 수 집계

	plt.rc('font', family='gulim')
	fig, ax = plt.subplots(1, 1, figsize=(10, 10))
	
	# 날짜 데이터 타입을 그대로 사용하면 중간에 날짜(시간)들이 추가된다. 문자열로 변환하여 x축에 표시
	ax.bar(count.index.astype(str), count.values)
	plt.xticks(rotation=45)
	plt.bar_label(ax.containers[0])  # 막대 위에 값 표시, bar 그래프를 생성한 후에 사용해야 함
	ax.yaxis.set_major_locator(plt.MaxNLocator(integer=True))  # y축을 정수로 설정
	ax.set_title('틀린 영단어 날짜별 통계', fontsize=20)
	ax.set_xlabel('날짜', fontsize=20)
	ax.set_ylabel('틀린 영단어 수', fontsize=20)

	plt.show()

 

 

 

영어퀴즈.zip
0.03MB

전체 프로그램

 

※ 참고

여러가지 데이터가 섞인 CSV 파일을 DataFrame에 로드하기

 

import csv
import pandas as pd

# 파일 내용 (file.csv)
#
# ---점수---
# 92,89,75
# ---등급---
# A,B,C
# ---석차---
# 2,4,7

data = []

with open('file.csv', mode='r', encoding='utf-8') as f:
	reader = csv.reader(f)
	for row in reader:
		if not row[0].startswith('-'):
			data.append(row)

print(data)

df = pd.DataFrame(data, columns=('영어', '수학', '과학'))
print(df)

 

 

아래 코드는 데이터가 comma(,)가 아닌 semicolon(;)으로 구분된 경우이다.

import csv
import pandas as pd

# 파일 내용 (file.csv)
#
# ---점수---
# 92;89;75
# ---등급---
# A;B;C
# ---석차---
# 2;4;7

data = []

with open('file.csv', mode='r', encoding='utf-8') as f:
	reader = csv.reader(f)
	for row in reader:
		if not row[0].startswith('-'):
			data.append(row)

print(data)

split_data = [row[0].split(';') for row in data]
df = pd.DataFrame(split_data, columns=('영어', '수학', '과학'))
print(df)

 

 

반응형
Posted by J-sean
: