본문 바로가기

[Python]/[Python 프로젝트]

[Python 프로젝트] 공부를 도와주는 디스코드 봇 프로젝트

728x90

프로젝트 설명

안녕하세요. 고등학생 개발자 주이어입니다. 오늘 소개할 프로젝트는 제가 고등학교 1학년 때 만든 공부를 도와주는 디스코드 봇입니다. 작동 방식은 사용자가 추가한 문제들 중에서 랜덤으로 뽑아 문제를 출제하고 답을 입력하면 맞았는지 틀렸는지를 알려주는 봇입니다. 만들게 된 계기는 고등학교 1학년 때 암기과목이 많아서 조금 더 효율적으로 공부할 수 있는 방법이 없을까 고민하던 중에 평소에 자주 사용하는 디스코드에 이러한 봇을 만든다면 틈틈히 공부를 할 수 있겠구나 라는 생각이 들어 만들게 되었습니다. 봇 제작은 'Python''Discord'모듈을 이용해서 제작하였습니다.

 

코드상세 설명

기본 CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import discord
import random
 
client = discord.Client()
 
@client.event
async def on_ready():
    print("봇 구동 중")
    bar = discord.Game("퀴즈 만들기")
    await client.change_presence(status=discord.Status.online, activity=bar)
 
science = {"표준화석이란?" : "지층의 생성시대를 알려주는 화석""화석이란?" : "지질시대에 살았던 생물의 유해나 흔적이 지층 속에 남아 있는 것""시상화석이란?" : "지층의 생성환경을 알려주는 화석""약(   년) 전 지구가 탄생한 후부터 현재까지의 기간을 지질시대라고 한다.(빈칸에 들어갈 말은?)" : "46억""지질시대의 구분기준?" : "지구환경 변화로 인한 생물의 급격한 변화""표준화석은 생존 기간이 (   ). 빈칸에 들어갈 말은?" : "짧다""표준화석은 분포면적이 (   ). 빈칸에 들어갈 말은?" : "넓다""선캄브리아 시대의 바다에서는 광합성을 하는 (   )가 출현했다. 빈칸에 들어갈 말은?" : "남세균 사이아노박테리아""남세균은 대기 중 (   )을 증가시켰다. 빈칸에 들어갈 말은?" : "산소함량""가장 오래된 생물의 흔적인 (   ) 형성. 빈칸에 들어갈 말은?" : "스트로마톨라이트""선캄브리아 시대 후기에 (   )생물이 출현하여 (   ) 화석 형성. 빈칸에 들어갈 말은?(각각 빈칸은 다른 답이 들어감. 띄워쓰기로 구분)" : "다세포 에디아카라 동물군""무척추 동물의 예시 3가지(띄워쓰기로 구분)" : "삼엽충 방추충 완족류",
"고생대의 척추 동물인 (   ). 예 : (   ). 빈칸에 들어갈 말은?(각각 빈칸은 다른 답이 들어감. 띄워쓰기로 구분)" : "어류 갑주어""중생대의 바다에는 (   ) 번성. 빈칸에 들어갈 말은?" : "암모나이트""중생대의 척추동물 (   ), 중생대의 식물 (   ). 빈칸에 들어갈 말은?(각각의 빈칸은 다른 답이 들어감. 띄워쓰기로 구분)" : "파충류 겉씨식물""신생대의 바다에는 (   ) 번성 -> (   )의 일종. 빈칸에 들어갈 말은?(각각의 빈칸은 다른 답이 들어감. 띄워쓰기로 구분)" : "화폐석 플랑크톤""신생대의 척추동물 (   ), 신생대의 식물 (   ). 빈칸에 들어갈 말은?(각각의 빈칸은 다른 답이 들어감. 띄워쓰기로 구분)" : "포유류 조류 속씨식물""신생대 후기의 (   ) 출현" : "최초의 인류""척추동물의 진화과정을 순서대로 쓰시오.(띄워쓰기로 구분)" : "어류 양서류 파충류 포유류와조류""식물의 진화과정을 순서대로 쓰시오.(띄워쓰기로 구분)" : "해조류 양치식물 겉씨식물 속씨식물","시상화석은 생존 기간이 (   ). 빈칸에 들어갈 말은?" : "길다""시상화석은 분포면적이 (   ). 빈칸에 들어갈 말은?" : "좁다""표준화석의 예시 7가지(띄워쓰기로 구분)" : "삼엽충 공룡 화폐석 갑주어 방추충 암모나이트 매머드""시상화석의 예시 4가지(띄워쓰기로 구분)" : "고사리 산호 조개 참나무",
"생존기간이 짧고 분포면적이 넓은 화석은?" : "표준화석""생존기간이 길고 분포면적이 좁은 화석은?" : "시상화석""화석을 통해 알 수 있는 것 6가지(쉼표로 구분)" : "지층이 생성된 시대,지층이 생성될 당시의 환경,과거 생물의 진화과정,대륙의 이동,과거육지와 바다환경,지층의 융기""중생대 시대에 나타난 산맥 2가지(띄워쓰기로 구분)" : "로키산맥 안데스산맥""신생대 시대에 나타난 산맥 2가지(띄워쓰기로 구분)" : "알프스산맥 히말라야산맥""판게아가 형성된 시대는?" : "고생대""판게아가 분리된 시대는?" : "중생대""대서양과 인도양이 멀어지고 태평양이 좁아져 현재와 비슷한 수륙분포를 가지는 시대는?" : "신생대""고생대의 육지에서 번성한 것은? 3가지 (띄워쓰기로 구분)" : "양서류 곤충류 양치식물""겉씨식물의 예시 3가지 (띄워쓰기로 구분)" : "소철 은행나무 잣나무""속씨식물의 예시 2가지 (띄워쓰기로 구분)" : "단풍나무 참나무""Ph란 무엇인가?" : "수소이온의 농도""Ph차이가 2라면 수소농도 차이는?" : "100배""중화반응 식은?" : "산 + 염기 -> H2O + 염 + 중화열""알짜이온 반응식을 쓰시오" : "H+ + OH- -> H2O",
"염이란 무엇인가?" : "산의 음이온과 염기의 양이온이 만난 것이다.""중화점이란?" : "H+나 OH-가 하나도 남지 않은 중성 상태의 지점""중화점 이후 온도가 내려가는 이유는?" : "온도는 전체 용액 부피 분의 생성된 물의 양이다 따라서 중화점 이후는 전체 용액 부피는 증가하고 생성된 물의 양은 무변이랑 온도는 감소한다""중화점까지 전류의 세기가 감소하는 이유는?" : "H2O가 생성되면서 이온의 농도가 감소하므로 전류의 세기가 감소하게 된다.""산의 공통된 성질 4가지 (쉼표로 구분)" : "H+를 가진다,신맛이 난다,금속과 반응시 H2기체가 발생한다,CaCo3와 반응시 Co2기체가 발생한다""염기의 성질 4가지" : "OH-를 가진다,물에 녹아서 전류가 흐른다,쓴맛이 난다,단백질을 녹여서 미끌미끌하다""산은 리트머스 종이에 닿으면 무슨 색으로 변할까?" : "붉은색""염기는 리트머스 종이에 닿으면 무슨 색으로 변할까?" : "푸른색""산은 메틸오렌지에 닿으면 무슨 색으로 변할까?" : "붉은색""염기는 메틸오렌지에 닿으면 무슨 색으로 변할까?" : "노란색""산은 BTB에 닿으면 무슨 색으로 변할까?" : "노란색""염기는 BTB에 닿으면 무슨 색으로 변할까?" : "푸른색""산은 페놀프탈레인에 닿으면 무슨 색으로 변할까?" : "투명색""염기는 페놀프탈레인에 닿으면 무슨 색으로 변할까?" : "붉은색""강산의 종류 3가지 (띄워쓰기로 구분)" : "HCL HNO3 H2SO4""강염기의 종류 3가지 (띄워쓰기로 구분)" : "NAOH KOH CA(OH)2""약산의 종류 3가지 (띄워쓰기로 구분)" : "HF H2CO3 CH3COO-""약염기의 종류 2가지 (띄워쓰기로 구분)" : "MG(OH)2 NH3+H2O"}
 
english = {"2030년, Ares 3 탐사대는 화성으로 보내진다." : "in 2030 the ares 3 mission team is sent to mars""임무를 수행하던 중, 그들은 사고를 겪게 되고, 여섯 명의 팀원 중 한 명인 Mark Watney는 실종된다." : "during their mission they have an accident and mark watney one of the six members goes missing""그가 죽었다고 생각하고 나머지 팀원들은 헤르메스라고 불리는 우주선을 타고 화성을 떠난다." : "thinking he is dead the rest of the crew goes aboard a spaceship called hermes and leaves mars""그러나 Mark는 여전히 살아 있으며 험난한 행성 위에 홀로 있는 자신을 발견한다." : "however mark is still alive and finds himself alone on the harsh palnet""이제 그는 살아남기 위해 자신의 전문 지식과 경험, 그리고 아이디어에 의존해야만 한다." : "now he must depend on his expertise experience and ideas to survive""일지 기록: 7일째" : "log entry: day7""좋아, 밤에 잠을 잘 자고 나니, 상황이 어제만큼 절망적으로 보이진 않는다." : "okay i have had a good night's sleep and things do not seem as hopeless as they did yesterday""오늘 나는 보급품과 외부 장비를 점검했다. 나의 상황은 이러하다." : "today i checked the supplies and external equipment here is my situation""화성 표면 탐사 기간은 31일로 예정되어 있었다." : "the surface mission was supposed to be thirty-one days""우리는 전 대원이 56일 동안 지내기에 충분한 식량을 가져왔다." : 'we brought enough food to last the whole crew fifty-six days',
"▶6일째 되는 날 사고가 났고, 그리하여 여섯 사람이 50일 동안 먹을 수 있는 충분한 식량이 남았다." : "the accident happened on the sixth day which leaves enough food to feed six people for fifty days""▶나는 혼자이므로, 300일 동안 버틸 수 있을 것이다." : "i am just one guy so it will last me three hundred days""만약 내가 식사량을 줄인다면, 훨씬 더 오래 버틸 수 있을 것이다." : "if i cut down on my meals it will last much longer""나는 지금 바로 식사량 제한을 시작할 것이다." : "i am going to start limiting them right now""이미 꽤 최소한의 양으로 식사하고 있지만, 식사마다 1인분의 3/4을 먹을 수 있고, 그래도 괜찮을 것 같다" : "meals are pretty minimal already but i think i can eat a three-fourths portion per meal and still be all right""그렇게 하면 300일 분량의 식량을 400일 분량으로 바꿀 수 있다." : "that should turn my three hundred days of food into four hundred""우주복 또한 넉넉히 있다." : "i have enough space suits too""내가 어제 입었던 우주복은 구멍이 났다" : "yhe one i wore yesterday has a hole in it""그렇지만, 거주용 막사(Hab) 안에 상태가 아주 좋은 여벌의 우주복이 여섯 벌 있다" : "but in the hab there are six extra suits in perfect condition""그렇지만, 거주용 막사(Hab) 밖으로 나와 보니 밖의 상황은 그리 낙관적이지 않다." : "when i go out of the hab however things are not so optimistic""위성 안테나 접시가 보이지 않는다. 몇 킬로미터쯤 날아간 모양이다." : "i cannot find the satellite dish it could be kilometers away""▶MAV는 사라졌다. 나의 동료들이 그것을 타고 궤도에 있는 Hermes호로 갔다." : "the mav is gone the crew took it up to hermes in orbit",
"MDV는 남아 있으며, 선체에 손상이 있다." : "the mdv is left and there is damage on the main body""두 대의 화성 표면 탐사 차 모두 거의 완전히 모래에 묻혀 있지만, 상태는 괜찮아 보인다." : "both rovers are almost completely buried in sand but they seem okay""하루쯤 일을 하면 파낼 수 있을 것이다." : "i will be able to dig them out with a day or so of work""오늘 그렇게 한다면, 나는 내일 이맘때 두 대 중 적어도 한 대는 운전하고 있을 것이다." : "if i do so today i will be driving at least one of them at this time tomorrow.""태양광 전지들은 모래를 뒤집어쓴 채 있었지만, 모래를 쓸어 주자 완벽하게 제 기능을 회복했다." : "the solar cells were covered in sand but once i swept them off they returned to full efficiency""▶내가 무엇을 하든, 전력은 충분 할 것이다." : "whatever i do i will have plenty of electric power""내가 해야 할 일은 며칠에 한 번씩 태양광 전지의 모래를 쓸어 내는 것뿐이다." : "what i have to do is sweep them off every few days""거주용 막사 안에 있는 장비들은 막사의 튼튼한 설계 덕분에 상태가 아주 좋다." : "things inside the hab are great thanks to its solid design""나는 산소 발생기에 대한 전체 점검을 실행했다. 상태가 완벽하다." : "i did a full checkup on the oxygenator it is perfect""그것에 문제가 생기더라도 내가 사용할 수 있는 여분의 장비가 있다." : "if anything goes wrong with it there is a spare i can use",
"그러나 그것은 주 산소 발생기를 수리하는 동안 사용하는 비상용 장비일 뿐이다." : "but it is only for emergency use while i repair the main one""이 장비는 5일 동안 사용하게 되어 있으므로 내겐 30일 치(대원 여섯 명이 아니라 혼자 숨 쉬는 것이므로)의 여분이 있는 셈이다" : "it is intended to last five days which means thirty days for me (just one person breathing instead of the six crew members)""물 환원기도 잘 작동한다." : "the water recycler is working fine too""나쁜 소식은 여분의 물 환원기가 없다는 것이다." : "the bad news is there is no spare""물 환원기가 작동을 멈춘다면, 서둘러 소변을 끓이는 장비를 만드는 동안에 나는 비축된 물을 마시고 있어야 할 것이다." : "if it stops working i will have to drink reserve water while i rush to make equipment for boiling urine.",
"다행히, 현재 물 환원기는 아무 문제가 없다." : "fortunately there are no problems with the water recycler now""이제, 음식, 물, 그리고 막사 안의 장비들을 모두 점검했다." : "so food water and equipment inside the hab are all taken care of""더 좋은 것은, 내가 식물학자이자 기계 공학자라는 것이다." : "what is better i am a plant scientist and mechanical engineer""탐사 대원들은 모두 전문 분야가 각자 두 개씩 있다." : "everyone on the mission has two specialties""기본적으로, 나는 식물을 만지작거리는 탐사대의 기술자인 셈이다." : "basically i am the mission’s engineer who plays with plants.""내 전문 지식은 무언가 좋지 않은 상황이 일어났을 때 내 목숨을 구해줄 수 있을지도 모른다." : "my specialties could save my life if something bad happens""나는 어떻게 하면 살아남을지 계속 궁리하고 있다. 희망이 전혀 없는 것은 아니다." : "i have been thinking about how to survive it is not entirely hopeless""약 4년 후 Ares 4 탐사대가 도착할 때 다시 화성에 사람들이 돌아올 것이다." : "there will be humans back on mars in about four years when the ares 4 mission team arrives""Ares 4 탐사대는 이곳에서 멀리 떨어진 장소에 착륙할 것이고, 나 혼자 힘으로 그곳에 갈 수 없다." : "the team will be landing at a site far from here and i cannot get there on my own""하지만, 통신을 할 수 있다면 구조될지도 모른다." : "but if i could communicate i might get rescued""그들이 수중에 있는 자원으로 어떻게 나를 구조해 낼지는 모르겠지만, NASA에는 똑똑한 사람들이 많이 있다." : "i am not sure how they would manage that with the resources on hand but nasa has a lot of smart people""그러므로, 내가 가장 필요한 것은 통신 장비이다. 그것부터 고쳐야 한다." : "so what i need most is a communications device i have to fix it first"}
check = False
= ""
cs

봇을 구동하는데 필요한 기본 코드와 문제를 저장하는 딕셔너리 코드입니다. 문제가 더 많아진다면 txt파일에 저장한 후 읽어오기를 하는 것도 괜찮을 것 같다는 생각이 드네요.

 

퀴즈 시작 CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@client.event
async def on_message(message):
    global science, b, check
 
    if message.content.startswith("!퀴즈"):
        if check == False:
            subject = message.content[4:6]
            if subject == "과학":
                a = random.choice(list(science.keys()))
                b = science[a]
                check = True
                await message.channel.send("`" + a + "`")
 
            if subject == "영어":
                space = message.content[7:]
                if space == "7":
                    a = random.choice(list(english.keys()))
                    b = english[a]
                    check = True
                    await message.channel.send("`" + a + "`")
 
        elif check == True:
            await message.channel.send("`이미 퀴즈를 푸시는 중 입니다. 모르겠다면 !패스를 쳐주세요.`")
cs

봇이 사용자가 원하는 과목을 입력받은 후 그 과목의 문제들 중 랜덤으로 하나를 뽑아 출제하는 코드입니다. 

 

정답 입력 CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
    if message.content.startswith("!정답"):
        if check == True:
            answer = message.content[4:]
            if answer == b:
                check = False
                embed = discord.Embed(title = "!정답!", color = 0x00aaaa)
                await message.channel.send(embed = embed)
            elif answer != b:
                embed = discord.Embed(title = "오답...", color = 0x00aaaa)
                await message.channel.send(embed = embed)
        
        elif check == False:
            await message.channel.send("`풀고 있는 퀴즈가 없습니다.`")
cs

사용자가 랜덤으로 출제된 문제를 보고 답을 입력하면 정답인지 오답인지 알려주는 코드입니다.

 

패스 CODE

1
2
3
4
5
6
7
8
9
    if message.content.startswith("!패스"):
        if check == True:
            check = False
            embed = discord.Embed(title = "#패스#", color = 0x00aaaa)
            await message.channel.send(embed = embed)
            await message.channel.send("`정답은 '" + b + "' 이였습니다.\n문제를 패스하셨습니다.`")
 
        elif check == False:
            await message.channel.send("`풀고 있는 퀴즈가 없습니다.`")
cs

사용자가 문제의 답을 모르겠는 경우 봇이 정답을 공개하고 문제를 패스해주는 코드입니다.

 

실제 사용 사진

실제 사용 사진 1
실제 사용 사진 2

 

후기

이 봇을 만들어서 실제로 암기 복습이 많이 되었고 많은 도움이 됐었던 것 같습니다. 또 코딩을 통해서 실제로 일상생활에 도움이 되는 봇을 만든 것 같아 뿌듯했습니다. 나중에 자습서 출판사 같은 곳에서 이러한 봇을 만든다면 많은 사람들이 이용하지 않을까? 라는 생각이 드네요. 다음에도 이런 유용한 봇을 만들고 싶다는 생각이 듭니다. 


728x90