Thursday, September 29, 2011

JavaScript helpers: Iterating an array while skipping select elements

 
Array.prototype.iterate || (Array.prototype.iterate = function (callback, ignore) {
  var i = 0, j = this.length;
    for (; i < j; ++i) {
        if (ignore && ignore(this[i], i)) {
          continue;
        } 
        
        callback(this[i], i);
    }
});

Usage

Here's how we can use it to iterate over a couple of numbers, skipping over the even ones:
 
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

arr.iterate(function (el) {
  console.log(el);
}, function (el) {
  return !(el % 2);
});

Output:
1
3
5
7
9

Here's another example, this time involving objects:
 
var queen = function (reference) {
    return {
        ref: reference
    };
}, arr = [queen("Aragon"), queen("Boleyn"), queen("Seymour"), queen("Cleves"), queen("Howard"), queen("Parr")];

arr.iterate(function (el, i) {
  console.log(i, el.ref);  
}, function (q) {
  return q.ref === "Boleyn"  || q.ref === "Howard";
});
Output (the queens who died with their heads on):
0 Aragon
2 Seymour
3 Cleves
5 Parr

If no ignore function is passed as the second parameter of the iterate method, no elements are skipped:
 
var arr = ["Mr. Albert Show", "Fusion Orchestra", "Fuzzy Duck", "Minotaurus"];

arr.iterate(function (el, i) {
  console.log(el);  
});
Output
Mr. Albert Show
Fusion Orchestra
Fuzzy Duck
Minotaurus

Saturday, September 17, 2011

Finding a YouTube video title by scraping

I was recently writing a tool in C# and I needed a way to get a YouTube video title. I could have used the YouTube API but I wasn't bothered about setting everything up and going through the documentation, so I decided to scrape the title off the video page itself.

For this, I first wrote a very simple way to execute a GET request and return the response (Removed all forms of error checking for brevity):
public static string ExecuteGETRequest(string url)
{
    var request = (HttpWebRequest)WebRequest.Create(url);

    using (var response = (HttpWebResponse)request.GetResponse())
    {
        var reader = new StreamReader(response.GetResponseStream());

        return reader.ReadToEnd();
    }
}
And here's the method that does the task at hand:
public static string GetYouTubeVideoTitle(string youtubeLinkUrl)
{
    string response = ExecuteGETRequest(youtubeLinkUrl),
             title = response.Substring(response.IndexOf("<title>\n") + 8);

    title = title.Substring(0, title.IndexOf("\n"));
    return title.Trim();
}

Usage

var title = GetYouTubeVideoTitle("http://www.youtube.com/watch?v=TY9jN6hm3N0"); // "Wicked Lady - Ship of Ghosts (Part 1 of 2) 1972"
Be wary of using this method for extracting titles because it could potentially break in the future due to changes in how YouTube renders the page with HTML; but it may be useful for quick scripts.

Checking for link validity

If you want to make sure the given link actually points to a YouTube video, you can use something like this:
public static bool IsValidYoutubeLink(string youtubeLink)
{
    // Regular expression from http://www.regexlib.com/REDetails.aspx?regexp_id=2569
    return Regex.IsMatch(youtubeLink, @"^http://\w{0,3}.?youtube+\.\w{2,3}/watch\?v=[\w-]{11}");
}


Sunday, September 11, 2011

Generating a list of links for a user's YouTube uploads

This is a very simple application I just wrote to generate a list of all of the video upload links given a YouTube user.

Download

Since this was such a small project, I didn't see fit to have a github repository for it so I just uploaded it to my hosting server.

Download the exe (release) file from: http://dreasgrech.com/upload/youtubeuseruploads/YouTubeUserUploads.exe

And the source: http://dreasgrech.com/upload/youtubeuseruploads/YouTubeUserUploads-source.zip
It won't be the best code you'll ever see, but it does the job for the task at hand.

Usage

YouTubeUserUploads.exe <username> [file]


If [file] is not given, a file links.txt will be created in the current directory.

Demo

Here's an example run using my YouTube username:

C:\YouTubeUserUploads.exe agnt666 uploads.txt
Username: agnt666
Saving links to: uploads.txt

Processing...
Finished writing 3 links

That would create (or overwrite) a text file called links.txt and write the links to my three currently uploaded videos at the time of writing:
http://www.youtube.com/watch?v=rsXnEpWyeEg
http://www.youtube.com/watch?v=sxBiD7u7nx8
http://www.youtube.com/watch?v=Ri2SHGZaSqs

Screenshots





Thursday, September 8, 2011

The Monty Hall game

After my last post on simulating the Monty Hall problem, I decided to go a step further and actually write the game itself. Since I wrote the simulation using JavaScript, I kept at it by writing the game using JavaScript by making use of the canvas element.

You can play the game here and find the source on Github: https://github.com/dreasgrech/The-Monty-Hall-Game.

The code leaves much to be desired but since this was a quick weekend project (...although some tweaks did spill over to the rest of the week), I didn't worry too much about it.

Screenshots




Saturday, September 3, 2011

Simulating the Monty Hall problem

You're on a game show and begin the game by having three doors in front of you. Behind one of the doors, lies the prize. You don't know which door is the winning door but the game show host knows.


You now randomly choose the door which you think has the prize behind it, but the door doesn't open for the time being. In this case, we are going to choose the middle door.


The game show host must now open one of the two remaining doors, and the door he chooses must not be the winning door. For this example, the game show host opens the door on the right.



The host now asks you if you want to stick with your first choice or switch to the remaining door.



Is it to your advantage to change your choice?




To test this out, I wrote some code using JavaScript to simulate playing a number of games and supplying me with the results of how many times it won when switching or not switching the chosen door upon given the choice. The initial guesses are all random.

Results

The following is the output for 5 runs with 10,000 games each:

Playing 10000 games
Wins when not switching door 3317
Wins when switching door 6738

Playing 10000 games
Wins when not switching door 3376
Wins when switching door 6735

Playing 10000 games
Wins when not switching door 3287
Wins when switching door 6726

Playing 10000 games
Wins when not switching door 3298
Wins when switching door 6664

Playing 10000 games
Wins when not switching door 3302
Wins when switching door 6674

These results show how the number of times you win when switching the door is approximately double the number of times you win when not switching the door.

This may seem counter intuitive at first as you may think that there's a 1/3 chance of winning, but as you can see from the above results, that's actually not the case. In fact, switching the door wins twice as often staying.


The same goes for when initially choosing Door 2 or Door 3:



Adapted from [Vos Savant, 1990]

Notice how, irrespective of which door you initially choose, you always have 2/3 chance of winning if you then switch.

The code

var totalGames = 10000,
     selectDoor = function () {
         return Math.floor(Math.random() * 3); // Choose a number from 0, 1 and 2.
     },
     games = (function () {
         var i = 0, games = [];

         for (; i < totalGames; ++i) {
             games.push(selectDoor()); // Pick a door which will hide the prize.
         }

         return games;
     }()),
     play = function (switchDoor) {
         var i = 0, j = games.length, winningDoor, randomGuess, totalTimesWon = 0;

         for (; i < j; ++i) {
             winningDoor = games[i];
             randomGuess = selectDoor();
             if ((randomGuess === winningDoor && !switchDoor) || 
                 (randomGuess !== winningDoor && switchDoor)) 
             {
                 /*
                  * If I initially guessed the winning door and didn't switch,
                  * or if I initially guessed a losing door but then switched,
                  * I've won.
                  *
                  * The only time I lose is when I initially guess the winning door 
                  * and then switch.
                  */

                 totalTimesWon++;
             }
         }
         return totalTimesWon;
     };

 /*
  * Start the simulation
  */

 console.log("Playing " + totalGames + " games");
 console.log("Wins when not switching door", play(false));
 console.log("Wins when switching door", play(true));

I've added this piece of code to the Monty Hall problem at the Rosetta Code website.