Monday, July 1, 2013

Finding the start of the week for a random DateTime

I've written before about extension methods here , here and here. There are pluses and minuses to using them but the other day I was able to add what I thought was a neat little one.

Given a random date we needed to be able to figure out when the week started for that date. Depending on the culture this could be either the Sunday or Monday before the date. After some googling and StackOverflow answers I was able to come up with the following DateTime extension method:
/// <summary>
/// Extension method to return the start of the week for the current culture.
/// </summary>
public static DateTime StartOfWeek(this DateTime dt) {

  // Get the difference in days from today to the start of the week and account for any negative conditions.
  // Sunday is 0, Monday is 1, etc
  int diff = (int)dt.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;

  // Adjust back to the start of the week and return a date stripped of time.
  if (diff < 0) { diff += 7; }
  return dt.AddDays(-diff).Date;
}
Now for a given DateTime you can call StartOfWeek like this:
    DateTime.Now.StartOfWeek();

Sunday, March 31, 2013

The SSD - Cheap Memory Paradox

I'm a big convert to using a SSD (solid-state drive) as the primary drive in a system. In terms of a speed boost there little more that can make as large a difference in your computing experience as with adding a SSD. Your OS and programs will load faster and if you have multiple programs open switching between them is smoother. SSD prices have been falling so that you can now find quality drives for under a $1/gigabyte. I was able to get a Corsair Force GT 128GB drive for x.

System memory has also fallen since the last time I upgraded my computer so on my last upgrade I was able to purchase 16GB for around 80 dollars. But here comes the problem Windows swap file (pagefile.sys) wants to be the same size as your RAM as does you hibernation file (hiberfil.sys). This eats up 32GB of an already shrunken drive (128GB actually becomes about 111GB formatted). While you could move the swapfile to another hard drive this reduces the swap speed and one of the benefits of the SSD. The hibernation file cannot be moved (see The File System Paradox) and has to be on the C drive.

Apparently this is improved in Windows 8 with the pagefile reduced to just 25% of RAM when hibernation is enabled (see Swapfile.sys, Hiberfil.sys and Pagefile.sys in Windows 8). If it wasn't for the annoying Metro interface I might consider upgrading. Ah well may have to look for specials on 256GB drives.

Wednesday, February 13, 2013

Virtual Static


In Smalltalk a Class is a first level object just like everything else in the system. Objects get instantiated using the Class as a template but the Class itself can have its own properties and methods. In fact constructors are just class methods in Smalltalk that return an instance.

Now as a C# programmer I've always thought of static properties and methods as the same thing as Smalltalk's class properties and methods. In the back of my head I knew that C# didn't have first-level Class objects but the static paradigm seemed to fit. So when the other day I wanted to override a static method in a subclass I figured no problem just mark the one in the superclass 'virtual' and then add my new implementation. One problem was that compiler balked at 'virtual static'.

After some searching around I found this blog post explaining why this was not a valid combination of keywords. As Eric Libbert writes:
Related questions come up frequently, in various forms. Usually people phrase it by asking me why C# does not support “virtual static” methods. I am always at a loss to understand what they could possibly mean, since “virtual” and “static” are opposites! “virtual” means “determine the method to be called based on run time type information”, and “static” means “determine the method to be called solely based on compile time static analysis”.
Turns out 'static' is really not equal to 'class'. I must admit I almost shed a tear that day as this sunk in.

Friday, January 18, 2013

Upgrading my Home Network

For 2013, I've set out a goal for myself to upgrade several key components of my home network. I have a household with PCs, Macs, iPads, Kindles, and smartphones (which makes me feel like a mini IT admin). Making sure those devices operate optimally and efficiently is my goal. Also with newer technology being designed to use less energy I think this effort can lower my overall power consumption. My three initial items are:
  1. Update wireless network
  2. Update file server and backup strategy
  3. Update home theater PC.
Once I get those items done I can reevaluate the next steps.

First up is my wireless network. I currently use an ASUS (RT-N16) running DD-WRT as my main router connected to a cable modem. While speeds on the wired connections with the gigabit switch have been great the wireless performance has just been ok. As I started researching this more I found out that just having G devices on the same network as N devices forces the router to lower speeds. First I tried to figure out which devices were using which protocols on the network but this proved to be surprisingly difficult. Basically the best I could find from googling was tools to scan the network for wireless devices (dd-wrt already has this list) and then go to each device and check its adapter and connection speed. Instead I set my router to N only and found out which devices could no longer connect. This helped me isolate the G devices to the Kindles and some older iPods (nothing that was critical).

RT-AC66UI looked at upgrading to this beast the ASUS RT-AC66U Dual-Band Router (what SmallNetBuilder calls the Dark Knight) but at close to $200 it was an expensive option. My plan if I got that was to put the N devices on 5GHz band and the G devices on the 2.4GHz. I seem to remember reading that this was possible but might lower the N a little bit. I don't have any AC devices yet but a little future proofing doesn't hurt.



Instead I decided to buy an old router off of eBay and just dedicate that for the G devices. I wanted something compatible with Tomato firmware as I've been interested in trying that out as an alternative to DD-WRT. There are number of newer builds of Tomato (eg Shibby or Toastman) but the original polarcloud one had the best documentation to get me started.

I was able to find a Linksys WRT54G for $20 shipped and quickly went to work getting it setup. I plugged my desktop directly into the router and was able to connect on 192.168.1.1 with the default username/password. Uploading the firmware went smoothly and soon I was running Tomato. Played around some of the settings and went to configure the router.

I made my only mistake when I configured both the router's IP address and its WAN address to be 192.168.1.2 (since the ASUS was still going to be the main router at 192.168.1.1). Connecting the Linksys WAN port to a port on the ASUS router didn't allow me to see the router. After a quick reset I set just the router's IP address to 192.168.1.2, skipped the WAN port and just connected it to one of the switched ports and all seemed good. I then configured the wireless on the Linksys with it's own SSID. I set each router to only serve a specific protocol and put them on channels far apart.

So far everything seems good and connection speeds are higher on the N devices. Fairly inexpensive fix to speed up things. The next project is not going to be as cheap.

These articles were a great in helping me figure out what I needed:

Monday, October 1, 2012

Simple Mechanical Turk example using C#


I started looking at the AWS API and specifically the Mechanical Turk Requester API the other day. After reading the overview and understanding the basics I wanted to test making a simple call to get a feel for it. I set up an account and got my access credentials (getting credentials is a whole other story as it involves two different websites and seems overly complicated but it's done for now). I figured the GetAccountBalance operation seemed like the best first option as I didn't want to create a HIT (Human Intelligence Task - their term for tasks you can create) and manage that. Since I hadn't added any money it should be easy for them to return a zero to me.
The web services are REST based and calling them seems pretty straightforward. You figure out the operation you want to perform, set some querystring parameters and make a web request. The complicated bit is calculating the signature (a SHA1 hash of the operation, service and current time using your secret access id as the key). Amazon doesn't have a nice simple example of constructing this in C# and even the other language examples don't look simple. There is a SDK for .NET it looks like it does a good job wrapping the Amazon endpoints but I wanted to figure out the basics for myself. So by starting with the examples from the SDK I was able to simplify the code down to the following:
using System;
using System.Globalization;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;

namespace TurkTest {
 class Program {

  static void Main(string[] args) {
   const string SERVICE_NAME = "AWSMechanicalTurkRequester";  // requester service for MTurk
   const string TIMESTAMP_FORMAT = "yyyy-MM-ddTHH:mm:ss.fffZ";

   // Modify these with your values.
   const string operation = "GetAccountBalance";
   const string accessKey = "[Your access key]";
   const string secretAccessKey = "[Your secret access key]";

   // Millisecond values in the timestamp string can result in intermittent BadClaimsSupplied errors.
   // Get the current UTC time and use that to create a new time with milliseconds set to zero to avoid this case.
   DateTime now = DateTime.UtcNow;
   now = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, 0, DateTimeKind.Utc);
   string timeStamp = now.ToString(TIMESTAMP_FORMAT, CultureInfo.InvariantCulture);

   // Create the hash-based messaged authentication algorithm (SHA1) using our secret access key as the key.
   var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(secretAccessKey));

   // Combine the service name, operation and timestamp and then hash them to produce the signature.
   var dataBytes = Encoding.UTF8.GetBytes(SERVICE_NAME + operation + timeStamp);
   string signature = Convert.ToBase64String(hmac.ComputeHash(dataBytes));

   // Build the URL to send to Amazon
   string url =
    @"https://mechanicalturk.amazonaws.com/?Service=AWSMechanicalTurkRequester&AWSAccessKeyId={0}&Version=2012-03-25&Operation={1}&Signature={2}&Timestamp={3}";
   url = string.Format(url, accessKey, operation, signature, timeStamp);

   // Send the request and write the respose to the console
   using (WebClient client = new WebClient()) {
    using (StreamReader reader = new StreamReader(client.OpenRead(url))) {
     Console.WriteLine(reader.ReadToEnd());
    }
   }

   Console.Read();
  }
 }
}
After a couple of false starts I was able to get it to return my zero balance. Hope this helps the next person get started.