This post has been de-listed
It is no longer included in search results and normal feeds (front page, hot posts, subreddit posts, etc). It remains visible only via the author's post history.
Not sure what WAYRStats is? Check out my post here.
Hello! Yes I'm still making these posts, if you only upvote it 12 times then I have to keep karma farming /s
Y'all should know the deal by now, this thread is gonna be showing off a new module for you guys. Unfortunately this one isn't brand new; this is just a year-in-total leaderboard version of an existing monthly metric. That said, that's a good thing! That means this data has scalability:
as the data one works with gets bigger and bigger, this module adapts to that and can still carry out its core functions. Something like the largest post metric isn't particularly scalable; yeah we can find the largest post of the year, but the monthly metrics already find that, and a smaller scope increases the value of that metric. On the opposite scale, something like post streak data has problems with smaller scales as opposed to larger ones, as the whole purpose of the module is to monitor data over a long period of time. The Sweet Talker's Club has nice scalability because both within smaller and larger contexts the data it produces is valuable, up and up and up as more data gets added to the scope. So, without further ado:
Leaderboard Stats: Sweet Talker's Club
#1: /u/AutoModerator....[99]
#2: /u/PHNX_Arcanus.....[40]
#3: /u/Some_Guy_87......[31]
#4: /u/tintintinintin...[24]
#5: /u/superange128.....[20]
#6: /u/UnknownNinja.....[16]
#7: /u/tauros113........[15]
#8: /u/Veshurik.........[12]
#9: /u/lostn............[11]
#10: /u/Bruxae..........[9]
As requested from a previous WAYRStats thread, you can view the full, 204-user leaderboard here. Automod puts in the fuckin work dude, hahaha. I primarily selected to show this one off because it shows off a different set of users compared to all the post total/average leaderboards which have a tendency to have a lot of shared names between this one. As I mentioned in my debut post, The Sweet Talker's Club tracks total comment replies, and it does so with a headache of a technique called recursion.
You can check out the post I linked up top for an in-depth explanation for how this module works; with this post, I wanted to take a second to show how I get everything to print out so nice and neat.
In most of my posts I simply end with "and then we print to console." ...But how do we do that? Obviously things are formatted pretty well, and if you looked at my code it's not a single line saying print(allTheData).MakeItLookNicePlease("thanks");
It takes a bit of extra stuff but that little extra makes things look great. So, here's the print code for this module:
def PrintSweetTalkers(self):
logging.info("\nThe Sweet Talker's Club: Tracks total comment replies for the month.")
for i, user in enumerate(OrderedDict(reversed(sorted(self.sweetTalkers.items(), key = lambda x : x[1]))), 0):
if self.sweetTalkers[user] > 2 and i < 10:
logging.info(str("#{}: /u/{}".format(i 1, user)).ljust(24, "-") "[{}]".format(self.sweetTalkers[user]))
One thing you'll notice is whenever it looks like I'm actually printing something I use a command called logging.info.
This is a command from the logging
import library, and it's identical in every way to other print statements like cout
or print
or Console.WriteLine
except that it also allows me to output things to a text file simultaneously. So with that, rather than having to copy all the text from the console window which it does not like when you do that at all, now I can just open up my log file and have access to everything in notepad, it's super handy. For other minor details, i
is a variable simply set up to limit the results to 10, and self
is used to make sure we have access to all the data we've collected (that data being stored in an instance of the class, accessed via self
). The last 2 lines are tricky but easy once explained. Let's take the first one: for i, user in enumerate(OrderedDict(reversed(sorted(self.sweetTalkers.items(), key = lambda x : x[1]))), 0):
There's a lot of functions happening here on top of one another, let's start from the middle of it all.
self.sweetTalkers.items()
- accesses the numerical values of my sweetTalkers data structure. Data is stored here inkey : value
pairs, this accesses the values, which is the data we care about.key = lambda x : x[1]
- this is a parameter we pass to the function explained in the next bullet. What this translates to is "sort based on which element is larger"sorted()
- This function...yeah. It sorts. Using the above two parameters it sorts the array and returns a list oftuples
based on the sort rules.reversed()
-sorted()
takes and sorts from low to high, but for leaderboards we want high to low, so we reverse the output.OrderedDict()
- Did you catch that in the above bullet? "Sorted" returns a list oftuples
- aka a single entry in a dictionary - but we're working with adictionary
and we want it to stay that way. Alist of tuples
is very similar to adictionary
however we expressly want to convert back to make things as manageable as possible.enumerate()
- Tells the two variables in the parentheses (our giant mess of ordered data andi
) to increment with each loop; it would do that anyway with the dictionary but it allows us to add ini
as well.
So fun fact about sorted
- that function doesn't actually sort the data. It changes nothing about my data, moves nothing around, rearranges zip, zilch, nada. What does it do? It stores the enumeration pattern in order to sort the data; in other words, it remembers in what order to go through the data to sort it, rather than actually sorting it. It's weird. I hate it. So we now have all of our data sorted and organized and ready to be printed, now let's look at this bad boy: logging.info(str("#{}: /u/{}".format(i 1, user)).ljust(30, ".") "[{}]".format(self.sweetTalkers[user]))
format()
- this one is cool. Format is a part of the native string library, and allows you to insert variables into strings, using{}
to signify where they go. So this bit here"#{}: /u/{}".format(i 1, user)
will output"#{i 1}: /u/{user}"
and thus something like#1: /u/AutoModerator
- there's a bunch of ways to go about this but I like this one, so here we are.str().ljust(30, ".")
- like above,ljust()
is a part of the string library, and stands for "left justify;" it takes everything withinstr()
(which is there to make whatever is inside it process as a string) and pads out the left of it with the fill character until it hits the character count. Here, it's 30 characters and the fill is periods; this is what makes it look straight and neat regardless of username length.
Thus we have our output. Formatted, looks nice, sorted and everything. If you have any questions lemme know and I'll answer what I can.
Pros and cons, I guess? Like, the universal con to be concerned about is "what if a user expressly games the system to get on [x] leaderboard?" But like, who's gonna do that for comment replies? It's a public facing forum, that kinda stuff can be dealt with easily. The pros, obviously, is that there's gonna be more comment replies, aka more conversation, aka more activity, aka mission accomplished. I don't really know of any ways to improve this module, but if you think you've got an idea then throw it my way!
As always, remember to upvote automod-chan, and: What are you reading?
Subreddit
Post Details
- Posted
- 4 years ago
- Reddit URL
- View post on reddit.com
- External URL
- reddit.com/r/visualnovel...