# Frenetic Array

## A canvas for logic and imagination.

When considering going viral, one of the critical things to consider is timing. For reddit, there are many tools and studies for this; but they’re all subreddit specific. This is for good cause, different subreddits are more active at different times of the day. But what about “r/all”?

So, skipping the implementation details (you can read about them below), I wrote a script that parsed 165,607 posts to get a general idea of what “r/all” does in a given day. Note the times are for Pacific Time (PT) zone.

So a pretty good trend. What about the mean upvote count?

Okay, not so pretty. Let’s filter out the outliers by replacing anything above 300 upvotes with a -1.

A decent trend until around 12:00 to 14:00, where everything goes sporadic. Let’s take a look at the median upvotes.

Again, let’s filter the outliers (anything above 1000).

So we can safely assume a lot of reddit posts are upvote counts are zero (actually, the mode — the most commonly occurring upvote count — is by far zero).

So far, these are pretty useless. But, there is one good litmus test for popularity: reaching over 1,000 upvotes. Let's take a look at that.

There looks like there could be something here. Let's switch to line graph and only sum to the hour.

Now that's a trend. Adding a cubic spline, we get a beautiful line graph:

It seems quite apparent that the best time to post is around 14:00 to 15:00. Neat.

## Implementation

I used the praw python package to download and parse all of the data. Unfortunately Reddit was having issues handling over 100,000 consecutive request (around 100/second), so my connection would be severed constantly. I had to manually restart where I left off.

The code is as follows

import praw
import datetime
from functools import reduce
import statistics
import time

def get_date(submission):
time = submission.created
return datetime.datetime.fromtimestamp(time)

def date_to_unix_second(t):
return (t-datetime.datetime(1970,1,1)).total_seconds()

# Thanks https://stackoverflow.com/questions/10797819/finding-the-mode-of-a-list
def mode(numbers, out_mode):
counts = {k:numbers.count(k) for k in set(numbers)}
modes = sorted(dict(filter(lambda x: x[1] == max(counts.values()), counts.items())).keys())
if out_mode=='smallest':
return modes[0]
elif out_mode=='largest':
return modes[-1]
else:
return modes

reddit = praw.Reddit(user_agent='bot1', client_id='', client_secret='', redirect_uri='' 'authorize_callback')
subreddit = reddit.subreddit('all')

day1 = datetime.datetime(2017, 5, 26, hour=0, minute=0, second=0)
day2 = datetime.datetime(2017, 5, 27, hour=0, minute=0, second=0)

current_day = day2

while current_day != day1:
current_minute = 0
total = 0

for submission in subreddit.submissions(date_to_unix_second(day1), date_to_unix_second(current_day) - 60*60):
submission_date = get_date(submission)

if submission_date.minute != current_minute:
current_minute = submission_date.minute

print("{0}:{1},{2},{3},{4},{5},{6},{7}".format(
submission_date.hour if submission_date.hour > 9 else "0" + str(submission_date.hour),
submission_date.minute if submission_date.minute > 9 else "0" + str(submission_date.minute),
))

current_day = submission_date

print(total)


For the spline, the code is as follows:

    delta_t = max(x) - min(x)
N_points = 300
xnew = [min(x) + i*delta_t/N_points for i in range(N_points)]

x_ts = [x_.timestamp() for x_ in x]
xnew_ts = [x_.timestamp() for x_ in xnew]
ynew = spline(x_ts, y, xnew_ts)


The graphs were produced by matplotlib, the code is below.

#!/usr/local/bin/python3
#
# plot.py
# Desktop
#
# Created by Illya Starikov on 05/16/17.
#

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime

import csv

def import_from_csv(filename):
with open(filename, "rt") as csvfile:

date_times = []
values = []

for date_and_time_string, value in csv_parsor:
datetime_object = datetime.strptime(date_and_time_string, '%H:%M')

date_times += [datetime_object.replace(day=26, month=5, year=2017)]
values += [value]

return (date_times, values)

def main():
# Get the data and the subplots
x, y = import_from_csv('data.csv')
fig, ax = plt.subplots()

# Make the figure wide and draw it
fig.set_size_inches((12, 5))
ax.plot_date(x, y, color='b', marker='+', markersize=6)

# Custom labels, since I have milestones
labels = ["1:00", "2:00", "3:00", "4:00", "5:00", "6:00", "7:00", "8:00", "9:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00", "20:00", "21:00", "22:00", "23:00"]

locs = [
mdates.date2num(datetime(2017, 5, 26, 1, 00)),
mdates.date2num(datetime(2017, 5, 26, 2, 00)),
mdates.date2num(datetime(2017, 5, 26, 3, 00)),
mdates.date2num(datetime(2017, 5, 26, 4, 00)),
mdates.date2num(datetime(2017, 5, 26, 5, 00)),
mdates.date2num(datetime(2017, 5, 26, 6, 00)),
mdates.date2num(datetime(2017, 5, 26, 7, 00)),
mdates.date2num(datetime(2017, 5, 26, 8, 00)),
mdates.date2num(datetime(2017, 5, 26, 9, 00)),
mdates.date2num(datetime(2017, 5, 26, 10, 00)),
mdates.date2num(datetime(2017, 5, 26, 11, 00)),
mdates.date2num(datetime(2017, 5, 26, 12, 00)),
mdates.date2num(datetime(2017, 5, 26, 13, 00)),
mdates.date2num(datetime(2017, 5, 26, 14, 00)),
mdates.date2num(datetime(2017, 5, 26, 15, 00)),
mdates.date2num(datetime(2017, 5, 26, 16, 00)),
mdates.date2num(datetime(2017, 5, 26, 17, 00)),
mdates.date2num(datetime(2017, 5, 26, 18, 00)),
mdates.date2num(datetime(2017, 5, 26, 19, 00)),
mdates.date2num(datetime(2017, 5, 26, 20, 00)),
mdates.date2num(datetime(2017, 5, 26, 21, 00)),
mdates.date2num(datetime(2017, 5, 26, 22, 00)),
mdates.date2num(datetime(2017, 5, 26, 23, 00))
]

# Assign the data, change fonts to Bebas Neue, make titles and labels
ax.set_xticklabels(labels, fontname="Bebas Neue")
ax.set_yticklabels([int(i) for i in ax.get_yticks()], fontname="Bebas Neue")

ax.set_title("Title", fontsize=22, fontname="Bebas Neue")
ax.set_xlabel("Time of Day", fontsize=14, fontname="Bebas Neue")
ax.set_xticks(locs)

# Make nicer x axis
plt.gcf().autofmt_xdate()

# Export that shit
ax.grid()
plt.draw()
plt.savefig("figure.png", format='png', dpi=280)

if __name__ == "__main__":
main()


One of the most frustrating things to deal with is trailing whitespace. Trailing whitespace is such a pain because:

• It can screw up string literals
• It can break expectations in a text editor (i.e. jumping to a new line or the end of the line)
• It can actually break programming languages
• It is just unflattering

However, in Vim, it takes one autocmd to alleviate this.

augroup spaces
autocmd!
autocmd BufWritePre * %s/\s\+\$//e
augroup END


On every buffer save substitute spaces at the end of the line with nothing. Easy!

I was always curious as to what my heart rate would be during an exam, so I decided to test it. Armed with my Apple Watch and a two-hour Differential Equations (DiffEq) final, I tested it.

Here are the results (click to enlarge).

There were four major milestones to bring out.

• Start Exam Well, I start the exam.
• Through Exam I don't generally do entire problems at once, but find a good stopping point, move on, and come back to double check everything.
• Finish Exam I finished all the problems.
• First Review I generally review twice, and this is where I finished the first review.
• Leave Exam I Finished the second review and I'm going back to bed.

The interesting parts were the spikes, and those were generally problems I was either stumped on, or had hoped they would not be on the exam.

The graph was produced via matplotlib. You can find the source code below.

#!/usr/local/bin/python3
#
# plot.py
# Desktop
#
# Created by Illya Starikov on 05/16/17.
#

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime

import csv

def import_from_csv(filename):
with open(filename, "rt") as csvfile:

date_times = []
values = []

for date_and_time_string, value in csv_parsor:
datetime_object = datetime.strptime(date_and_time_string, '%Y-%m-%d %H:%M:%S')

date_times += [datetime_object]
values += [value]

return (date_times, values)

def main():
# Get the data and the subplots
x, y = import_from_csv('data.csv')
fig, ax = plt.subplots()

# Make the figure wide and draw it
fig.set_size_inches((12, 5))
ax.plot_date(x, y, color='r', marker='x', markersize=6)

# Custom labels, since I have milestones
labels = ["Start Exam", "", "10:15", "", "Through Exam", "10:45", "11:00", "Finish Exam", "", "11:30", "First Review", "Leave Exam", "12:00", "12:15"]

locs = [
mdates.date2num(datetime(2017, 5, 10, 10, 00)),
mdates.date2num(datetime(2017, 5, 10, 10, 00)),
mdates.date2num(datetime(2017, 5, 10, 10, 15)),
mdates.date2num(datetime(2017, 5, 10, 10, 30)),
mdates.date2num(datetime(2017, 5, 10, 10, 30)),
mdates.date2num(datetime(2017, 5, 10, 10, 45)),
mdates.date2num(datetime(2017, 5, 10, 11, 00)),
mdates.date2num(datetime(2017, 5, 10, 11, 13)),
mdates.date2num(datetime(2017, 5, 10, 11, 15)),
mdates.date2num(datetime(2017, 5, 10, 11, 30)),
mdates.date2num(datetime(2017, 5, 10, 11, 35)),
mdates.date2num(datetime(2017, 5, 10, 11, 45)),
mdates.date2num(datetime(2017, 5, 10, 11, 48)),
mdates.date2num(datetime(2017, 5, 10, 12, 00)),
]

# Assign the data, change fonts to Bebas Neue, make titles and labels
ax.set_xticklabels(labels, fontname="Bebas Neue")
ax.set_yticklabels([int(i) for i in ax.get_yticks()], fontname="Bebas Neue")
ax.set_xticks(locs)

ax.set_title("Heart Rate vs. DiffEq Exam", fontsize=22, fontname="Bebas Neue")
ax.set_ylabel("Heart Rate (BPM)", fontsize=14, fontname="Bebas Neue")
ax.set_xlabel("Time", fontsize=14, fontname="Bebas Neue")

# Make nicer x axis
plt.gcf().autofmt_xdate()

# Export that shit
ax.grid()
plt.draw()
plt.savefig("figure.png", format='png', dpi=280)

if __name__ == "__main__":
main()


I recently gave a lecture over C++11 and C++14 to an introductory programming course. This briefly covers auto, lambda expressions, constexprs, and the default and deleted keywords. My lecture notes can be found here (alternatively, under projects).

Since reading about its faults in The Not So Short Introduction to LaTeX (highly recommended read), I have avidly stayed away form eqnarray. However, I feel as if the book didn’t covey the ideas as well as it should; also, it suggestion was IEEEeqnarray, apposed to the classically recommended align. This article on TeX User Groups conveys ideas more eloquently and provides better alternatives.