Thursday, November 10, 2011

Using boost's replace_all_regex_copy


#include <iostream>
#include <string>
#include <algorithm>
#include "boost/algorithm/string/regex.hpp"

using namespace std;

int main(void) {
string orig_str="FUBAR";
boost::regex re("UBA");
std::string replacement="ooba";
string result = boost::algorithm::replace_all_regex_copy(
orig_str,re,replacement);
cout << result << endl;
return 0;
}

Yields:

FoobaR

Saturday, July 16, 2011

Tabata Protocol Soundtrack MP3

I've recently become interested in the Tabata Protocol ( See 1, 2, and 3.) I tried to use a number of Tabata Protocol apps in Android, but all the apps I tried required the Android phone to not be in locked screen mode. If you are in locked screen mode, then these apps won't properly tell you when to start and stop running. If you're running while holding an Android phone, you clearly need to be able to lock the screen, otherwise your grip on the phone will punch all sorts of buttons or turn off the app.


What about the tried and true method? The mp3. Thankfully, you can play an mp3 on an Android phone with the screen locked. Now, I couldn't just generate one mp3 manually in Audacity. I had to completely solve the problem for everyone who wants to create a timing or HIIT mp3 with any combination of starts and stops with any kind of spacing between them.


BEHOLD! The Tabata Protocol Soundtrack generator!


This little web page will generate a HIIT soundtrack or a Tabata Protocol soundtrack according to your specification. If you simply go to the page and click the generate button, you'll get the classic Tabata Protocol timing that Mr. Tabata himself used whilst doing his study.

Shoot me some feedback in the comments if you find it useful.

Friday, April 15, 2011

Python one-liner to convert hex numbers to decimal

A one-line to convert all hex numbers from standard in to decimal:


cat log | \
python -c 'import sys,re;[sys.stdout.write(re.sub("0x([a-fA-F0-9]+)",lambda m : str(int(m.group(0),16)),l)) for l in sys.stdin]'

Friday, November 12, 2010

How to automatically click ok on "Authentication Required" popup

Lately, I've been doing some web scraping automation. For the most part, I'm using Selenium, but Selenium doesn't seem to be able to automatically click "OK" when an authentication window pops up.

This python code, works with Redhat's Dogtail to auto-magically click "OK" button on an "Authentication Required" popup:

from dogtail import tree
from dogtail.utils import run
from time import sleep
from os import environ, path, remove
import sys
environ['LANG']='en_US.UTF-8'

#print tree.root.dump()
firefox = tree.root.application('Firefox')

#print firefox.dump()
#print dir(firefox)
#print firefox.findChildren()
auth_required = firefox.childNamed("Authentication Required")
#auth_required = firefox.child(name="Authentication Required")
ok_button = auth_required.childNamed("OK")
ok_button.click()
print 'ok button clicked now'
#print dir(ok_button)


NOTE:

Doing gui-automation this way may be a "bad idea", but I'm only doing this automation to scrape an internal webpage, and it only has to work on a very specific configuration -- Ubuntu 10.04 with Firefox.

Tuesday, November 2, 2010

Script to nuke specific onclick() behavior in Rally tool.

When you're editing your user stories in Rally the most irritating part is that you can't open all your stories in new tabs by holding down the ctrl key and clicking all the story links. The following greasemonkey script enables you to do that:


// Makes Rally tool do what it is supposed to.
// 2009.03.17, Ross Rogers
// Copyright (c) 2005, Mark Pilgrmim
// Released under the GPL license
// http://www.gnu.org/copyleft/gpl.html
//
// --------------------------------------------------------------------
//
// This is a Greasemonkey user script.
//
// To install, you need google's Chrome or
// Greasemonkey: https://addons.mozilla.org/en-US/firefox/addon/748
// Then restart Firefox and revisit this script.
// Under Tools, there will be a new menu item to "Install User Script".
// Accept the default configuration and install.
//
// To uninstall, go to Tools/Manage User Scripts,
// select "Hello World", and click Uninstall.
// --------------------------------------------------------------------
//
// ==UserScript==
// @name Rally Onclick Nuke
// @namespace http://diveintogreasemonkey.org/download/
// @description Nukes the "onclick" attribute from user story links so you can
// CTRL click a link and have it open in a new tab. Also creates
// "accesskey" shortcuts for Save (alt+a), "edit_tags" (alt+t),
// and "apply" button (alt+a)
// @include https://*rally.sp*
// @include https://*slm/ar/edit.sp*
// ==/UserScript==

function remove_story_onclicks() {

console.log("running remove_story_onclicks\n");
var links = document.getElementsByTagName("a");
for (i = 0; i < links.length; i++) {
var node = links[i];
var link = node.getAttribute("href");
var className = node.getAttribute("class");
var is_edit_button = (className && className.indexOf("sprite-edit") > -1);
if (is_edit_button) {
var newHref = node.getAttribute("onclick").replace(/.*popup\('([^']*?)'.*/, "$1");
node.setAttribute("href",newHref);
}
if (link && link.indexOf("slm/detail/ar/") > -1 ||
is_edit_button ) {
if (node.getAttribute("onclick")) {
node.removeAttribute("onclick");
console.log("removed attribute onclick\n");
}
}
}
var buttons = document.getElementsByTagName("button");
for (i = 0; i < buttons.length; i++) {
var button = buttons[i];
console.log("Iterating through buttons\n");
console.log(button.innerHTML);
if (button.innerHTML.match(/^Save$/) ) {
button.setAttribute("accesskey","s");
console.log("setting Save button's accesskey to 's'\n");
};
if (button.innerHTML.match(/^Apply$/) ) {
button.setAttribute("accesskey","a");
console.log("setting Apply button's accesskey to 'a'\n");
};
};

var edit_tags_link = document.getElementById("edit_tags");
if (edit_tags_link) {
edit_tags_link.setAttribute("accesskey","t");
console.log("setting edit_tags-link's accesskey to 't'\n");
};


}


// override onclicks everywhere
var links = document.links;
for (i = 0; i < links.length; i++) {
var node = links[i];
console.log(node.onclick);
if (node.getAttribute("onclick")) {
console.log("wrappering onclick\n");
var original_onclick = node.onclick;
function wrapper_onclick(e ) {
var ret = original_onclick(e);
remove_story_onclicks();
return ret;
}
node.onclick = wrapper_onclick;
}
}

remove_story_onclicks();
function document_onclick() {
console.log("document_onclick() called\n");
remove_story_onclicks.apply(this,arguments);
}
document.onclick=document_onclick;

To install this, put it in a file named rally_onclick_nuke.user.js, then load it in chrome by dragging the file onto the browser. It should ask you at the bottom of the page if you want to install the extension, and you press yes.

Thursday, September 18, 2008

How to debug environments in Unix or Linux

How to tkdiff two environments

This scenario occurs frequently:
Frank can run program Chutney Aggregator, but Bob cannot.

What differs between Frank's and Bob's environment variables such that Frank can run Chutney Aggregator and Bob cannot?

If you run the command env, your shell will dump out all the environment variables. e.g.

KDE_MULTIHEAD=false
SSH_AGENT_PID=5349
DM_CONTROL=/var/run/xdmctl
TERM=xterm
SHELL=/bin/bash
XDM_MANAGED=/var/run/xdmctl/xdmctl-:0,maysd,mayfn,sched,rsvd,method=classic
...


Unfortunately, if we were to compare the output of command env on Frank's and Bob's, it would be extremely tedious, because env seems to just dump the environment variable hash in whatever fashion it pleases.

In order to be able to compare the environments, we need to sort the output from env.

env | sort

COLORTERM=
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-aEV1NDyS2z,guid=c31c98d5c8ad88de33dbfa0046ec2f30
DESKTOP_SESSION=default
DISPLAY=:0.0
...


If we put the output of this one-liner into a file, we can use tkdiff to compare the Frank's and Bob's environments in a visual way.

Frank performs this command in his terminal:

 env | sort > ~/tmp.shell_env


Bob does the same command in his terminal:

 env | sort > ~/tmp.shell_env


Now, we can compare the two environments:

 tkdiff ~Frank/tmp.shell_env ~Bob/tmp.shell_env



I find that the above process determines will crack most environment issues.


How to import a different environment

In tcsh, if I have to copy another person's environment variable wholesale, you can use this one-liner to create a tcsh script from their env which you may then source in another environment in order to reproduce their issues.


env | sort | perl -ne 's/'"'"'/'"'"'"'"'"'"'"'"'/g; \
s/^([\w_]+)=(.*)/setenv \1 '"'"'\2'"'"'/; print $_' > ~/tmp
source ~/tmp



If you back up your environment in the same way and then iteratively load part of their environment ( binary search?) you can pin point the difference that causes 1 environment to succeed and another to fail.


Root-Causing an Environment Issue

If you do have an environment dump from a person who is able to successfully run the program that you want to run, then you can possibly determine the root cause of the issue by iteratively importing their environment and testing whether you are now able to run the program.

To start, make sure that the problem you're encountering is caused by environment variable issues. Back up your environment as a script which you can use to restore it.


 env | sort | perl -ne 's/'"'"'/'"'"'"'"'"'"'"'"'/g; \
s/^([\w_]+)=(.*)/setenv \1 '"'"'\2'"'"'/; print $_' > ~/my_env



Take the dump that the other person created from their environment and import all variables into your shell by creating a script from their environment per How to debug environments in Unix or Linux#How to import a different environment.

Import their environment by sourcing the script you created.


source ~/other_env



Run the program and see if it passes. If it does, you know that the root cause of your issues is the difference between your environment variables and the other person's environment variables.

Now comes the binary search part.

Restore your environment:


source ~/my_env



* Comment out the first half of the other person's environment script*. Then source

their modified environment script:


source ~/other_env



Run the program. If the program runs, then the environment variable that was causing the issue is in the 2nd half of the ~/other_env script. *You have just eliminated the first half of the script as the source of your environment problem!*

If the program doesn't run, the bad environment variable is in the 1st half of the ~/other_env script. *You have just eliminated the 2nd half of the script as the source of your environment problem!* Uncomment the first half of the script and comment out the 2nd half.

Keep repeating this process with the remaining un-commented sections of environment variables by restoring your environment ( source ~/my-env ) and smashing over your environment with different pieces of ~/other_env until you find the problem environment variable.
Tricks
Identifying and Removing Unused Variables with a 'one-liner'

Unused struct members can clutter and obfuscate Specman code. For the purpose of eliminating this annoyance I have created the following one-liner that may help you identify unused Specman members.

grep -i --perl-regex -h '^ *[a-zA-Z][\w_]+ *:.*;' *e |           \
grep -v var | \
perl -ne \
's/^ *//; \
s/([\w_]+).*/$1/; \
print "$_";' | \
sort -u | \
perl -ne \
'chomp; \
$ret_val = `grep -h $_ *e | \
grep -v --perl-regex '"'"'^\\s*$_\\s*:.*;'"'"' | \
grep -v --perl-regex '"'"'^\\s*keep\\s*(soft\\s*)?$_.*==.*'"'"'`; \
if( $ret_val =~m/^\s*$/ ) { \
print "$_\n"; \
}'

This little 'one-liner' will look through all the *e files in your current directory and look for all struct or unit members and then try to see if each of the members is used in any other code in the current directory.

Aliases

Aliases for the cshell.
diff_dirs  
Pull up tkdiff for each file that is different between two directories:

alias diff_dirs 'diff --brief "\!:1" "\!:2" |\\
perl -pne '"'"'if (m/([\w-_\.\/]+) +and +([\w-_\.\/]+) +differ/)\\
{ `tkdiff "$1" "$2"` ;}'"'"



svn_diff_dirs

tkdiff the current directory with what all files used to be

alias svn_diff_dirs 'svn status |\\
grep M | \\
perl -ne '"'"'s/^M *//; \\
chomp; \\
`tkdiff .svn/text-base/$_.svn-base $_`'"'"