commit dc4a51a86ffd3fbb1c04c4623e04ce3e83f33e17
parent e9068c04f921d98f858f8f00e2d4bd0d2a3b6b7c
Author: AsherMorgan <59518073+AsherMorgan@users.noreply.github.com>
Date: Thu, 4 Feb 2021 18:19:42 -0800
Implement speed command.
Diffstat:
| M | README.md | | | 6 | ++++++ |
| M | bot.py | | | 176 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------- |
2 files changed, 136 insertions(+), 46 deletions(-)
diff --git a/README.md b/README.md
@@ -64,6 +64,12 @@ If a command is not run in a countdown channel, the bot will run it for the 1st
**Usage:** `!countdown progress|p`
+### speed
+**Description:** Shows countdown speed statistics
+
+**Usage:** `!countdown speed|s`
+
+
### reload
**Description:** Reloads the countdown cache
diff --git a/bot.py b/bot.py
@@ -157,50 +157,6 @@ class Countdown:
except:
pass
- def progress(self):
- """
- Get countdown progress statistics.
-
- Returns
- -------
- dict
- A dictionary containing countdown progress statistics.
- """
-
- # Get basic statistics
- if (len(self.messages) > 0):
- total = self.messages[0].number
- current = self.messages[-1].number
- percentage = (total - current) / total * 100
- start = self.messages[0].timestamp
- else:
- total = 0
- current = 0
- percentage = 0
- start = datetime.utcnow()
-
- # Get rate statistics
- if (len(self.messages) > 1):
- rate = (total - current)/((self.messages[-1].timestamp - self.messages[0].timestamp) / timedelta(days=1))
- eta = datetime.utcnow() + timedelta(days=current/rate)
- else:
- rate = 0
- eta = datetime.utcnow()
-
- # Get list of progress
- progress = [{"time":x.timestamp, "progress":x.number} for x in self.messages]
-
- # Return stats
- return {
- "total": total,
- "current": current,
- "percentage": percentage,
- "progress": progress,
- "start": start,
- "rate": rate,
- "eta": eta,
- }
-
def contributors(self):
"""
Get countdown contributor statistics.
@@ -313,6 +269,73 @@ class Countdown:
leaderboard = sorted(leaderboard, key=lambda x: x["points"], reverse=True)
return leaderboard
+ def progress(self):
+ """
+ Get countdown progress statistics.
+
+ Returns
+ -------
+ dict
+ A dictionary containing countdown progress statistics.
+ """
+
+ # Get basic statistics
+ if (len(self.messages) > 0):
+ total = self.messages[0].number
+ current = self.messages[-1].number
+ percentage = (total - current) / total * 100
+ start = self.messages[0].timestamp
+ else:
+ total = 0
+ current = 0
+ percentage = 0
+ start = datetime.utcnow()
+
+ # Get rate statistics
+ if (len(self.messages) > 1):
+ rate = (total - current)/((self.messages[-1].timestamp - self.messages[0].timestamp) / timedelta(days=1))
+ eta = datetime.utcnow() + timedelta(days=current/rate)
+ else:
+ rate = 0
+ eta = datetime.utcnow()
+
+ # Get list of progress
+ progress = [{"time":x.timestamp, "progress":x.number} for x in self.messages]
+
+ # Return stats
+ return {
+ "total": total,
+ "current": current,
+ "percentage": percentage,
+ "progress": progress,
+ "start": start,
+ "rate": rate,
+ "eta": eta,
+ }
+
+ def speed(self):
+ """
+ Get countdown speed statistics.
+
+ Returns
+ -------
+ list
+ The countdown speed statistics.
+ """
+
+ # Get speed statistics
+ speed = []
+ dates = list(set([(x.timestamp - timedelta(hours=8)).date() for x in self.messages]))
+ for date in dates:
+ speed += [{
+ "date":date,
+ "progress":len([x for x in self.messages if (x.timestamp - timedelta(hours=8)).date() == date]),
+ }]
+ speed = sorted(speed, key=lambda x: x["date"])
+
+ # Return speed statistics
+ return speed
+
# Load list of channels
@@ -580,8 +603,8 @@ async def progress(ctx):
# Create embed
embed=discord.Embed(title="Countdown Progress")
- embed.description = f"**Progress:** {stats['total'] - stats['current']:,} / {stats['total']:,} ({round(stats['percentage'], 2)}%)\n"
- embed.description += f"**Average Progress per Day:** {round(stats['rate'], 2):,}\n"
+ embed.description = f"**Progress:** {stats['total'] - stats['current']:,} / {stats['total']:,} ({round(stats['percentage'], 1)}%)\n"
+ embed.description += f"**Average Progress per Day:** {round(stats['rate']):,}\n"
embed.description += f"**Start Date:** {start} ({startDiff:,} days ago)\n"
embed.description += f"**Estimated End Date:** {end} ({endDiff:,} days from now)\n"
embed.set_image(url="attachment://image.png")
@@ -624,6 +647,67 @@ async def reload(ctx):
+@bot.command(aliases=["s"])
+async def speed(ctx):
+ """
+ Shows information about countdown speed
+ """
+
+ # Get messages
+ if (ctx.channel.id in channels):
+ countdown = countdowns[ctx.channel.id]
+ else:
+ countdown = countdowns[channels[0]]
+
+ # Make sure the countdown has started
+ if (len(countdown.messages) == 0):
+ await ctx.send("Error: The countdown is empty.")
+ return
+
+ # Create temp file
+ tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
+ tmp.close()
+
+ # Get stats
+ stats = countdown.progress()
+ speed = countdown.speed()
+
+ # Create plot
+ plt.close()
+ plt.title("Countdown Speed")
+ plt.xlabel("Time")
+ plt.ylabel("Progress per Period")
+ plt.gcf().autofmt_xdate()
+
+ # Add data to graph
+ x = [x["date"] for x in speed]
+ y = [x["progress"] for x in speed]
+ for i in range(0, len(x)):
+ plt.bar(x[i], y[i], width=timedelta(days=1), color="#1f77b4")
+
+ # Save graph
+ plt.savefig(tmp.name)
+ file = discord.File(tmp.name, filename="image.png")
+
+ # Create embed
+ embed=discord.Embed(title="Countdown Speed")
+ embed.description = f"**Period Size:** 1 day\n"
+ embed.description += f"**Average Progress per Period:** {round(stats['rate']):,}\n"
+ embed.description += f"**Record Progress per Period:** {max(x['progress'] for x in speed):,}\n"
+ embed.description += f"**Progress during Current Period:** {speed[-1]['progress']:,}\n"
+ embed.set_image(url="attachment://image.png")
+
+ # Send embed
+ await ctx.send(file=file, embed=embed)
+
+ # Remove temp file
+ try:
+ os.remove(tmp.name)
+ except:
+ print(f"Unable to delete temp file: {tmp.name}.")
+
+
+
# Run bot
if (__name__ == "__main__"):
load_dotenv()