Skip to content

Commit

Permalink
feat: small quality of life changes (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
SkellyBG authored Mar 15, 2024
1 parent a967c38 commit e96acab
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 31 deletions.
44 changes: 38 additions & 6 deletions cogs/puzzle.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,25 @@ async def submit_answer(
)
return

await interaction.followup.send("The submitted answer is ...CORRECT!")
completed_puzzles = await get_completed_puzzles(player.team_name)
# we must have submitted a puzzle correctly at this point
# if so, we can check if the number of puzzles completed is
# UTS - 4, USYD - 11 (4 + 1 + 6), or UNSW - 16 (4 + 1 + 6 + 1 + 4) respectively
num_of_puzzles_completed = len(completed_puzzles)
if num_of_puzzles_completed == 4:
await interaction.followup.send(
"The submitted answer is ...CORRECT! The meta for UTS is now unlocked!"
)
elif num_of_puzzles_completed == 11:
await interaction.followup.send(
"The submitted answer is ...CORRECT! The meta for USYD is now unlocked!"
)
elif num_of_puzzles_completed == 16:
await interaction.followup.send(
"The submitted answer is ...CORRECT! The meta for UNSW is now unlocked!"
)
else:
await interaction.followup.send("The submitted answer is ...CORRECT!")

@app_commands.command(name="list", description="List the available puzzles")
@in_team_channel
Expand All @@ -183,20 +201,24 @@ async def list_puzzles(self, interaction: discord.Interaction):

puzzle_ids = []
puzzle_name_links = []
puzzle_answers = []
for puzzle in puzzles:
submissions = await find_submissions_by_discord_id_and_puzzle_id(
player.discord_id, puzzle.puzzle_id
)

if any([submission.submission_is_correct for submission in submissions]):
puzzle_ids.append(f":white_check_mark: {puzzle.puzzle_id}")
puzzle_answers.append(f"{puzzle.puzzle_answer}")
else:
puzzle_ids.append(puzzle.puzzle_id)
puzzle_answers.append("?")

puzzle_name_links.append(f"[{puzzle.puzzle_name}]({puzzle.puzzle_link})")

embed.add_field(name="ID", value="\n".join(puzzle_ids), inline=True)
embed.add_field(name="Puzzles", value="\n".join(puzzle_name_links), inline=True)
embed.add_field(name="Answers", value="\n".join(puzzle_answers), inline=True)
await interaction.followup.send(embed=embed)

@app_commands.command(
Expand Down Expand Up @@ -274,19 +296,29 @@ async def leaderboard(self, interaction: discord.Interaction):
)
for _ in range(num_embeds)
]
leaderboard_text = [("", "") for _ in range(num_embeds)]
leaderboard_text = [("", "", "") for _ in range(num_embeds)]
for i, val in enumerate(leaderboard_values):
team_name, puzzles_solved = val

team_str, puzzles_solved_str = leaderboard_text[i // TEAMS_PER_EMBED]
team_name, puzzles_solved, submission_time = val
print(leaderboard_text[i // TEAMS_PER_EMBED])
team_str, puzzles_solved_str, submission_time_str = leaderboard_text[
i // TEAMS_PER_EMBED
]
team_str += f"{i+1}. {team_name}\n"
puzzles_solved_str += f"{puzzles_solved}\n"
submission_time_str += f"{submission_time.strftime('%d/%m %X') if submission_time else 'N/A'}\n"

leaderboard_text[i // TEAMS_PER_EMBED] = (team_str, puzzles_solved_str)
leaderboard_text[i // TEAMS_PER_EMBED] = (
team_str,
puzzles_solved_str,
submission_time_str,
)

for page_num, embed in enumerate(leaderboard_embeds):
embed.add_field(name="Team", value=leaderboard_text[page_num][0])
embed.add_field(name="Puzzles Solved", value=leaderboard_text[page_num][1])
embed.add_field(
name="Last Submission Time", value=leaderboard_text[page_num][2]
)

await interaction.followup.send(
embed=leaderboard_embeds[0], view=PaginationView(leaderboard_embeds)
Expand Down
19 changes: 14 additions & 5 deletions src/context/puzzle.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,17 @@ async def can_access_puzzle(puzzle: Puzzle, team_name: str) -> bool:
async def get_accessible_puzzles(team_name: str) -> List[Puzzle]:
puzzles = await get_puzzles()
completed_puzzles = await get_completed_puzzles(team_name)
return [
puzzle
for puzzle in puzzles
if can_access_puzzle_context(puzzle, completed_puzzles)
]
return sorted(
[
puzzle
for puzzle in puzzles
if can_access_puzzle_context(puzzle, completed_puzzles)
],
key=lambda p: (
p.uni != "UTS",
p.uni != "USYD",
p.uni != "UNSW",
p.uni != "METAMETA",
p.puzzle_name,
),
)
28 changes: 14 additions & 14 deletions src/db/seed.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@

async def seed_puzzles():
sample_puzzles = [
Puzzle("UTS-1", "UTS Puz1", "uts1", "skelly", "tiny.cc/puz", "UTS"),
Puzzle("UTS-2", "UTS Puz2", "uts2", "skelly", "tiny.cc/puz", "UTS"),
Puzzle("UTS-3", "UTS Puz3", "uts3", "skelly", "tiny.cc/puz", "UTS"),
Puzzle("UTS-4", "UTS Puz4", "uts4", "skelly", "tiny.cc/puz", "UTS"),
Puzzle("UTS-01", "UTS Puz1", "uts1", "skelly", "tiny.cc/puz", "UTS"),
Puzzle("UTS-02", "UTS Puz2", "uts2", "skelly", "tiny.cc/puz", "UTS"),
Puzzle("UTS-03", "UTS Puz3", "uts3", "skelly", "tiny.cc/puz", "UTS"),
Puzzle("UTS-04", "UTS Puz4", "uts4", "skelly", "tiny.cc/puz", "UTS"),
Puzzle("UTS-M", "UTS PuzM", "utsm", "skelly", "tiny.cc/puz", "UTS"),
Puzzle("USYD-1", "USYD Puz1", "usyd1", "simon", "tiny.cc/puz", "USYD"),
Puzzle("USYD-2", "USYD Puz2", "usyd2", "simon", "tiny.cc/puz", "USYD"),
Puzzle("USYD-3", "USYD Puz3", "usyd3", "simon", "tiny.cc/puz", "USYD"),
Puzzle("USYD-4", "USYD Puz4", "usyd4", "simon", "tiny.cc/puz", "USYD"),
Puzzle("USYD-5", "USYD Puz5", "usyd5", "simon", "tiny.cc/puz", "USYD"),
Puzzle("USYD-6", "USYD Puz6", "usyd6", "simon", "tiny.cc/puz", "USYD"),
Puzzle("USYD-01", "USYD Puz1", "usyd1", "simon", "tiny.cc/puz", "USYD"),
Puzzle("USYD-02", "USYD Puz2", "usyd2", "simon", "tiny.cc/puz", "USYD"),
Puzzle("USYD-03", "USYD Puz3", "usyd3", "simon", "tiny.cc/puz", "USYD"),
Puzzle("USYD-04", "USYD Puz4", "usyd4", "simon", "tiny.cc/puz", "USYD"),
Puzzle("USYD-05", "USYD Puz5", "usyd5", "simon", "tiny.cc/puz", "USYD"),
Puzzle("USYD-06", "USYD Puz6", "usyd6", "simon", "tiny.cc/puz", "USYD"),
Puzzle("USYD-M", "USYD PuzM", "usydm", "simon", "tiny.cc/puz", "USYD"),
Puzzle("UNSW-1", "UNSW Puz1", "unsw1", "timothy", "tiny.cc/puz", "UNSW"),
Puzzle("UNSW-2", "UNSW Puz2", "unsw2", "timothy", "tiny.cc/puz", "UNSW"),
Puzzle("UNSW-3", "UNSW Puz3", "unsw3", "timothy", "tiny.cc/puz", "UNSW"),
Puzzle("UNSW-4", "UNSW Puz4", "unsw4", "timothy", "tiny.cc/puz", "UNSW"),
Puzzle("UNSW-01", "UNSW Puz1", "unsw1", "timothy", "tiny.cc/puz", "UNSW"),
Puzzle("UNSW-02", "UNSW Puz2", "unsw2", "timothy", "tiny.cc/puz", "UNSW"),
Puzzle("UNSW-03", "UNSW Puz3", "unsw3", "timothy", "tiny.cc/puz", "UNSW"),
Puzzle("UNSW-04", "UNSW Puz4", "unsw4", "timothy", "tiny.cc/puz", "UNSW"),
Puzzle("UNSW-M", "UNSW PuzM", "unswm", "timothy", "tiny.cc/puz", "UNSW"),
Puzzle(
"METAMETA", "Meta Meta", "youwin", "everyone <3", "tiny.cc/puz", "METAMETA"
Expand Down
7 changes: 4 additions & 3 deletions src/queries/puzzle.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime
from typing import List
import psycopg
from psycopg.rows import class_row, dict_row
Expand Down Expand Up @@ -131,13 +132,13 @@ async def delete_puzzle(puzzle_id: str):
return True


async def get_leaderboard() -> tuple[str, int]:
async def get_leaderboard() -> List[tuple[str, int, datetime | None]]:
aconn = await psycopg.AsyncConnection.connect(DATABASE_URL)
acur = aconn.cursor()

await acur.execute("SET TIMEZONE to 'Australia/Sydney'")
await acur.execute(
"""
SELECT t.team_name, t.puzzle_solved
SELECT t.team_name, t.puzzle_solved, MAX(s.submission_time)
FROM public.teams AS t LEFT JOIN public.submissions AS s
ON (t.team_name = s.team_name)
AND s.submission_is_correct = TRUE
Expand Down
55 changes: 52 additions & 3 deletions tests/puzzle_test.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
from datetime import datetime
from zoneinfo import ZoneInfo
import pytest
import pytest_asyncio

from tests.utils import truncate
from src.queries.puzzle import create_puzzle, find_puzzle
from src.queries.puzzle import create_puzzle, get_puzzle, get_leaderboard
from src.queries.team import create_team, increase_puzzles_solved
from src.queries.submission import create_submission
from src.models.puzzle import Puzzle


Expand All @@ -15,7 +19,7 @@ async def async_setup(self):
@pytest.mark.asyncio
async def test_can_create_puzzle(self):
expected: Puzzle = Puzzle(
"UTS-1", "The Answer of Life", "42", "Skelly", "tiny.cc/rickroll", "UTS"
"UTS-01", "The Answer of Life", "42", "Skelly", "tiny.cc/rickroll", "UTS"
)
await create_puzzle(
expected.puzzle_id,
Expand All @@ -25,5 +29,50 @@ async def test_can_create_puzzle(self):
expected.puzzle_link,
expected.uni,
)
result = await find_puzzle("UTS-1")
result = await get_puzzle("UTS-01")
assert expected == result

@pytest.mark.asyncio
async def test_empty_leaderboard(self):
await create_puzzle(
"UTS-01",
"The Answer of Life",
"42",
"Skelly",
"tiny.cc/rickroll",
"UTS",
)
await create_team("test team", 1, 1, 1, 1)
assert await get_leaderboard() == [("test team", 0, None)]

@pytest.mark.asyncio
async def test_leaderboard(self):
await create_puzzle(
"UTS-01",
"The Answer of Life",
"42",
"Skelly",
"tiny.cc/rickroll",
"UTS",
)
await create_team("test team 1", 1, 1, 1, 1)
await create_team("test team 2", 1, 1, 1, 1)

await create_submission(
"UTS-01",
"test team 2",
datetime(2024, 1, 1, tzinfo=ZoneInfo("Australia/Sydney")),
"42",
True,
)

await increase_puzzles_solved("test team 2")

assert await get_leaderboard() == [
(
"test team 2",
1,
datetime(2024, 1, 1, tzinfo=ZoneInfo("Australia/Sydney")),
),
("test team 1", 0, None),
]

0 comments on commit e96acab

Please sign in to comment.