Shopping made easy with RPushbullet

Recently Dirk Eddelbuettel released the new R package RPushbullet to allow for pushing via pushbullet from R. This package is great if you want to know when some long slow running model has finished going through all the loops etc.. However, recently I have been trying to buy new forks for my mountain bike off a fourm over on single track. The great thing about single track sales is the price but there is one slight problem. People generally get in quick and snap up the bargins well before I get a chance. This is where RPushbullet comes in to save me.

By combining the XML, stringr and the RPushBullet packages I can download the titles of all the recent posts and search for the key word of the shocks I want. If the script finds anything interesting it will push it to my phone using RPushbullet.

The script is below. It also includes a log of post titles that have already been sent to my phone to ensure I don’t get flooded repetitively.

# Load the required packages
library(XML)
library(RPushbullet)
library(stringr)
# Check to see if there is a log file on the system and load it.
if(sum(str_detect(dir("/Users/USERNAME/"), "singletrack.Rdata"))==0){
  log <- ""
} else {
  load("/Users/USERNAME/singletrack.Rdata")
}
# assign the forums url
theurl <- "http://singletrackworld.com/forum/forum/classifieds"
# rip the forum titles as a table
tables <- readHTMLTable(theurl)
# reformat the table structure
post_titles <- as.character(tables[[1]][,1])
 
# Create an index of posts that match what I am after
index <- str_detect(tolower(post_titles), "rockshox")
if(sum(index)&gt;0){
  # Subset the posts that match the keyword
  posts <- (1:length(index))[index==1]
  # Loop through the matches and check to see if they are in the log. 
  # if not then push it to the phone, and add it to the log file.
  for(i in posts){
    if(!any(str_detect(tolower(log), tolower(post_titles[i])))){
      log <- c(log, tolower(post_titles[i]))
      pbPost("link", post_titles[i], url="http://singletrackworld.com/forum/forum/classifieds")
    }
  }
 # Update the log file for the next round. 
  save(log, file="/Users/USERNAME/singletrack.Rdata")
}

With the script completed and saved as something like searchSingleTrack.R I can now use crontab on my mac to get the script to run every 30 minutes. I didn’t have any previous crontab jobs up and running so I had to set everything up from scratch. This is all fairly easy stuff. In a terminal window:

bash sudo touch /etc/crontab crontab -e

This will open up the crontab file. Within this you need to add the following (press i [for insert]):

bash 0,30 * * * * Rscript /Users/USERNAME/searchSingleTrack.R

That should be it (press ESC then :w [for write] then :q [for quit]). The R script will now automatically check the forum every 30 minutes and if it finds anything push it to my phone.

First play with the matbotix sonar sensor

Today, I finally got to the local electric store before they had closed. I had to get a soldiering iron and some pcb headers. I soldiered the headers to the sonar sensor, and plugged it into my breadboard. This setup is very nasty at the moment, but i wanted to know if this was going to work for me. I have been doing a little reading and found a few useful links. The code from the playground site; MaxSensor. There is some good info in this forum from a matbotix rep about filtering the output from the sensor.

//Feel free to use this code.
//Please be respectful by acknowledging the author in the code if you use or modify it.
//Author: Bruce Allen
//Date: 23/07/09

//Digital pin 7 for reading in the pulse width from the MaxSonar device.
//This variable is a constant because the pin will not change throughout execution of this code.
const int pwPin = 7; 
//variables needed to store values
long pulse, cm;
void setup() {
  //This opens up a serial connection to shoot the results back to the PC console
  Serial.begin(9600);
}
void loop() {
  pinMode(pwPin, INPUT);

  pulse = pulseIn(pwPin, HIGH);
  cm = pulse/58;
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  delay(500);
}

For loops in cpp. A Rcpp example

This blog shows a quick example of a for loop, using c++ syntax. The function loops over the inputted data and returns the results to R. The code is not the best, however it highlights how data can be taken into and taken out the c++ environment.

src<-'
//Get the R data into Rcpp format
NumericVector input(vecIn); //This is a pointer from my understanding.
 
//Create an integer for the size of the inputted vector
int input_n;
//Set the size of the vector to the integer
input_n = input.size();
 
//Create a Vector for output of the size of input.
NumericVector output(input_n);
 
for(int i=0;i<input_n;i++){
  output(i) = input(i)/2;	
}
//The wrap function is a lazy method to get the results back to R.
return wrap(output);
'
 
simpleForloop <- cxxfunction(signature(vecIn ="numeirc"),src,plugin="Rcpp")
 
simpleForloop(c(1,2,3))

In R a for loop is easy to write;

x <- c(1, 2, 3)
for(i in 1:length(x)){
  print(x[i])
}
## [1] 1
## [1] 2
## [1] 3

This loop assigns i as 1 and loops through from 1 to the length of x. In c++ this is formatted differently. One must declare the object (int i=0), The indexing of objects in c++ starts at 0 unlike R. The condition to stop the loop (i<x.size()) must be provided, and set the increment by which i increase (i++). i++ is a fast and easy way to write i=i+1, and is often used in c++ code. The c++ version of the aove for loop becomes;

for ( int i = 0; i < x.size(); i++){
}