Part 12: How To Estimate Curation Rewards Using Steem-Python
![steem-python.png](https://steemitimages.com/640x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1515886103/kmzfcpvtzuwhvqhgpyjp.png)
This tutorial is part of a series where we explain different aspects of programming with steem-python
. Links to the other tutorials can be found in the curriculum section below. In part 9 of this series we learned how to calculate the total rewards of a post and in this tutorial we will learn how to estimate the curation rewards of a post!
What will I learn
- How to sort votes by rshares
- How to calculate the curation reward penalty
- How to use this to calculate the curation reward of a vote
- How to estimate the total curation reward of a post
Requirements
- Python3.6
steem-python
Difficulty
- Intermediate
Tutorial
If you find it easier to follow along this way you can get the entire code for this tutorial from here, where I have split everything up into the relevant sections.
Sorting votes by rshares
Before we start calculating the curation reward penalty I want to look at the information each vote provides.
{
"voter": "juliank",
"weight": 19987,
"rshares": "407698665716",
"percent": 3000,
"reputation": "66217154475939",
"time": "2018-01-22T18:10:33"
}
If you recall from part 10, each vote looks something like the above one. Instead of jumping to calculating the curation penalty straight away, we will print some information about each post, so you can see what each part can be used for. For example, using what we have already learned, we could print the voter, how much their vote was worth and the percent of their vote. To do this we need the code that we used in part 9 to calculate a post's rewards, then create a list of all the votes using list comprehension and loop over it, like so
# Everything we need to calculate the reward
reward_fund = steem.get_reward_fund()
reward_balance = Amount(reward_fund["reward_balance"]).amount
recent_claims = float(reward_fund["recent_claims"])
reward_share = reward_balance / recent_claims
base = Amount(steem.get_current_median_history_price()["base"]).amount
post = Post("@steempytutorials/part-11-how-to-build-a-list-of-transfers-and-broadcast-these-in-one-transaction-with-steem-python")
# Create list of all votes, sort them by reward and print the top five
votes = [vote for vote in post["active_votes"]]
for vote in sorted(votes, key=lambda x: float(x["rshares"]), reverse=True):
print("{0:16} voted for ${1} - {2:>5}%".format(
vote["voter"],
str(float(vote["rshares"]) * reward_share * base)[:5],
vote["percent"] / 100))
which outputs the following
juliank voted for $3.849 - 30.0%
nicnas voted for $0.390 - 100.0%
fooblic voted for $0.176 - 100.0%
adialam voted for $0.037 - 100.0%
cifer voted for $0.017 - 90.0%
But here we aren't taking the curation reward penalty into account (amongst other things)! We need to use the time
attribute of a vote to calculate this!
Curation reward penalty
As some of you may know there is a curation reward penalty in the first 30 minutes after a post has been published. For example, if we take a post that is 10 minutes old and vote on it, our vote would only get 33% curation rewards. In steem-python
there's a function called curation_reward_pct()
that takes a post and then outputs what the penalty would be if you voted on it at that moment. We don't really have a use for this function, but we can use it as inspiration to create our own function. So let's take a look at it:
def curation_reward_pct(self):
""" If post is less than 30 minutes old, it will incur a curation reward penalty.
"""
reward = (self.time_elapsed().seconds / 1800) * 100
if reward > 100:
reward = 100
return reward
Looks pretty simple! We can create a function that takes a post and a vote on that post as arguments, then outputs the penalty the vote incurred at the time of voting. To do this we can use the function parse()
to easily convert the time
string to something we can use in our calculations and use timedelta
to change the 1800 seconds to 30 minutes instead (just for readability)
from dateutil.parser import parse
from datetime import timedelta
def curation_penalty(post, vote):
post_time = post["created"]
vote_time = parse(vote["time"])
time_elapsed = vote_time - post_time
reward = time_elapsed / timedelta(minutes=30) * 1.0
if reward > 1.0:
reward = 1.0
return reward
I have decided to return a number in the range 0 - 1.0
, because then we can use this to multiple each vote's reward.
Calculating curation reward per vote
Okay, so now we have a function to calculate the curation penalty, but what do we actually use this for? Since someone's reward is calculated by their amount of rshares
, we can simply multiply this with their curation penalty to get their actual rshares
. Also, instead of calculating the actual reward at the end, like we did in part 9, we will calculate the reward straight away. To do this we can create a simple curation_reward()
function that calculates the estimated payout that each voter will receive. We must also remember that only 25% goes to the curators, so we should take that into account as well
curation_pct = 0.25
def curation_reward(post, vote):
rshares = float(vote["rshares"])
base_share = reward_share * base
return (rshares * curation_penalty(post, vote) * curation_pct) * base_share
Adding everything together
Now we can calculate the payout for each vote separately, all that's left is to sum everything together!
curation_share = sum([curation_reward(post, vote) for vote in votes])
print(f"Estimated curation reward for this post is ${curation_share:.2}")
which for the post we used outputs the following
Estimated curation reward for this post is $0.22
Revisiting the votes
Since we can now calculate the actual value that curators get, we can revisit the five votes from above and see what their actual reward is!
juliank curation reward is $0.035 - 30.0%
nicnas curation reward is $0.097 - 100.0%
fooblic curation reward is $0.044 - 100.0%
adialam curation reward is $0.009 - 100.0%
cifer curation reward is $0.004 - 90.0%
Congratulations, you've now learned how to estimate the curation reward for a post using steem-python
! You've also been introduced to using list comprehensions (if you have never used them before), which are personally one of my favourite things.
Curriculum
The code for this tutorial can be found on GitHub!
This tutorial was written by @amosbastian in conjunction with @juliank.
Posted on Utopian.io - Rewarding Open Source Contributors
Thank you for the contribution. It has been approved.
You can contact us on Discord.
[utopian-moderator]
Merci beaucoup!
thanks for the tutorial, it is very helpful to predict how many results we can get from the curator or author
Hey @steempytutorials I am @utopian-io. I have just upvoted you!
Achievements
Suggestions
Get Noticed!
Community-Driven Witness!
I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!
Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x