In this blog post a quick script to plot the frequency of our blog articles in the terminal. It’s good to see that we’re getting back on track 🙂
The code gist is here.
First we import the libraries we are going to use. As always we separate Standard Library modules from 3rd party ones as per PEP8:
from collections import Counter
from datetime import date
from dateutil.parser import parse
import plotext as plt
import requests
Then I define some constants:
API_URL = "https://codechalleng.es/api/articles/"
START_YEAR = 2017
THIS_YEAR = date.today().year
THIS_MONTH = date.today().month
MONTH_RANGE = range(1, 13)
I defined a year month generator. Why? Because some months we have not posted, yet I still want to show them on the graph.
def _create_yymm_range():
for year in range(START_YEAR, THIS_YEAR + 1):
for month in MONTH_RANGE:
yield f"{year}-{str(month).zfill(2)}"
if year == THIS_YEAR and month == THIS_MONTH:
break
Then the wokhorse function that calculates the amount of posts per month. We conveniently use a Counter
, the right abstraction here:
def get_articles_per_month(url=API_URL):
ym_range = _create_yymm_range()
cnt = Counter({ym: 0 for ym in ym_range})
data = requests.get(API_URL)
for row in data.json():
dt = parse(row["publish_date"])
if dt.year < START_YEAR:
continue
ym = dt.strftime("%Y-%m")
cnt[ym] += 1
return cnt
We use the requests
library to get all the articles which we expose using our platform’s API.
Again, using _create_yymm_range()
we make sure that all months are covered, even if there were 0 posts.
(Looking back cnt
could be better named as number_posts_per_months
. Well, you hardly get it right the first time!)
Making a plot with plotext is as simple as picking the type of graph and feeding it labels and values:
def show_plot(data):
labels, values = zip(*data.items())
plt.bar(labels, values)
plt.title("Pybites articles published per month")
plt.show()
zip(*data.items())
is a nice trick to extract labels and values from a list of tuples (which a dict’s .items()
method gives us):
>>> d = {1: 'a', 2: 'b', 3: 'c'}
>>> list(zip(*d.items()))
[(1, 2, 3), ('a', 'b', 'c')]
We give the plot a title and show it, which will render it in the terminal.
Lastly we make sure we call the two functions only if you call the script directly, not when importing it.
You do that by using an if __name__ == "__main__"
block:
if __name__ == "__main__":
data = get_articles_per_month()
show_plot(data)
And the result:
—
Thanks Russell for introducing me to this library the other day. Do you want to see a really cool use case? Check out his blog article 😍