#!/usr/bin/env python # coding: utf-8 # # Exploring Hackers News Posts # # Hacker News is a site started by the startup incubator Y Combinator, where user-submitted stories (known as "posts") are voted and commented upon, similar to reddit. Hacker News is extremely popular in technology and startup circles, and posts that make it to the top of Hacker News' listings can get hundreds of thousands of visitors as a result. # # You can find the data set here, but note that it has been reduced from almost 300,000 rows to approximately 20,000 rows by removing all submissions that did not receive any comments, and then randomly sampling from the remaining submissions. Below are descriptions of the columns: # # * id: The unique identifier from Hacker News for the post # * title: The title of the post # * url: The URL that the posts links to, if it the post has a URL # * num_points: The number of points the post acquired, calculated as the total number of upvotes minus the total number of downvotes # * num_comments: The number of comments that were made on the post # * author: The username of the person who submitted the post # * created_at: The date and time at which the post was submitted # # We're specifically interested in posts whose titles begin with either`Ask HN` or `Show HN`. Users submit `Ask HN` posts to ask the Hacker News community a specific question. # # Likewise, users submit `Show HN` posts to show the Hacker News community a project, product, or just generally something interesting. # # We'll compare these two types of posts to determine the following: # # * Do `Ask HN` or `Show HN` receive more comments on average? # * Do posts created at a certain time receive more comments on average? # # Intro # In[15]: # Read in the data. import csv file = open('hacker_news.csv') hn = list(csv.reader(file)) print(hn[:5]) # # Removing Headers from a List of Lists # In[16]: headers = hn[0] hn = hn[1:] print(headers) print(hn[:5]) # # Extracting Ask HN and Show HN Posts # # Now that we've removed the headers from hn, we're ready to filter our data. Since we're only concerned with post titles beginning with `Ask HN` or `Show HN`, we'll create new lists of lists containing just the data for those titles. # In[17]: ask_posts = [] show_posts =[] other_posts = [] for post in hn: title = post[1] if title.lower().startswith("ask hn"): ask_posts.append(post) elif title.lower().startswith("show hn"): show_posts.append(post) else: other_posts.append(post) print(len(ask_posts)) print(len(show_posts)) print(len(other_posts)) # # Calculating the Average Number of Comments for Ask HN and Show HN Posts # # Let's determine if ask posts or show posts receive more comments on average # In[18]: total_ask_comments = 0 for post in ask_posts: total_ask_comments += int(post[4]) avg_ask_comments = total_ask_comments / len(ask_posts) print(avg_ask_comments) total_show_comments = 0 for post in show_posts: total_show_comments += int(post[4]) avg_show_comments = total_show_comments / len(show_posts) print(avg_show_comments) # Ask posts in our sample receive around 14 comments on average, while show posts receive around 10. # # Finding the Amount of Ask Posts and Comments by Hour Created # # Since ask posts are more likely to receive comments, we'll focus our remaining analysis just on these posts. # # Next, we'll determine if ask posts created at a certain time are more likely to attract comments. We'll use the following steps to perform this analysis: # # 1. Calculate the amount of ask posts created in each hour of the day, along with the number of comments received. # 2. Calculate the average number of comments ask posts receive by hour created. # # In[19]: import datetime as dt result_list = [] for post in ask_posts: result_list.append( [post[6], int(post[4])] ) counts_by_hour = {} comments_by_hour = {} for row in result_list: date = row[0] comment = row[1] d_format = "%m/%d/%Y %H:%M" time = dt.datetime.strptime(date, d_format).strftime("%H") if time not in counts_by_hour: counts_by_hour[time] = 1 comments_by_hour[time] = comment else: counts_by_hour[time] += 1 comments_by_hour[time] += comment print(comments_by_hour) # # Calculating the Average Number of Comments for Ask HN Posts by Hour # In[20]: avg_by_hour = [] for hour in comments_by_hour: avg_by_hour.append([hour, comments_by_hour[hour] / counts_by_hour[hour]]) print(avg_by_hour) # # Sorting and Printing Values from a List of Lists # In[21]: swap_avg_by_hour = [] for row in avg_by_hour: swap_avg_by_hour.append([row[1], row[0]]) print(swap_avg_by_hour) print("\n") sorted_swap = sorted(swap_avg_by_hour, reverse = True) print(sorted_swap) print("\n") print("Top 5 Hours for Ask Posts Comments") for avg, hour in sorted_swap[:5]: time = dt.datetime.strptime(hour, "%H").strftime("%H:%M") print( "{}: {:.2f} average comments per post".format(time, avg)) # According to the documentation of the dataset, the timezone used is US Eastern Time. One should post around 3 pm est to have the greatest chance of receiving comments. # # Determine if show or ask posts receive more points on average # In[24]: total_ask_points = 0 for post in ask_posts: total_ask_points += int(post[3]) avg_ask_points = total_ask_points / len(ask_posts) print(avg_ask_points) total_show_points = 0 for post in show_posts: total_show_points += int(post[3]) avg_show_points = total_show_points / len(show_posts) print(avg_show_points) # Ask posts in our sample receive around 15 points on average, while show posts receive around 27.5. # # Determine if posts created at a certain time are more likely to receive more points # In[33]: result_list_points = [] for post in show_posts: result_list_points.append( [post[6], int(post[3])] ) counts_by_hour_2 = {} points_by_hour = {} for row in result_list_points: date = row[0] points = row[1] d_format = "%m/%d/%Y %H:%M" time = dt.datetime.strptime(date, d_format).strftime("%H") if time not in counts_by_hour_2: counts_by_hour_2[time] = 1 points_by_hour[time] = points else: counts_by_hour_2[time] += 1 points_by_hour[time] += points print(points_by_hour) # In[34]: avg_points_by_hour = [] for hour in points_by_hour: avg_points_by_hour.append([hour, points_by_hour[hour] / counts_by_hour_2[hour]]) print(avg_points_by_hour) # In[35]: swap_avg_points_by_hour = [] for row in avg_points_by_hour: swap_avg_points_by_hour.append([row[1], row[0]]) print(swap_avg_points_by_hour) print("\n") sorted_swap_points = sorted(swap_avg_points_by_hour, reverse = True) print(sorted_swap_points) print("\n") print("Top 5 Hours for Show Posts Points") for avg, hour in sorted_swap_points[:5]: time = dt.datetime.strptime(hour, "%H").strftime("%H:%M") print( "{}: {:.2f} average points per post".format(time, avg)) # For show posts one should post around 11 pm est to have the greatest chance of receiving the most points.