캡스톤 프로젝트(플래시 카드 앱)

JOOYEUN SEO·2024년 9월 13일

100 Days of Python

목록 보기
31/76
post-thumbnail

🗂️ Day31 프로젝트 : 플래시 카드 앱

어떤 언어에서든 가장 보편적으로 사용되는 단어를 플래시 카드로 배우는 프로그램

1. Tkinter로 UI 만들기

🔍 유의 사항

  • Wiktionary:Frequency lists 에서 단어 목록 가져오기
    • 사용된 빈도수 순서로 정렬된 목록에서 100개만 가져오기
    • 구글 시트에서 csv파일로 저장
      • 첫 번째 열은 단어, 두 번째 열은 뜻
      • =GOOGLETRANSLATE( text, "source_language", "target_language" )
        텍스트를 자동으로 번역하는 함수
        • text : 번역하려는 텍스트가 있는 셀
        • source_language : 번역할 언어의 코드
        • target_language : 번역될 목표 언어의 코드
          (언어 코드를 생략해도 구글 계정의 설정된 언어로 자동 번역됨)
  • 플래시 카드 UI (캔버스)
    • 앞면 이미지 1개(2열 차지)
    • 텍스트 2개(어떤 언어인지 표시, 단어)

🖼️ card_back.png

🖼️ card_front.png

🖼️ right.png

🖼️ wrong.png

📄 english_words.csv

English,Korean
come,오다
get,얻다
…
yes,예

⌨️ main.py

from tkinter import *

BG_COLOR = "#B1DDC6"

# UI SETUP -----------------------------------------------------------
window = Tk()
window.title("Flash Card Game")
window.config(padx=50, pady=50, bg=BG_COLOR)

canvas = Canvas(width=800, height=526, bg=BG_COLOR, highlightthickness=0)
card_front_img = PhotoImage(file="images/card_front.png")
canvas.create_image(400, 263, image=card_front_img)
canvas.create_text(400, 150, text='title', font=("Ariel", 40, "italic"))
canvas.create_text(400, 263, text='word', font=("Ariel", 60, "bold"))
canvas.grid(row=0, column=0, columnspan=2)

cross_img = PhotoImage(file="images/wrong.png")
unknown_button = Button(image=cross_img, highlightbackground=BG_COLOR)
unknown_button.grid(row=1, column=0)
check_img = PhotoImage(file="images/right.png")
known_button = Button(image=check_img, highlightbackground=BG_COLOR)
known_button.grid(row=1, column=1)


window.mainloop()

2. 새 플래시 카드 만들기

🔍 유의 사항

  • csv 파일의 단어를 무작위로 골라 플래시 카드에 넣기
  • X 또는 ✓버튼을 누를 때마다 새로운 단어가 무작위로 나와야 한다
  • DataFrame.to_dict(orient="records") 사용 (Day25 참고)
  • mainloop 전에 타이틀과 단어를 바꾸는 함수를 호출하여 시작부터 단어가 뜨게 만들기

⌨️ main.py

from tkinter import *
import pandas
import random

BG_COLOR = "#B1DDC6"

data = pandas.read_csv("data/english_words.csv")
to_learn = data.to_dict(orient="records")

def next_card():
    current_card = random.choice(to_learn)
    canvas.itemconfig(card_title, text='English')
    canvas.itemconfig(card_word, text=current_card['English'])

# UI SETUP -----------------------------------------------------------# 시작하자마자 랜덤한 단어가 뜨기 때문에 text 부분 필요 없음
card_title = canvas.create_text(400, 150, text='', font=("Ariel", 40, "italic"))
card_word = canvas.create_text(400, 263, text='', font=("Ariel", 60, "bold"))
canvas.grid(row=0, column=0, columnspan=2)

cross_img = PhotoImage(file="images/wrong.png")
unknown_button = Button(image=cross_img, highlightbackground=BG_COLOR, command=next_card)
unknown_button.grid(row=1, column=0)
check_img = PhotoImage(file="images/right.png")
known_button = Button(image=check_img, highlightbackground=BG_COLOR, command=next_card)
known_button.grid(row=1, column=1)

# 시작하자마자 단어가 보여지도록 함수 호출
next_card()

window.mainloop()

3. 카드 뒤집기

🔍 유의 사항

  • Day28 참조
  • 3초(3000밀리초)가 지나면 카드가 뒷면으로 뒤집히고 현재 영단어에 해당하는 뜻 보이기
  • 카드 이미지와 글자색 변경
    • 캔버스 이미지 변경은 텍스트 변경과 같은 방법
    • ❗️ PhotoImage 객체는 함수 내부에서 생성하면 제대로 동작하지 않음
  • 현재 카드(딕셔너리)를 전역변수로 저장하기
  • 버튼을 누르면 다시 앞면으로 뒤집혀야 한다
  • 버튼을 누를 때마다 3초 타이머가 초기화되어야 한다
    • after() 가 있는 코드를 전역 변수로 지정
    • 버튼을 누르면 after_cancel() 로 취소하기

⌨️ main.py

from tkinter import *
import pandas
import random

BG_COLOR = "#B1DDC6"

data = pandas.read_csv("data/english_words.csv")
to_learn = data.to_dict(orient="records")
current_card = {}

def next_card():
    global current_card, flip_timer
    # 타이머 캔슬
    window.after_cancel(flip_timer)
    current_card = random.choice(to_learn)
    canvas.itemconfig(card_title, text='English', fill='black')
    canvas.itemconfig(card_word, text=current_card['English'], fill='black')
    canvas.itemconfig(card_bg, image=card_front_img)
    # 카드를 뒤집은 뒤 타이머 다시 설정
    flip_timer = window.after(3000, func=flip_card)

def flip_card():
    canvas.itemconfig(card_title, text="Korean", fill='white')
    canvas.itemconfig(card_word, text=current_card['Korean'], fill='white')
    canvas.itemconfig(card_bg, image=card_back_img)

# UI SETUP -----------------------------------------------------------
window = Tk()
window.title("Flash Card Game")
window.config(padx=50, pady=50, bg=BG_COLOR)

# 카드 뒤집기 첫 실행(처음 켰을 때만)
flip_timer = window.after(3000, func=flip_card)

canvas = Canvas(width=800, height=526, bg=BG_COLOR, highlightthickness=0)
# 카드 이미지
card_front_img = PhotoImage(file="images/card_front.png")
card_back_img = PhotoImage(file="images/card_back.png")

card_bg = canvas.create_image(400, 263, image=card_front_img)# 시작하자마자 단어가 보여지도록 함수 호출
next_card()

window.mainloop()

4. 중간 저장하기

🔍 유의 사항

  • 사용자가 ✓버튼을 누르면 해당 카드가 더 이상 나오지 않도록 수정
  • 업데이트된 데이터를 새 파일(words_to_learn.csv)에 저장
  • 이후 프로그램 실행 시 words_to_learn.csv 파일이 있는지 확인
    • 파일이 있으면 해당 파일의 단어들을 사용
    • 파일이 없으면 기존 csv 파일의 단어들 사용
  • 판다스로 csv 파일을 읽을 때마다 자동으로 records 번호를 맨 앞에 붙임
    (이를 저장할 때마다 계속 열이 늘어나는 현상 발생)
    • data.to_csv( "file.csv", index=False )
      • index : 신규 csv 파일에 인덱스를 생략하려면 False로 설정

⌨️ main.py

from tkinter import *
import pandas
import random

BG_COLOR = "#B1DDC6"
current_card = {}
to_learn = {}

try:
    data = pandas.read_csv("data/words_to_learn.csv")
except FileNotFoundError:
    original_data = pandas.read_csv("data/english_words.csv")
    to_learn = original_data.to_dict(orient="records")
else:
    to_learn = data.to_dict(orient="records")

def next_card():
    global current_card, flip_timer
    window.after_cancel(flip_timer)
    current_card = random.choice(to_learn)
    canvas.itemconfig(card_title, text='English', fill='black')
    canvas.itemconfig(card_word, text=current_card['English'], fill='black')
    canvas.itemconfig(card_bg, image=card_front_img)
    flip_timer = window.after(3000, func=flip_card)

def flip_card():
    canvas.itemconfig(card_title, text="Korean", fill='white')
    canvas.itemconfig(card_word, text=current_card['Korean'], fill='white')
    canvas.itemconfig(card_bg, image=card_back_img)

def is_known():
    # 목록에서 아는 단어 제거하기
    to_learn.remove(current_card)
    new_data = pandas.DataFrame(to_learn)
    new_data.to_csv("data/words_to_learn.csv", index=False)

    next_card()

# UI SETUP -----------------------------------------------------------
window = Tk()
window.title("Flash Card Game")
window.config(padx=50, pady=50, bg=BG_COLOR)

flip_timer = window.after(3000, func=flip_card)

canvas = Canvas(width=800, height=526, bg=BG_COLOR, highlightthickness=0)

card_front_img = PhotoImage(file="images/card_front.png")
card_back_img = PhotoImage(file="images/card_back.png")

card_bg = canvas.create_image(400, 263, image=card_front_img)

card_title = canvas.create_text(400, 150, text='', font=("Ariel", 40, "italic"))
card_word = canvas.create_text(400, 263, text='', font=("Ariel", 60, "bold"))
canvas.grid(row=0, column=0, columnspan=2)

cross_img = PhotoImage(file="images/wrong.png")
unknown_button = Button(image=cross_img, highlightbackground=BG_COLOR, command=next_card)
unknown_button.grid(row=1, column=0)
check_img = PhotoImage(file="images/right.png")
known_button = Button(image=check_img, highlightbackground=BG_COLOR, command=is_known)
known_button.grid(row=1, column=1)

next_card()

window.mainloop()

📄 words_to_learn.csv

English,Korean
come,오다
make,만들다
about,~에 대한
before,~ 전에
for,~을 위한
of,~의
any,어느
though,그렇지만




▷ Angela Yu, [Python 부트캠프 : 100개의 프로젝트로 Python 개발 완전 정복], Udemy, https://www.udemy.com/course/best-100-days-python/?couponCode=ST3MT72524

0개의 댓글