From 415f4e54747eed4ba7a79ee46aaa7e757cc7cf36 Mon Sep 17 00:00:00 2001 From: Wim De Clercq Date: Thu, 10 May 2018 15:15:09 +0200 Subject: [PATCH] Add the snake quiz from Team 7 - Mushy and Cardium - to the snakes cog. Original PR: https://github.com/discord-python/code-jam-1/pull/2 Completes task: https://app.clickup.com/754996/757069/t/2ww7u --- bot/cogs/snakes.py | 51 ++++++++++++++++++++- bot/constants.py | 4 ++ snake_questions.json | 104 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 snake_questions.json diff --git a/bot/cogs/snakes.py b/bot/cogs/snakes.py index d2484469b5..1a2cbeffc2 100644 --- a/bot/cogs/snakes.py +++ b/bot/cogs/snakes.py @@ -1,11 +1,16 @@ import asyncio +import json import logging import random import string +from typing import Dict -from discord import Colour, Embed, Member, Reaction +from discord import Colour, Embed, Member, Message, Reaction +from discord.abc import Messageable from discord.ext.commands import AutoShardedBot, Context, command +from bot import constants + log = logging.getLogger(__name__) # Antidote constants @@ -261,6 +266,50 @@ def event_check(reaction_: Reaction, user_: Member): log.debug("Ending pagination and removing all reactions...") await board_id.clear_reactions() + @command(name="snakes.quiz()", alias=["snakes.quiz"]) + async def quiz(self, ctx: Context): + """Asks a snake-related question in the chat and validates the user's guess.""" + channel = ctx.channel + answers_emoji = { + "a": "🇦", + "b": "🇧", + "c": "🇨", + "d": "🇩" + } + question, message = await self._post_quiz_question(answers_emoji, channel) + await self._validate_quiz_answer(answers_emoji, channel, ctx, question, message) + + async def _post_quiz_question(self, answers_emoji:Dict[str,str], channel:Messageable): + """Ask a random question from the snake_questions.json in the chat.""" + with open(f"{constants.PROJECT_ROOT}/snake_questions.json") as quizson: + questions = json.load(quizson) + question = questions["questions"][random.randint(0, 10)] + em = Embed(title=question["question"], + description="\n\n".join(f"{value}: {question[key]}" + for key, value in answers_emoji.items())) + quiz = await channel.send("", embed=em) + for emoji in answers_emoji.values(): + await quiz.add_reaction(emoji) + return question, quiz + + async def _validate_quiz_answer(self, answers_emoji:Dict[str,str], channel:Messageable, ctx:Context, + question:Dict[str,str], message:Message): + """Validates the author's guess to the given question.""" + def my_check(reaction, user): + return reaction.message.id == message.id and user == ctx.author and str(reaction.emoji) + + try: + reaction, user = await ctx.bot.wait_for("reaction_add", timeout=20.0, check=my_check) + except asyncio.TimeoutError: + await channel.send("Bah! You took too long.") + else: + answer = question["answerkey"] + if str(reaction.emoji) == answers_emoji[answer]: + await channel.send("That was correct! Well done!") + else: + await channel.send(f"That was incorrect! " + f"The correct answer was {answer}, unfortunately.") + def setup(bot): bot.add_cog(Snakes(bot)) diff --git a/bot/constants.py b/bot/constants.py index 6641a89bb7..49ec729daf 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -60,6 +60,10 @@ PAPERTRAIL_ADDRESS = os.environ.get("PAPERTRAIL_ADDRESS") or None PAPERTRAIL_PORT = int(os.environ.get("PAPERTRAIL_PORT") or 0) +# Paths +BOT_DIR = os.path.dirname(__file__) +PROJECT_ROOT = os.path.abspath(os.path.join(BOT_DIR, os.pardir)) + # Bot replies NEGATIVE_REPLIES = [ "Noooooo!!", diff --git a/snake_questions.json b/snake_questions.json new file mode 100644 index 0000000000..d3841da6d5 --- /dev/null +++ b/snake_questions.json @@ -0,0 +1,104 @@ +{ + "questions":[ + { + "id": 0, + "question": "How long have snakes been roaming the Earth?", + "a":"3 million years", + "b":"30 million years", + "c":"130 million years", + "d":"200 million years", + "answerkey":"c" + }, + { + "id": 1, + "question": "What characteristics do all snakes share?", + "a":"They are carnivoes", + "b":"They are all programming languages", + "c":"Cold-blooded", + "d":"They are both carnivores and cold-blooded", + "answerkey":"c" + }, + { + "id": 2, + "question": "How snakes hear?", + "a":"With small ears", + "b":"Through their skin", + "c":"Through their tail", + "d":"They don't use their ears at all", + "answerkey":"b" + }, + { + "id": 3, + "question": "What don't snakes see?", + "a":"Colour", + "b":"Light", + "c":"Both of the above", + "d":"Other snakes", + "answerkey":"a" + }, + { + "id": 4, + "question": "What unique vision ability do boas and pythons possess?", + "a":"Night vision", + "b":"Infared vision", + "c":"See through walls", + "d":"They don't have vision", + "answerkey":"b" + }, + { + "id": 5, + "question": "How does a snake smell?", + "a":"Through its nose", + "b":"Through its tongue", + "c":"Through its ears", + "d":"Both through its nose and its tongues", + "answerkey":"d" + }, + { + "id": 6, + "question": "Where are Jacobson's organs located in snakes?", + "a":"Mouth", + "b":"Tail", + "c":"Stomach", + "d":"Liver", + "answerkey":"a" + }, + { + "id": 7, + "question": "Snakes have very similar internal organs compared to humans. Snakes, however; lack the following:", + "a":"A diaphragm", + "b":"Intestines", + "c":"Lungs", + "d":"Kidney", + "answerkey":"a" + }, + { + "id": 8, + "question": "Snakes have different shaped lungs than humans. What do snakes have?", + "a":"An elongated right lung", + "b":"A small left lung", + "c":"Both of the above", + "d":"None of the above", + "answerkey":"c" + }, + { + "id": 9, + "question": "What's true about two-headed snakes?", + "a":"They're a myth!", + "b":"Rarely survive in the wild", + "c":"They're very dangerous", + "d":"They can kiss each other", + "answerkey":"b" + }, + { + "id": 10, + "question": "What substance covers a snake's skin?", + "a":"Calcium", + "b":"Keratin", + "c":"Copper", + "d":"Iron", + "answerkey":"b" + } + ] + +} \ No newline at end of file