mscroggs.co.uk
mscroggs.co.uk

subscribe

Blog

Archive

Show me a Random Blog Post
 2017 
 2016 
 2015 
 2014 
 2013 
 2012 

Tags

folding paper folding tube maps london underground platonic solids rhombicuboctahedron raspberry pi weather station programming python php news royal baby probability game show probability christmas flexagons frobel coins reuleaux polygons countdown football world cup sport stickers tennis braiding craft wool emf camp people maths trigonometry logic propositional calculus twitter mathslogicbot oeis pac-man graph theory video games games chalkdust magazine menace machine learning javascript martin gardner reddit national lottery rugby puzzles advent game of life dragon curves fractals pythagoras geometry triangles european cup dates palindromes chalkdust christmas card bubble bobble asteroids final fantasy curvature binary arithmetic bodmas statistics error bars estimation accuracy misleading statistics

Archive

Show me a Random Blog Post
▼ show ▼
 2015-08-29 08:48:00 

How OEISbot Works

A few weeks ago, I made OEISbot, a Reddit bot which posts information whenever an OEIS sequence is mentioned.
This post explaind how OEISbot works. The full code can be found on GitHub.

Getting Started

OEISbot is made in Python using PRAW (Python Reddit Api Wrapper). PRAW can be installed with:
pip install praw
Before making a bot, you will need to make a Reddit account for your bot, create a Reddit app and obtain API keys. This python script can be used to obtain the necessary keys.
Once you have your API keys saved in your praw.ini file, you are ready to make a bot.

Writing the Bot

First, the necessary imports are made.
import praw
import re
import urllib
import json
from praw.objects import MoreComments
To prevent OEISbot from posting multiple links to the same sequence in a thread, a list of all the sequences which have been linked to is loaded.
with open("/home/pi/OEIS/seen") as f:
    seen = json.load(f)
Next, OEISbot logs into Reddit.
r = praw.Reddit('OEIS link and description poster by /u/mscroggs.')

access_i = r.refresh_access_information(refresh_token=r.refresh_token)
r.set_access_credentials(**access_i)

auth = r.get_me()
The subs which OEISbot will search through are listed. I have used all the math(s) subs which I know about, as these will be the ones mentioning sequences.
subs = ['math','mathpuzzles','casualmath','theydidthemath',
        'learnmath','mathbooks','cheatatmathhomework','matheducation',
        'puremathematics','mathpics','mathriddles','askmath']
The markup function loads the necessary information from OEIS and formats it. Each comment will end with the output of the me function. The ouput of joiner will be used between sequences which are mentioned.
def markup(seq_n):
    pattern = re.compile("%N (.*?)<",re.DOTALL|re.M)
    desc=urllib.urlopen("http://oeis.org/A"+seq_n+"/internal").read()
    desc=pattern.findall(desc)[0].strip("\n")
    pattern = re.compile("%S (.*?)<",re.DOTALL|re.M)
    seq=urllib.urlopen("http://oeis.org/A"+seq_n+"/internal").read()
    seq=pattern.findall(seq)[0].strip("\n")
    new_com = "[A"+seq_n+"](http://oeis.org/A"+seq_n+"/): "
    new_com += desc+"\n\n"
    new_com += seq+"..."
    return new_com

def me():
    return "I am OEISbot. I was programmed by /u/mscroggs. [How I work](http://mscroggs.co.uk/blog/20)."

def joiner():
    return "\n\n- - - -\n\n"
For each sub OEISbot is monitoring, the hottest 10 posts are searched through for mentions of sequences. If a mention is found, a reply is generated and posted.
for sub in subs:
    subreddit = r.get_subreddit(sub)
    for submission in subreddit.get_hot(limit = 10):
        try:
            seen[submission.id]
        except KeyError:
            seen[submission.id] = []
        re_s = re.findall("A([0-9]{6})",submission.title)
        re_s += re.findall("oeis\.org/A([0-9]{6})",submission.url)
        post_me = []
        for seq_n in re_s:
            if seq_n not in seen[submission.id]:
                post_me.append(markup(seq_n))
                seen[submission.id].append(seq_n)
        if len(post_me)>0:
            post_me.append(me())
            submission.add_comment(joiner().join(post_me))
            break
        flat_comments = praw.helpers.flatten_tree(submission.comments)
        for comment in flat_comments:
            if not isinstance(comment,MoreComments) and comment.author is not None and comment.author.name != "OEISbot":
                re_s = re.findall("A([0-9]{6})",comment.body)
                post_me = []
                for seq_n in re_s:
                    if seq_n not in seen[submission.id]:
                        post_me.append(markup(seq_n))
                        seen[submission.id].append(seq_n)
                if len(post_me)>0:
                    post_me.append(me())
                    comment.reply(joiner().join(post_me))
                    break
        else:
            continue
        break
    else:
        continue
    break
The list of sequences which have been posted in each thread is saved to prevent duplication later.
with open("/home/pi/OEIS/seen","w") as f:
    json.dump(seen,f)

Running the Code

I put this script on a Raspberry Pi which runs it every 10 minutes (to prevent OEISbot from getting refusals for posting too often). This is achieved with a cron job.
*/10 * * * * python /path/to/bot.py

Making Your Own Bot

The full OEISbot code is available on GitHub. Feel free to use it as a starting point to make your own bot! If your bot is successful, let me know about it in the comments below or on Twitter.

Similar Posts

Logical Contradictions
Logic Bot, pt. 2
Logic Bot
Raspberry Pi Weather Station

Comments

Comments in green were written by me. Comments in blue were not written by me.
 Add a Comment 


I will only use your email address to reply to your comment (if a reply is needed).

To prove you are not a spam bot, please type "k" then "e" then "y" in the box below (case sensitive):
© Matthew Scroggs 2017