Netflix whoas

It’s disappointing to see Netflix in it’s current state.  The luster that it once was just isn’t there anymore.  Perhaps it’s because when I first got it the content was new, the movies seemed good.  Now, I’ve seen all the good movies, new ones trickle in, but they are merely B-Quality.  I left Blockbuster in favor of this glorious creation of instant entertainment.  I should clarify that, as I do I have the DVD service but I’m too lazy to put them back in the mail box (damn you Netflix, you’ve known that all along haven’t you).

I’m still hopeful for this young pioneer in the streaming business.  I don’t really have much of a choice for another service though.  Competition would be nice, it would also justify the latest pricing increase (well not latest but still).  On top of that I heard that the deal with HBO and Showtime got canceled.  But they tag a deal with Dreamworks however the shows won’t be coming until 2012 or 2013, something like that.  I can honestly say I’m not entirely happy with the Streaming side of things.

I should also clarify that I view streaming on my X Box 360, if that has any effect on my viewing experience.

Posted in Uncategorized | Leave a comment

Make a Clicker Game with Canvas

HTML’s Canvas is pretty neat, and I’m learning more and more about it. One of the things I made real quickly was a little game where a circle randomly switches spots every second and you have to click on it as many times as you can.

Here’s what your making.

The first thing we need to do is is make sure we start out with a good doctype and xhtml markup.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" > 
<head>

Next we assign our public variables

var framerate = 1000;	//how fast the circle moves (in milliseconds)
var difficulty = 50;	//millisecond subtraction from framerate
var canvas = null;		//canvas element
var context = null;		//the acutal thing we're writing too
var score = null;		//score variable to track the.....score
var mouseX;				//the mouse's X location
var mouseY;				//the mouse's Y location

var oldCX = null;		//old value of circle's X value
var oldCY = null;		//old value of circle's Y value
var cX = null;			//The circles X location
var cY = null;			//The circles Y location

Next comes our initialization function that’s going to run when the page loads. Here we’re going to write to the canvas and context elements, and throughout the script we’re going to write to the context of the canvas element, and not the canvas element itself.

function init()
{
	canvas = document.getElementById("myCanvas");
	context = canvas.getContext("2d");
	runner();
}

init() also calls our next function, runner(). This will be the main function that will (Clear the Canvas, Draw the Objects, and finally run itself).

function runner()
{
	clearCanvas();
	drawObjects();
	setTimeout("runner()",framerate);
}

Next we want to draw the object of the circle to the screen

function drawObjects()
{
	cX = Math.floor(Math.random()*canvas.width);	//Random number between the width of the canvas
	cY = Math.floor(Math.random()*canvas.height);
	context.strokeStyle = "#000000";
	context.fillStyle = "#FFFF00";
	context.beginPath();							//tell it we're starting a path
	context.arc(cX,cY,50,0,Math.PI*2,false);		//arc(X,Y,radius,starting angle, ending angle, something else)
	context.closePath();							//finish the path call
	context.stroke();								//write the path to the context (ie canvas)
	context.fill();									//do our fill
}

And finally in our script we have our Score function, clearing of the canvas function, and our mouse handler functions (for movement, clicking, etc).

function updateScore()
{
	score += 1;
	document.getElementById("score").innerText = score;
	document.getElementById("speed").innerText = framerate;
}
function clearCanvas()
{
	context.clearRect(0,0,canvas.width,canvas.height);
	context.beginPath();
}
function handleMouseMove(event)
{
	mouseX = event.clientX - canvas.offsetLeft;
	mouseY = event.clientY - canvas.offsetTop;
}
function handleMouseOut(event)
{
	mouseX = null;
	mouseY = null;
}
function handleMouseClick(event)
{
	if (Math.abs(cX-mouseX) <= 50 &amp;amp;amp;amp;&amp;amp;amp;amp; Math.abs(cY-mouseY) <= 50 
		&amp;amp;amp;amp;&amp;amp;amp;amp; cX != oldCX &amp;amp;amp;amp;&amp;amp;amp;amp; cY != oldCY)
	{	
		oldCX = cX;
		oldCY = cY;
		updateScore();
		framerate-=difficulty;
	}
}
</script>

And our html, make sure you specify the width and height of canvas!

</head>
<body>
<body onload="init()">
<div id="score">0</div>
<div id="speed">Current Speed: 0</div>
<canvas id="myCanvas" width="400" height="400"		<!-- You MUST specify the width and height -->
	onmousemove="handleMouseMove(event)"
	onmouseout="handleMouseOut(event)"
	onclick="handleMouseClick(event)"
/>

</body>
</html>

And here it is all together:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" > 
<head>
<script>
var framerate = 1000;	//how fast the circle moves (in milliseconds)
var difficulty = 50;	//millisecond subtraction from framerate
var canvas = null;		//canvas element
var context = null;		//the acutal thing we're writing too
var score = null;		//score variable to track the.....score
var mouseX;				//the mouse's X location
var mouseY;				//the mouse's Y location

var oldCX = null;		//old value of circle's X value
var oldCY = null;		//old value of circle's Y value
var cX = null;			//The circles X location
var cY = null;			//The circles Y location

function init()
{
	canvas = document.getElementById("myCanvas");
	context = canvas.getContext("2d");
	runner();
}
function runner()
{
	clearCanvas();
	drawObjects();
	setTimeout("runner()",framerate);
}
function drawObjects()
{
	cX = Math.floor(Math.random()*canvas.width);	//Random number between the width of the canvas
	cY = Math.floor(Math.random()*canvas.height);
	context.strokeStyle = "#000000";
	context.fillStyle = "#FFFF00";
	context.beginPath();							//tell it we're starting a path
	context.arc(cX,cY,50,0,Math.PI*2,false);		//arc(X,Y,radius,starting angle, ending angle, something else)
	context.closePath();							//finish the path call
	context.stroke();								//write the path to the context (ie canvas)
	context.fill();									//do our fill
}
function updateScore()
{
	score += 1;
	document.getElementById("score").innerText = score;
	document.getElementById("speed").innerText = framerate;
}
function clearCanvas()
{
	context.clearRect(0,0,canvas.width,canvas.height);
	context.beginPath();
}
function handleMouseMove(event)
{
	mouseX = event.clientX - canvas.offsetLeft;
	mouseY = event.clientY - canvas.offsetTop;
}
function handleMouseOut(event)
{
	mouseX = null;
	mouseY = null;
}
function handleMouseClick(event)
{
	if (Math.abs(cX-mouseX) <= 50 && Math.abs(cY-mouseY) <= 50 
		&& cX != oldCX && cY != oldCY)
	{	
		oldCX = cX;
		oldCY = cY;
		updateScore();
		framerate-=difficulty;
	}
}
</script>
</head>
<body>
<body onload="init()">
<div id="score">0</div>
<div id="speed">Current Speed: 0</div>
<canvas id="myCanvas" width="400" height="400"		<!-- You MUST specify the width and height -->
	onmousemove="handleMouseMove(event)"
	onmouseout="handleMouseOut(event)"
	onclick="handleMouseClick(event)"
/>

</body>
</html>
Posted in JavaScript | Leave a comment

Staffing Calculator in Javascript

So you wanna use the ErlangC formula to see how much staff you need? Or you wanna build a workforce management program, well here’s module to do that:

CallDuration = 4;
IntervalLength = 60;
Agents = 0;
Calls = 0;

function OptimalStaff(daCalls, idealImmediateAnswer)
{
	i = 0;
	Calls=daCalls;
	for (i=0;i<=500;i++)
	{
		Agents = i;
		if (ImmediateAnswer() > idealImmediateAnswer)
		{			
			return i - 1;
		}
	}	
}
function AverageSpeedOfAnswer()
{
	return Math.round((ErlangC() * (CallDuration * 60) / (Agents * (1 - AgentOccupancy())))*100)/100;
}
function ImmediateAnswer()
{
	return Math.round(( 1 - ErlangC() * 100 )*100)/100;
}
function ErlangC()
{
	return Poisson(Agents, TrafficIntensity()) / (Poisson(Agents, TrafficIntensity()) + (1 - AgentOccupancy()) * PoissonCumul(Agents - 1, TrafficIntensity()));
}
function TrafficIntensity()
{
	return (Calls / (IntervalLength * 60)) * (CallDuration * 60);
}
function AgentOccupancy()
{
	return TrafficIntensity() / Agents;
}
function Poisson(IdealSuccesses, TheMean)
{
	Numerator = 0;
	Denominator = 0;
	if (IdealSuccesses <= 0)
	{ 
		return 0 
	} else {
		Numerator = Math.pow(TheMean, IdealSuccesses) * (Math.pow(Math.E, (TheMean * -1)));
		Denominator = Factorial(IdealSuccesses);
		return Numerator / Denominator;
	}
}
function PoissonCumul(IdealSuccesses, TheMean)
{
	daReturn = 0;
	i = 0;
	for (i=0;i<=IdealSuccesses;i++)
	{
		daReturn = daReturn + Poisson(i, TheMean);
	}
	return daReturn;
}
function Factorial(Input)
{
	if (Input == 0)
	{
		return 1
	} else {
		return Input * Factorial(Input - 1);
	}
}

Just set the call duration that you’re using (how long the agent is typically on the phone, for cold-calling, this will usually be 2.

To use this, just call OptimalStaffing, with the parameters: (# of calls, Ideal Immediate answer rate)
Like this:

OptimalStaffing(300,.9);

This means, find me the right amount of staff I need for 300 calls, where 90% of them are going to be answered immediately.

Posted in JavaScript | 2 Comments

Working with Databases in .Net

So you’ve gotta work with some data, awesome! Let’s get to work.

When I work with data, the easiest method is to encapsulate some stuff before we begin, then it’ll get so much easier. First we publicly declare our connection and two other variables:

Public kindofCon As New OleDb.OleDbConnection("Provider=SQLOLEDB;Data Source=some.kindof.place.COM;Initial Catalog=TdiXL;Persist Security Info=True;User ID=user;Password=pass")
Public DS As New DataSet
Public DR As DataRow
Public Adapter As OleDb.OleDbDataAdapter
Public SQL As String

Then we have our two functions, FillTable() which populates a dataset to work with, and SendCommand() which is for UPDATEs and DELETEs:

Sub FillTable(ByVal DS As DataSet, ByVal TableName As String, ByVal daSQL As String, ByVal Connection As OleDb.OleDbConnection, Optional ByVal CloseAfter As Boolean = False)
        If Connection.State <> ConnectionState.Open Then
            Connection.Open()
        End If
        If DS.Tables(TableName) Is Nothing Then
            DS.Tables.Add(TableName)
        Else
            DS.Tables(TableName).Columns.Clear()
            DS.Tables(TableName).Clear()
        End If
        Adapter = New OleDb.OleDbDataAdapter(daSQL, Connection)
        Adapter.SelectCommand.CommandTimeout = 0
        Adapter.Fill(DS, TableName)

        If CloseAfter = True Then
            Connection.Close()
        End If
    End Sub

    Sub SendCommand(ByVal daSQL As String, ByVal Connection As OleDb.OleDbConnection, Optional ByVal CloseConnection As Boolean = False)
        If Connection.State <> ConnectionState.Open Then
            Connection.Open()
        End If
        Dim CMD As New OleDb.OleDbCommand(daSQL, Connection)
        CMD.ExecuteNonQuery()
        If CloseConnection = True Then
            OleCon.Close()
        End If
    End Sub

Now when we want to do something, we’re going to do it row by row, because tables are set based things. So we can do that by:

SQL = ""
SQL += "SELECT * FROM SomeTable"
FillTable(DS,"data",SQL,kindaCon,False)
For Each DR IN DS.Tables("data").Rows
	DoSomeStuff()
Next 
Posted in VB.NET | Leave a comment

Using Google Visualization with AJAX

Google Visualization is great, but it can get kind of fussy with ajax. Here’s how I got around this:
In my example, I used Google Visualization and Jquery. Your header should include:

<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

Then immediately in the header, well after you link your stylesheet, load Google’s visualization stuff:

google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(function(){	
	$(document).ready(function()
	{		
		LoadData();	
	});	
});

LoadData() is the function we’re going to call when it’s ready. You could also use a loop to constantly refresh the data. Next, our main function:

function LoadData(dtype, id, chartType, chartTitle, chartHeight, chartWidth)
{
var data = new google.visualization.DataTable();
try
{
$.ajax({
    type: "GET",
    url: "datareturn.asp?dtype=" + dtype,
    dataType: "xml",	
    success: function parseXml(xml){
		data.setValue(0,0,0);	/*Set your own values here*/			
		makeGraph(data, dtype, id, chartType, chartTitle, chartHeight, chartWidth);							
	}
  });
 } catch(err) {
 
 }
}

I had to trim my code down a bit, so you won’t have dtype, id, etc….. But, when it calls makeGraph, that’s your own function to draw the chart, here’s my version (keep in my mind you won’t have as many parameters:

function makeGraph(data, dtype, id, chartType, chartTitle, chartHeight, chartWidth) {
	var chart;
	if (chartType=='line') {
		chart = new google.visualization.LineChart(document.getElementById(id));
	} else if (chartType=='bar') {
		chart = new google.visualization.BarChart(document.getElementById(id));
	} else if (chartType=='pie') {
		chart = new google.visualization.PieChart(document.getElementById(id));
	}
	chart.draw(data, {width: chartWidth, height: chartHeight, title: chartTitle});
}

If you have your setup like this, then you should have no problem generating great graphs via ajax!

Posted in JavaScript | Leave a comment

Multi Threading in VB.NET

I like to cook, and I love to program. Well one day I decided to utilize my VB kung-fu and made a program that pulls recipes and their ingredients from this one website that has “all” the “recipes” wink wink. Any hoot let’s dig in!
First we declare the streams we’re going to read and write too:

Private RecipesStream As Scripting.TextStream
 Private IngredientsStream As Scripting.TextStream

Next we need to initiate our threads (however many we want to run concurrently). Also we need to open our streams:

RecipesStream = FSO.OpenTextFile("ChickenRecipes.txt", Scripting.IOMode.ForReading)
IngredientsStream = FSO.OpenTextFile("Ingredients.txt", Scripting.IOMode.ForAppending, True)
Dim daThread As System.Threading.Thread
Dim I As Integer = 0
For I = 0 To 100
	daThread = New System.Threading.Thread(AddressOf RunningThread)	'RunningThread is the name of the Subroutine we wish to use
	daThread.Start()
Next

Now we have our horse, the “RunningThread” subroutine. This will do many things:

  1. Initiate all the msHTML objects we need(collection,element,document)
  2. Initate our loop in the thread which pulls the next Recipe URL and writes the ingredients
  3. Finally it writes the data and goes to the next Recipe URL

Here’s the code:

Private Sub RunningThread()
        Try
            Dim RecipeURL As String

            Dim TempString As String = ""

            Dim DaCol As mshtml.IHTMLElementCollection
            Dim DaEle As mshtml.IHTMLElement
            Dim LoaderDoc As New mshtml.HTMLDocument
            Dim objMSHTML As mshtml.HTMLDocument
            Dim iPersistStream As IPersistStreamInit

            objMSHTML = New mshtml.HTMLDocument
            iPersistStream = DirectCast(objMSHTML, IPersistStreamInit)
            iPersistStream.InitNew()
            RecipeURL = NextRecipe()
            Do
                LoaderDoc = objMSHTML.createDocumentFromUrl(RecipeURL, vbNullString)
                Do
                    Application.DoEvents()
                Loop Until LoaderDoc.readyState = "complete"
                Application.DoEvents()

                DaCol = LoaderDoc.getElementsByTagName("li")
                For Each DaEle In DaCol
                    If DaEle.innerHTML.Contains("href") = False And DaEle.innerHTML.Contains("<a") = False Then
                        If DaEle.innerHTML.Contains("<SPAN>") = True Or DaEle.innerHTML.Contains("<B>") = True Then 'It's at the directions, quite page
                            Exit For
                        End If
                        If DaEle.innerText <> "" And DaEle.innerText.Trim(" ") <> "" Then
                            TempString += DaEle.innerText &amp;amp;amp; vbNewLine
                        End If
                    End If
                Next

                WriteIngredients(TempString)
                RecipeURL = NextRecipe()
                'Just to count how fast/slow this is:
                daCounter += 1
                Debug.Print(daCounter)
            Loop Until RecipeURL = "-1"

            RecipesStream.Close()
            IngredientsStream.Close()
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
        
    End Sub

I’d like to mention that upon reviewing the code, I realized I didn’t need to use IPersistStream, I don’t even remember why I thought I needed that. Also, I close the two streams after the loop closes. But that’s not right because it should only close when ALL the threads have finished (ie. the last thread).
Here are the two functions to read/write data, using SyncLock:


    Private Function NextRecipe() As String
        Dim A() As String
        SyncLock RecipesStream
            If RecipesStream.AtEndOfStream Then
                Return -1
            Else
                A = RecipesStream.ReadLine.Split("|")
                Return A(1)
            End If
        End SyncLock
    End Function

    Private Sub WriteIngredients(ByVal ToWrite As String)
        SyncLock IngredientsStream
            IngredientsStream.WriteLine(ToWrite)
        End SyncLock
    End Sub

We do it this way, rather than just calling the object directly and writing or reading a line. Because in multi-threaded apps, a thread can be using this object at anytime, so you must “wait your turn” as a thread. It’s similiar to SQL, when you reading a table it’s actually LOCKing it, and you can’t write data to it until the read is finished. But VB doesn’t have these concurrency checks in place, which is why we use SyncLock.

Posted in VB.NET | Leave a comment

Erlang C Calculator in VB.NET

Let’s say you wanted to make an erlang C calculator in VB, well that’s not so hard:

Module ErlangCalculator
    Public CallDuration As Double = 2
    Public IntervalLength As Integer = 60
    Public Agents As Integer = 0
    Public Calls As Integer = 0

    Function AverageSpeedOfAnswer() As Double
        Return Math.Round(ErlangC() * (CallDuration * 60) / (Agents * (1 - AgentOccupancy())), 2)
    End Function

    Function ImmediateAnswer() As Double
        Return Math.Round((1 - ErlangC()) * 100, 2)
    End Function

    Function ErlangC() As Double
        Return Poisson(Agents, TrafficIntensity, False) / (Poisson(Agents, TrafficIntensity, False) + (1 - AgentOccupancy()) * PoissonCumul(Agents - 1, TrafficIntensity, False))
        'Return Poisson(tbAgents.Value, TrafficIntensity, False) / (Poisson(tbAgents.Value, TrafficIntensity, False) + (1 - AgentOccupancy()) * Poisson(tbAgents.Value - 1, TrafficIntensity, True))
    End Function

    Function TrafficIntensity() As Double
        Return (Calls / (IntervalLength * 60)) * (CallDuration * 60)
    End Function

    Function AgentOccupancy() As Double
        Return TrafficIntensity() / Agents
    End Function

    Function Poisson(ByVal IdealSuccesses As Double, ByVal TheMean As Double, ByVal Cumulative As Boolean) As Double
        Dim Numerator As Double
        Dim Denominator As Double
        If IdealSuccesses <= 0 Then
            Return Nothing
        Else
            If Cumulative = False Then
                Numerator = Math.Pow(TheMean, IdealSuccesses) * (Math.Pow(Math.E, (TheMean * -1)))
                Denominator = Factorial(IdealSuccesses)
                Return Numerator / Denominator
            Else
                Numerator = Math.Pow(TheMean, IdealSuccesses) * (Math.Pow(Math.E, (TheMean * -1)))
                Denominator = Factorial(IdealSuccesses)
                Return (Numerator / Denominator) + Poisson(TheMean, IdealSuccesses - 1, True)
            End If
        End If
    End Function

    Function PoissonCumul(ByVal IdealSuccesses As Double, ByVal TheMean As Double, ByVal Cumulative As Boolean) As Double
        Dim daReturn As Double = 0
        Dim I As Integer = 0
        For I = 0 To IdealSuccesses
            daReturn += Poisson(I, TheMean, False)
        Next
        Return daReturn
    End Function

    Function Factorial(ByVal Input As Integer) As Double
        If Input = 0 Then
            Return 1
        Else
            Return Input * Factorial(Input - 1)
        End If
    End Function

End Module

Then you can just change the agents and calls, and call the AverageSpeedOfAnswer() function to get how quickly the agents will answer the phone give, the call volume. It’s also based on 60 minute segments and an average call duration of 2 minutes.

Posted in VB.NET | Leave a comment

Proper Case without a UDF

Sometimes your working with a 3rd party product, and they record their names in all capitals. Since you can’t go in and fix this error, you must accommodate, but you don’t want to use a UDF, for whatever reason. You could construct something like this:

SELECT
	UCASE(SUBSTRING(a.FirstName,1,1)) + LCASE(SUBSTRING(a.FirstName,2,LEN(a.FirstName)-1)) as FirstName,
	UCASE(SUBSTRING(a.LastName,1,1)) + LCASE(SUBSTRING(a.LastName,2,LEN(a.LastName)-1)) as LastName
FROM SomeTable

And there you go, you have a lovely, properly cased set of names.

Posted in SQL | 3 Comments

Why you like subqueries.

Subqueries are great, when used properly.  One example of utilizing this magnificent beast is in reporting.  Let’s say you had to generate an email to you client every week on the number of sandwich types are being sold.

Sandwiches
Pastrami
Turkey
BLT
Meatball

And the client is concerned about the weekly, monthly, and yearly sales of these fine sandwiches.  In good SQL form we could execute something like this:

SELECT
	*
FROM (
	SELECT
		*
	FROM Sandwiches
) main
LEFT JOIN (
	SELECT
		COUNT(*) as Sales
	FROM Sandwich_Sales
	WHERE
		DateDiff(Week,DateAdded,CURRENT_TIMESTAMP) = 0 -- 0 for the current week, 1 for the previous week.
) Weekly
ON Weekly.ParentID = main.ID
LEFT JOIN (
	SELECT
		COUNT(*) as Sales
	FROM Sandwich_Sales
	WHERE
		DateDiff(Monthly,DateAdded,CURRENT_TIMESTAMP) = 0
) Monthly
ON Monthly.ParentID = main.ID
LEFT JOIN (
	SELECT
		COUNT(*) as Sales
	FROM Sandwich_Sales
	WHERE
		DateDiff(Year,DateAdded,CURRENT_TIMESTAMP) = 0
) Yearly
ON Yearly.ParentID = main.ID

We can we see that the initial part [main] held the unique categories that the others were going to join too.  And what we and up with is a nice table with the sandwiches and their sales.

Sandwich Weekly Monthly Yearly
Pastrami 56 203 1039
Turkey 78 504 1325
BLT 15 122 560
Meatball 12 55 91
Posted in SQL | 1 Comment

Joining could lead to duplication.

When beginners first learn SQL they can make some mistakes.  One of these is with joins.

One particular incident is with left or right joining and not having duplicates.  For example, lets say I have a unique set of data, no duplicate rows.  Then I Left Join to a table that has duplicate rows, however many matches it finds in that second table will be how many times that row is duplicated.

For example, if we had a table consisting of three rows:

ID Name Birthdate
1 Bob 1908-01-01
2 Mike 1912-01-01
3 Sam 1905-01-01

And we Left Joined it to this table:

ID ParentID Action Date of Action
1 1 Bought Coffee 2011-01-01
2 1 Made Breakfast 2011-01-05
3 1 Bought Oatmeal 2011-01-02
4 2 Typed On Keyboard 2011-01-03
5 3 Used a tissue 2011-01-01
6 3 Stared at Wall 2011-01-01
7 1 Ate One Banana 2011-01-01
8 2 Sneezed 2011-01-01

How many rows would it return? Eight, because it’s matches with all eight rows we were joining.

Posted in SQL | Leave a comment