Open a New Tab in Terminal.app in the Same Directory on Mac OS X

When working with Rails on my Mac OS X machine, I often find myself opening a lot of terminal tabs. Unfortunately I then need to navigate to the same directory as the other tabs. It’s a big pain. Fortunately superuser.com has a solution.

Create a new file in “/usr/local/bin” named “nt”

#!/bin/bash
osascript -e 'tell application "Terminal"' \
-e 'tell application "System Events" to tell process "Terminal" to keystroke "t" using command down' \
-e "do script with command \"cd `pwd`;clear\" in selected tab of the front window" \
-e 'end tell' &> /dev/null

Then set its executable bit. “chmod +x /usr/local/bin/nt”

That’s it!

Advertisement:
Make Git simple. Let Gitpilot show you the right way to Git things done. Gitpilot will help you write software faster.

Installing MongoDB 1.8.1 on Ubuntu 10.04 LTS

A lot of this information will seem obvious to a lot of you. But it did require me to perform a few Google searches, so hopefully I can save you the trouble.

I provide a script to automate this process:

This script is deprecated now. Fortunately 10Gen (the company who makes MongoDB) provides an Apt repository. Do not use the current MongoDB version in the Ubuntu apt sources. It’s version 1.6.*

All you need to do:

vim /etc/apt/sources.list

Add the following line:
deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen


apt-get update
apt-get install mongodb-10gen

By default MongoDB runs in trusted mode. This means that it’s listening on port 27017 for any connection. We want it to only listen on localhost.

Edit the file: /etc/mongodb.conf

Add the following lines:
bind_ip 127.0.0.1
noauth = true ##### YOU MUST add this line if you use bind_ip

Are you a Git user? Let me help you make project management with Git simple. Checkout Gitpilot.

That’s it. Follow me on Twitter: @jprichardson and read my blog on software entrepreneurship.

-JP

Linear Regression in C#/.NET Using Least Squares

I had a class that handled the regression of my data sets, but it had too many business rules. It was necessary for me to refactor the code.

Here’s how you can use it:

double[] X = { 75.0, 83, 85, 85, 92, 97, 99 };
double[] Y = { 16.0, 20, 25, 27, 32, 48, 48 };
var ds = new XYDataSet(X, Y);

Console.WriteLine(Math.Round(ds.Slope,2)); //1.45
Console.WriteLine(Math.Round(ds.YIntercept,2)); //-96.85
ConsoleWriteLine(Math.Round(ds.ComputeRSquared(), 3)); //0.927

The source is in my .NET CommonLib library.
XYDataSet.cs: https://github.com/jprichardson/CommonLib/blob/master/CommonLib/Numerical/XYDataSet.cs
XYDataSetTest.cs: https://github.com/jprichardson/CommonLib/blob/master/TestCommonLib/Numerical/XYDataSetTest.cs

Here is the source for XYDataSet.cs:

using System;
using System.Collections.Generic;
using System.Collections;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using CommonLib.Geometry;

namespace CommonLib.Numerical
{
	public class XYDataSet : IList<PointD>
	{
		
		private List<PointD> _internalList = new List<PointD>();

		public XYDataSet() : this(null, null) { }

		public XYDataSet(IEnumerable<PointD> points) {
			ResetValues();

			foreach (var point in points)
				Add(point);
		}

		public XYDataSet(IEnumerable<double> Xs, IEnumerable<double> Ys) {
			ResetValues();
			
			if (Xs != null || Ys != null) {
				if (Xs.Count() != Ys.Count())
					throw new Exception("X count must be the same as the Y count.");

				for (int i = 0; i < Xs.Count(); ++i)
					Add(Xs.ElementAt(i), Ys.ElementAt(i));
			}
		}

		public int Count { get { return _internalList.Count; } }

		public bool IsReadOnly { get { return false; } }

		private double _maxX = Double.NegativeInfinity;
		public double XMax { get { return _internalList[XMaxIndex].X; } }
		private double _minX = Double.PositiveInfinity;
		public double XMin { get { return _internalList[XMinIndex].X; } }
		public int XMaxIndex { get; protected set; }
		public int XMinIndex { get; protected set; }

		private double _maxY = Double.NegativeInfinity;
		public double YMax { get { return _internalList[YMaxIndex].Y; } }
		private double _minY = Double.PositiveInfinity;
		public double YMin { get { return _internalList[YMinIndex].Y; } }
		public int YMaxIndex { get; protected set; }
		public int YMinIndex { get; protected set; }

		public double XMean { get { return XSum / Count; } }
		public double YMean { get { return YSum / Count; } }

		public double RSquare { get; protected set; }

		public PointD RegressionPoint0 { get; protected set; }
		public PointD RegressionPointN { get; protected set; }

		public double Slope { get; protected set; }

		public double XSum { get; set; }
		public double YSum { get; set; }
		public double XSquaredSum { get; set; }
		public double XYProductSum { get; set; }

		public double XIntercept { get { return -YIntercept / Slope; } }
		public double YIntercept { get; protected set; }


		public PointD this[int index] {
			get { return _internalList[index]; }
			set {
				var p = value;
				var old = _internalList[index];
				_internalList[index] = p;

				ComputeSums(old, SumMode.Subtract);
				ComputeSums(p, SumMode.Add);
				ComputeMinAndMax();
				ComputeSlopeAndYIntercept();
			}
		}

		public void Add(double x, double y) {
			Add(new PointD(x, y));
		}

		public void Add(PointD p) {
			_internalList.Add(p);
			RSquare = double.NaN;

			ComputeSums(p, SumMode.Add);
			ComputeMinAndMax(Count - 1, p);
			ComputeSlopeAndYIntercept();
		}

		public void Clear() {
			_internalList.Clear();
			ResetValues();
		}

		public void ComputeSlopeAndYIntercept() {
			double delta = Count * XSquaredSum - Math.Pow(XSum, 2.0);
			YIntercept = (1.0 / delta) * (XSquaredSum * YSum - XSum * XYProductSum);
			Slope = (1.0 / delta) * (Count * XYProductSum - XSum * YSum);

			RegressionPoint0.X = XMin;
			RegressionPoint0.Y = Slope * XMin + YIntercept;
			RegressionPointN.X = XMax;
			RegressionPointN.Y = Slope * XMax + YIntercept;
		}

		public double ComputeRSquared() {
			var SStot = _internalList.Sum(p => Math.Pow(p.Y - YMean, 2.0));
			var SSerr = _internalList.Sum(p => Math.Pow(p.Y - (Slope * p.X + YIntercept), 2.0));
			RSquare = 1.0 - SSerr / SStot;
			return RSquare;
		}

		public bool Contains(PointD p) {
			return _internalList.Contains(p);
		}

		public void CopyTo(PointD[] points, int index) {
			_internalList.CopyTo(points, index);
		}

		public IEnumerator<PointD> GetEnumerator() {
			return _internalList.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator() {
			return _internalList.GetEnumerator();
		}

		public int IndexOf(PointD p) {
			return _internalList.IndexOf(p);
		}

		public void Insert(int index, PointD p) {
			_internalList.Insert(index, p);
			RSquare = double.NaN;

			ComputeSums(p, SumMode.Add);
			ComputeMinAndMax();
			ComputeSlopeAndYIntercept();
		}

		public bool Remove(PointD p) {
			var success = _internalList.Remove(p);
			if (success) {
				RSquare = double.NaN;
				ComputeSums(p, SumMode.Subtract);
				ComputeMinAndMax();
				ComputeSlopeAndYIntercept();
			}
			return success;
		}

		public void RemoveAt(int index) {
			var old = _internalList[index];
			_internalList.RemoveAt(index);
			RSquare = double.NaN;

			ComputeSums(old, SumMode.Subtract);
			ComputeMinAndMax();
			ComputeSlopeAndYIntercept();
		}

		protected void ComputeMinAndMax() { //methods that call this, Insert, 
			ResetMinAndMax();

			for (int i = 0; i < _internalList.Count; ++i)
				ComputeMinAndMax(i, _internalList[i]);
		}

		protected void ComputeMinAndMax(int index, PointD newPoint) {
			if (newPoint.X <= _minX) {
				_minX = newPoint.X;
				XMinIndex = index;
			}

			if (newPoint.X >= _maxX) {
				_maxX = newPoint.X;
				XMaxIndex = index;
			}

			if (newPoint.Y <= _minY) {
				_minY = newPoint.Y;
				YMinIndex = index;
			}

			if (newPoint.Y >= _maxY) {
				_maxY = newPoint.Y;
				YMaxIndex = index;
			}
		}

		protected enum SumMode { Add, Subtract };
		protected void ComputeSums(PointD p, SumMode mode) {
			if (mode == SumMode.Add) {
				XSum += p.X;
				YSum += p.Y;
				XSquaredSum += Math.Pow(p.X, 2.0);
				XYProductSum += (p.X * p.Y);
			}
			else if (mode == SumMode.Subtract) {
				XSum -= p.X;
				YSum -= p.Y;
				XSquaredSum -= Math.Pow(p.X, 2.0);
				XYProductSum -= (p.X * p.Y);
			}
		}

		protected void ResetMinAndMax() {
			_maxX = double.NegativeInfinity;
			_maxY = double.NegativeInfinity;
			_minX = double.PositiveInfinity;
			_minY = double.PositiveInfinity;
		}

		protected void ResetValues() {
			ResetMinAndMax();

			RegressionPoint0 = new PointD();
			RegressionPointN = new PointD();

			RSquare = double.NaN;

			Slope = double.NaN;
			YIntercept = double.NaN;

			XSum = 0.0;
			YSum = 0.0;
			XSquaredSum = 0.0;
			XYProductSum = 0.0;

			XMaxIndex = -1;
			YMaxIndex = -1;
			XMinIndex = -1;
			YMinIndex = -1;
		}
		
	}
}

Are you a Git user? Let me help you make project management with Git simple. Checkout Gitpilot.

Follow me on Twitter: @jprichardson and read my blog on software entrepreneurship: Techneur

-JP

Quick JSON Serialization/Deserialization in C#

*This outdated*. You should use FridayThe13th the best JSON parser for Silverlight and .NET 4.0.

You don’t need to download an additional libraryto serialize/deserialize your objects to/from JSON. Since .NET 3.5, .NET can do it natively.

Add a reference to your project to “System.Web.Extensions.dll”

Let’s look at this example JSON string:

{
	"some_number": 108.541, 
	"date_time": "2011-04-13T15:34:09Z", 
	"serial_number": "SN1234"
}

You can deserialize the previous JSON into a dictionary like so:

using System.Web.Script.Serialization;

var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<Dictionary<string,string>>(jsonText);

Console.WriteLine(dict["some_number"]); //outputs 108.541

So what if your JSON is a bit more complex?

{
	"some_number": 108.541, 
	"date_time": "2011-04-13T15:34:09Z", 
	"serial_number": "SN1234"
	"more_data": {
		"field1": 1.0
		"field2": "hello"	
	}
}

Deserialize like so…

using System.Web.Script.Serialization;

var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<Dictionary<string,dynamic>>(jsonText);

Console.WriteLine(dict["some_number"]); //outputs 108.541
Console.WriteLine(dict["more_data"]["field2"]); //outputs hello

The field “more_data” gets deserialized into a Dictionary<string, object>.

You can actually just just deserialize like so:

using System.Web.Script.Serialization;

var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<dynamic>(jsonText);

Console.WriteLine(dict["some_number"]); //outputs 108.541
Console.WriteLine(dict["more_data"]["field2"]); //outputs hello

And everything still works the same. The only caveat is that you lose intellisense by using the “dynamic” data type.

Serialization is just as easy:

using System.Web.Script.Serialization;

var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<dynamic>(jsonText);

var json = jss.Serialize(dict);
Console.WriteLine(json);

Outputs…

{
	"some_number": 108.541, 
	"date_time": "2011-04-13T15:34:09Z", 
	"serial_number": "SN1234"
	"more_data": {
		"field1": 1.0
		"field2": "hello"	
	}
}

Do you use Git? If so, checkout Gitpilot to make project management and collaborating on projects seamless.

If you made it this far, read my blog on software entrepreneurship and follow me on Twitter: @jprichardson.

-JP

locate and updatedb on OS X Snow Leopard

On Linux, I love using the “locate” utility. In essence, the locate utility works similar to the “find” utility but it’s much faster. This is because the locate utility works in conjunction with the “updatedb” utility. updatedb builds an indexed database of the file names, this is how locate runs so quickly.

I was stoked to find out that OS X has locate, but where is its partner in crime updatedb? Google to the rescue, djangrrl.com has the answer:

sudo /usr/libexec/locate.updatedb

Are you a Git user? Let me help you make project management with Git simple. Checkout Gitpilot.

Follow me on Twitter: @jprichardson and read my blog on entrepreneurship: Techneur.

-JP

Migrating from Tunnelblick on OS X to OpenVPN GUI Client on Windows

This was done on Windows 7. These same instructions should work for Windows Vista.

First install OpenVPN from the actual OpenVPN site here: http://openvpn.net/index.php/open-source/downloads.html You should use at least version 2.1.4. Do NOT install OpenVPN GUI from http://openvpn.se/ It contains an older version that does not work properly on Windows Vista or Windows 7.

Run the installer as Administrator.

You can copy all of the Tunnelblick OpenVPN files on your OS X in “~/Library/Application Support/Tunnelblick/Configurations/” to “C:\Program Files\OpenVPN\config\”. Change the file extension of all “*.conf” files to “.ovpn” The OpenVPN Client GUI software scans for “.opvn” files.

Run the OpenVPN GUI as Administrator. Once connected, look in the log file and verify that you do not see the following line:

ROUTE: route addition failed using CreateIpForwardEntry: One or more arguments are not correct.

If you see this, you didn’t install the version from openvpn.net or you didn’t run the GUI as Administrator.

Are you a Git user? Let me help you make project management with Git simple. Checkout Gitpilot.

You should follow me on Twitter: @jprichardson and read my blog on entrepreneurship.

-JP

DataGrid Not Found in Silverlight 4

I created a fresh new Silverlight 4 project. I opened up MainPage.xaml and started typing “DataGrid”… but intellisense didn’t show it.

I found out that I needed to add the following to the top of my Xaml file:

xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"

In then started showing up in intellisense. I tried to compile the simple app and I got an error out of the MainPage.g.i.cs file. The error is:

“The type or namespace name ‘DataGrid’ could not be found (are you missing a using directive or an assembly reference?)”

I opened up the Silverlight MSDN for the DataGrid control and found out that my DataGrid is in the System.Windows.Controls namespace and the System.Windows.Controls.Data assembly. I didn’t see it in my references tree, so I tried to add a .NET reference. Unfortunately, “System.Windows.Controls” or “System.Windows.Controls.Data” weren’t in the list.

It turns out that you need to navigate to the “Browse” tab in the “Add Reference Dialog” and then add the file “System.Windows.Controls.Data” which is typically found in “C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Libraries\Client”

Hope this helps someone.

Are you a Git user? Let me help you make project management with Git simple. Checkout Gitpilot.

Follow me on Twitter: @jprichardson or read my blog on entrepreneurship: Techneur.

-JP

StreamWriter Share Read Access in Another Process

I have two applications, one is the main application that generates a log file, the other is an application that reads the log file to compute statistics.

I want my app that reads the log file to be able to read the file while the other app is running and generating the log file. If you just use the default StreamWriter and StreamReader constructors you will get a file access in error in one of the processes.

Log file generator: (1st process)

static void Main(string[] args) {
	var file = @"C:\logfile.txt";
	var sw = new StreamWriter(file);
	sw.AutoFlush = true;
	sw.WriteLine("some data");
	sw.WriteLine("some data2"); //set breakpoint here
	
	sw.Close();
}

Log file reader: (2nd process)

static void Main(string[] args) {
	var file = @"C:\logfile.txt";
	var sr = new StreamReader(file);

	var l1 = sr.ReadLine();
	var l2 = sr.ReadLine(); //set breakpoint here

	sr.Close();
}

Startup the “log file generator” app and then startup the “log file reader” app, you’ll get an IOException.
Here’s how you can fix this:

Log file generator: (1st process)

static void Main(string[] args) {
	var file = @"C:\logfile.txt";
	var fs = File.Open(file, FileMode.Append, FileAccess.Write, FileShare.Read);
	var sw = new StreamWriter(fs);
	sw.AutoFlush = true;
	sw.WriteLine("some data");
	sw.WriteLine("some data2"); //set breakpoint here
	
	sw.Close();
}

Log file reader: (2nd process)

static void Main(string[] args) {
	var file = @"C:\logfile.txt";
	var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
	var sr = new StreamReader(fs);

	var l1 = sr.ReadLine();
	var l2 = sr.ReadLine(); //set breakpoint here

	sr.Close();
}

You’ll notice that the breakpoint on the 2nd process will now work without getting an IOException. In short this works because the FileShare permissions are set properly. You can also read more about the enum FileMode.

Are you a Git user? Let me help you make project management with Git simple. Checkout Gitpilot.

Follow me on Twitter: @jprichardson and read my blog on entrepreneurship.

-JP

WPF Application Wide Exception Handling

What do you do if you want to catch all unhandled exceptions in an application?

In App.xaml:

<Application x:Class="MyApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DispatcherUnhandledException="UnhandledException"
>

Add “DispatcherUnhandledException” to App.xaml. Then in your App.xaml.cs file:

private void UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) {
	var time = DateTime.Now;
	File.AppendAllText(@"C:\exps.csv", string.Format("{0},{1}", time, e.Exception.Message));
	File.AppendAllText(@"C:\sts.txt", time + ":\n" + e.Exception.StackTrace + "\n");
	e.Handled = false; //we want the user to experience the crash
}

That’s it. So now if the app crashes on your users, you don’t have to ask your users what steps they did to cause the crash. You can just look at the logs!

Are you a Git user? Let me help you make project management with Git simple. Checkout Gitpilot.

Follow me on Twitter @jprichardson or read my blog on software entrepreneurship.

-JP

Feedzirra and Rails 3

Feedzirra is probably one of the best Ruby RSS parsers. But if you’re using it with Rails 3, you may get an error message like so:

no such file to load -- active_support/core_ext/time

If that happens, locate your feedzirra.rb file on your machine and comment out the lines:

#require 'active_support/core_ext/object'
#require 'active_support/core_ext/time'

Add these lines:
require 'active_support/core_ext'
require 'active_support/time'

Are you a Git user? Let me help you make project management with Git simple. Checkout Gitpilot.

Follow me on Twitter @jprichardson and read my blog on building a software business.

Follow

Get every new post delivered to your Inbox.