반응형
어휘력 향상을 위해 챗GPT에게 토익 필수 어휘 50개를 추천받았습니다.
단어와 한글이 짝을 이룬 텍스트 파일을 만들고,
이 텍스트 파일의 단어를 무작위 순서로 불러와 문제를 내고 답을 입력받아 채점하는 프로그램을 만들었습니다.
입력한 답이 맞으면 다음 단어로 넘어가고
틀렸을 때는 정답을 알려주고 다음 단어로 진행합니다.
모든 단어를 다 풀고 나면 틀렸던 문제만 모아서 다시 순서를 무작위로 섞고 문제를 냅니다.
모든 단어를 다 맞추고 나면 점수를 계산해서 알려줍니다.
만들 코드를 단계별로 정리해 봅니다.
1. 필요한 라이브러리 가져오기:
코드는 세 개의 라이브러리를 가져오는 것으로 시작합니다.
- pandas(pd로 가져옴): 테이블 형식의 데이터를 처리하는 데 사용되는 강력한 데이터 조작 라이브러리입니다.
- random: 퀴즈의 질문을 섞는 데 사용되는 난수를 생성하는 라이브러리입니다.
- tkinter(tk로 가져옴): GUI(그래픽 사용자 인터페이스) 응용 프로그램을 만들기 위한 표준 Python 라이브러리입니다.
2. Tkinter 창 만들기:
창 이름이 ">> Word Power <<"인 Tkinter 창 객체(창)를 만들고 화면에서 (500, 300)인 위치에 500x350 픽셀로 설정합니다.
3. 단어 데이터 로드:
- pandas를 사용하여 텍스트 파일(ToeicWords_1.txt)에서 단어 데이터를 읽고 DataFrame(df)에 저장합니다.
- 텍스트 파일에는 답변에 대한 'ans'와 질문에 대한 'question'의 두 열이 있다고 가정합니다.
- 세 번째 열 'check'는 사용자의 답변을 추적하기 위해 처음에 모든 값이 0으로 설정되어 DataFrame에 추가됩니다.
4. GUI 구성 요소 만들기:
- Tkinter를 사용하여 텍스트를 표시하는 레이블(lab1, lab2 등)
- 퀴즈 질문을 표시하는 레이블(question_label)
- 사용자가 입력할 항목 위젯(answer_entry)
- 답변을 확인할 수 있는 버튼(check_button)
5. GUI 구성 요소 배치:
- place() 메서드를 사용하여 창에서 GUI 구성 요소의 위치를 지정합니다.
6. 함수 정의:
퀴즈의 다양한 기능을 처리하는 여러 함수를 정의합니다.
- ask_question(): 이 함수는 question_label의 텍스트를 업데이트하고 answer_entry의 사용자 입력을 지워 다음 퀴즈 질문을 표시합니다. 또한 현재 문제 번호를 추적하고 lab3의 텍스트를 업데이트합니다.
- check_answer(): 이 함수는 정답과 사용자의 답변을 확인하고 그에 따라 DataFrame의 확인 열을 업데이트합니다. 또한 정답인지 오답인지를 나타내는 메시지를 message_label에 표시합니다. 모든 질문에 답하거나 퀴즈가 끝나면 finish_quiz() 함수를 호출합니다.
- finish_quiz(): 이 함수는 오답 문제를 필터링하고, 오답을 입력한 문제가 있는 경우 순서를 섞고 ask_question()을 호출하여 퀴즈를 다시 시작합니다. 모든 질문에 올바르게 답하면 question_label 및 message_label에 완료 메시지를 표시하고 configure() 메서드를 사용하여 check_button 및 answer_entry를 비활성화합니다.
- 바인딩 이벤트: <Return> 키 이벤트를 check_answer() 함수에 바인딩하여 버튼을 클릭하는 대신 Enter 키를 눌러 답변을 확인할 수도 있게 합니다.
7. 퀴즈 시작:
전역 변수(current_question, question_order, num_current 및 wrong_df)의 초기 값을 설정하고 ask_question()을 호출하여 첫 번째 질문을 표시하여 퀴즈를 시작합니다.
8. Tkinter 이벤트 루프 실행:
mainloop() 메서드를 호출하여 Tkinter 창의 이벤트 루프를 시작합니다. 이를 통해 사용자는 GUI 구성 요소와 상호 작용하고 창이 닫힐 때까지 이벤트에 응답할 수 있습니다.
import pandas as pd import random import tkinter as tk window = tk.Tk() window.title(">> Word Power <<") window.geometry("500x350+500+300") # 암기할 단어 불러오기 df = pd.read_csv('ToeicWords_1.txt', header=None, names=['ans', 'question']) df['check'] = 0 src = list(df.index) lab1=tk.Label(window, text="Increase your vocabulary power!", font=("나눔고딕", 20), width=50, anchor='w' ) lab2=tk.Label(window, text="단어 수 : ", font=("나눔고딕", 14), width=50, anchor='w' ) lab3=tk.Label(window, text="문제 번호 : ", font=("나눔고딕", 14), width=50, anchor='w' ) bar1=tk.Label(window, text="----------------------------------------------------------------------------", width=250, anchor='w' ) question_label=tk.Label(window, text="문제 : ", font=("나눔고딕", 22), width=50, anchor='w' ) lab_ans=tk.Label(window, text="Your Answer : ", font=("나눔고딕", 18), width=100, anchor='w' ) bar2=tk.Label(window, text="----------------------------------------------------------------------------", width=250, anchor='w' ) message_label=tk.Label(window, text="Message : ", font=("나눔고딕", 18), wraplength=400, justify='left') answer_entry=tk.Entry(window, width=18, font=("Arial", 18)) # 배치 ------------------------------------- lab1.place(x=20, y=10) lab2.place(x=20, y=50) lab3.place(x=20, y=80) bar1.place(x=20, y=100) question_label.place(x=20, y=150) lab_ans.place(x=20, y=200) bar2.place(x=20, y=230) message_label.place(x=20, y=250) answer_entry.place(x=140, y=200) # start quiz global current_question current_question = 0 question_order = random.sample(src, len(src)) num_question=len(src) lab2.config(text="단어 수 : " + str(num_question)) num_current = 0 lab3.config(text="문제 번호 : " + str(num_current)) global incorrect_df def ask_question(): # ask next question global current_question, num_current, incorrect_df if current_question < len(question_order): choice = question_order[current_question] num_current += 1 lab3.config(text="문제 번호 : " + str(num_current)) question_label.config(text="What is the word for ' {} '?".format(df.question[choice])) answer_entry.delete(0, tk.END) answer_entry.focus() else: finish_quiz() ask_question() def check_answer(): global current_question, incorrect_df choice = question_order[current_question] your_ans = answer_entry.get() if your_ans.lower() == df.ans[choice].lower(): df.loc[df.index[choice], 'check'] = 1 message_label.config(text="정답입니다!") else: message_label.config(text="' "+str(your_ans)+" ' 를 입력하셨는데, \n 정답은 " +str(df.ans[choice].lower()) + " 입니다." ) # move on to next question or finish quiz current_question += 1 if current_question == len(df): finish_quiz() else: ask_question() check_button = tk.Button(window, text="Check", font=('Arial', 18), command=check_answer) check_button.place(x=400, y=200) answer_entry.bind("<Return>", lambda event: check_answer()) #함수에 인자를 사용하지 않게 def finish_quiz(): # filter the questions that were answered incorrectly incorrect_df = df[df['check'] != 1] # ask the incorrect answers again if len(incorrect_df) > 0: global current_question, question_order question_order = random.sample(list(incorrect_df.index), len(incorrect_df)) src = list(incorrect_df.index) current_question = 0 ask_question() else: answer_entry.delete(0, tk.END) question_label.config(text="Quiz Complete!") message_label.config(text="축하합니다!!! 모든 문제를 다 맞추셨습니다! \n 점수는 " + str(num_question/num_current*100)+"점!!!") check_button.configure(state = 'disabled') answer_entry.config(state= "disabled") window.mainloop() |
728x90
'Manuals > 파이썬' 카테고리의 다른 글
파이썬] 피보나치 나선 그리기 (64) | 2023.11.12 |
---|---|
파이썬 Tkinter 사용법 (1) | 2023.09.03 |
파이썬 pandas, 액셀 파일 사용 (0) | 2023.04.03 |
파이썬, 체질량지수(BMI)와 정상체중 범위 (0) | 2023.04.03 |
파이썬 GUI, tkinter를 이용한 시간 관리 프로그램 (1) | 2023.03.24 |