Saturday, February 2, 2013

Pubsync 1.3 Released!

Today I released PubSync 1.3.

PubSync (short for Publish/Sync) is a command-line application I developed to ease the pain of publishing my Visual Studio projects. Although I developed it for use with Visual Studio, it can easily be used for syncing any directory structure.
I created PubSync to solve 3 issues:
  1. Visual Studio's Publish feature would often fail to overwrite changed files, forcing me to manually delete the destination files and re-publish. I hate manual steps.
  2. Visual Studio's option to remove the files on the destination that don't exist on the source is not configurable. For example, I couldn't choose to have it not wipe out my uploads folder containing user-created content.
  3. I sometimes work from home, and publishing through a VPN across the Internet was extremely slow, despite the file sizes being low. In my experience, PubSync is much faster.
PubSync's Main Features:

  • Simple XML schema for configuring file sync
  • Support for profiles to publish to different servers
  • High-speed syncing
    • Easily exclude files/folders from syncing using Regular Expressions
    • Delete files on the destination that do not exist on the source
    • Easily sync a single file
Simple XML schema for configuring file sync
I wanted to make configuring PubSync simple but flexible, so I made up a simple XML schema. The schema and a sample config file are included with PubSync.

Support for profiles to publish to different servers
At work, we use at least separate servers for development: development, staging, and live. I'm all about automating repetitive tasks, so Pubsync needed to support easily publishing to all 3.

High-speed syncing
At the first release, PubSync simply called Robocopy with the proper arguments to perform the sync.
This turned out to be quite a bit faster than Visual Studio, but it was still pretty slow when copying across the VPN from home, so I added a feature in PubSync to perform the sync internally. The Robocopy option is now deprecated and will likely be removed in the near future.
To determine if a file should be copied, PubSync uses a few simple checks:
  1. Is the file in the excluded list?
  2. Does the file exist on the destination?
  3. Do the source and destination files have the same size and date modified?
I'm unsure of all the criteria Robocopy uses to decide what to copy, but my method turned out to be much faster, especially when dealing with many small files.

Delete files on the destination that do not exist on the source
If a file exists on the destination but not on the source, PubSync will remove it. Simple and sweet.

Easily exclude files/folders from syncing using Regular Expressions
I needed PubSync to ignore the user uploads folder, as it only exists on the destination and the files should never be erased. I also required it to skip certain files (all the CSharp files, for example).
PubSync can be configured with regular expressions to exclude certain files and folders.

Easily sync a single file
I was working on a web app across a VPN and got sick of waiting for the entire directory structure to sync (it took about 20 seconds) when I had only changed 1 file, so I added an option to specify a single file to be synced.


Thursday, January 26, 2012

My new favorite Visual Studio extension!

Adding GAC references to a Visual Studio project sucks. Why? Because for every reference you add, you have to open the "Add Reference" box, wait 10-20 seconds for it to load the list, find your reference in the list, and click OK. It doesn't cache the list, and it doesn't sort it either (although it does remember your sort preference - if I sort the list A to Z and add a reference, then reopen the Add Reference dialog, the list is unsorted. However, if I then click to sort the list again, the list will be sorted Z to A. Genius! Oh wait...).

When you have to update multiple references in multiple projects, this quickly becomes an aggravating, time consuming process. But no longer! After years of silent suffering, I looked for and found an awesome fix: an VS extension called Muse.VSExtensions (http://visualstudiogallery.msdn.microsoft.com/36a6eb45-a7b1-47c3-9e85-09f0aef6e879/). This extension adds it own dialog for adding GAC references. The references are cached, easily searchable, and can be refreshed with a simple button press.

I only wish I'd found this sooner. Now, back to updating references.

Thursday, December 8, 2011

MySQL Failover with Entity Framework

I recently started using the Entity Framework 4.1, and I absolutely love it! It has taken away several of the headaches I've faced; for example, when I have multiple databases with identical schemas, I no longer need to keep separate stored procedures for them - the queries are now handled directly in my code. In addition, I now have strong typing without having to map each DataRow column to a class property. However, I ran into a small snag when it came to server failover. The app I'm working on has 4 MySQL servers - 3 slaves, 1 master. Two of the slaves are in a different site, so they are used only if the main read and master servers go offline. In the old version of the app, I used a custom solution to direct the queries to the proper servers. For example, instead of using this code:
var datatable = new DataTable();
using(var command = new MySqlCommand("Render_GetGraphics", new MySqlConnection("connectionstring")))
{
    command.Parameters.AddRange(new MySqlParameterCollection[]
                                    {
                                        new MySqlParameter("_clientId", _clientId),
                                        new MySqlParameter("_otherId", _otherId),
                                    });
    datatable.Load(command.ExecuteReader());
}
var graphics = datatable.Rows.Cast<DataRow>().Select(
        r =>
        new
        {
            Name = (string)r["Name"],
            Action = (GraphicApplicationAction)r["ActionID"],
            AlwaysApply = Convert.ToBoolean(r["AlwaysApply"]),
            PageSettings = (string)r["PageSettings"],
            IsEnabled = Convert.ToBoolean(r["IsEnabled"]),
            Image = r.IsNull("Image") ? null : (byte[])r["Image"],
            Type = r.IsNull("Type") ? "" : (string)r["Type"]
        })
    .ToList();
I used this code:
public ConnectionInfo dbConnection = new ConnectionInfo(null, new [] { "Server1", "Server2" }, "dbname", "dbuser",
                                                                   "dbpassword");
var graphics = new DbCommand(dbConnection, "Render_GetGraphics",
                                         new[]
                                             {
                                                 new MySqlParameter("_clientId", _clientId),
                                                 new MySqlParameter("_otherId", _otherId),
                                             })
                .RetrieveDataRows().Select(
                    r =>
                    new
                        {
                            Name = (string)r["Name"],
                            Action = (GraphicApplicationAction)r["ActionID"],
                            AlwaysApply = Convert.ToBoolean(r["AlwaysApply"]),
                            PageSettings = (string)r["PageSettings"],
                            IsEnabled = Convert.ToBoolean(r["IsEnabled"]),
                            Image = r.IsNull("Image") ? null : (byte[])r["Image"],
                            Type = r.IsNull("Type") ? "" : (string)r["Type"]
                        })
                .ToList();
The RetrieveDataRows() method had error handling so that if it had trouble connecting to one server, it could try the next best option. With the EntityFramework, I no longer had that option, as my old model would have prevented me from using LINQ efficiently. So I spent this morning working on it, and came up with these two classes: EntityFrameworkConnection.cs
using System;
using System.Collections.Generic;
using System.Data.EntityClient;
using System.Linq;
using MySql.Data.MySqlClient;

namespace myApp
{
    public class EntityFrameworkConnection
    {
        # region Fields

        readonly List<string> _servers = new List<string>();
        private readonly string _initialConnectionString;
        # endregion

        # region Properties

        public string ConnectionString
        {
            get
            {
                lock (_servers)
                {
                    EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder(_initialConnectionString);
                    entityBuilder.ProviderConnectionString = String.Format(entityBuilder.ProviderConnectionString, "localhost");
                    MySqlConnectionStringBuilder sqlConnectionBuilder = new MySqlConnectionStringBuilder(entityBuilder.ProviderConnectionString) { Server = _servers.First() };
                    entityBuilder.ProviderConnectionString = sqlConnectionBuilder.ToString();

                    return entityBuilder.ToString();
                }
            }
        }

        public List<string> Servers { get { lock (_servers) return _servers; } }

        # endregion

        # region Constructors

        public EntityFrameworkConnection(string connectionString)
        {
            _initialConnectionString = connectionString;
        }

        # endregion

        # region Public Methods

        public bool GoToNextServer()
        {
            lock (_servers)
                if (_servers.Any())
                    _servers.RemoveAt(0);

            return _servers.Any();
        }

        # endregion
    }
}
The final version of this class will be able to update the list of servers from the database. This version has to have the servers manually specified. After a failed connection to a server, that server is removed from the list of available servers, and the next server in the List<> is used. AdminDb.cs
using System;
using System.Configuration;
using System.Linq;
using MySql.Data.MySqlClient;

namespace myApp
{
    public class AdminDb
    {
        public delegate T QueryDelegate<T>(Models.adminEntities db);

        # region Instance Stuff
        private readonly EntityFrameworkConnection _dbConnection;
        //public EntityFrameworkConnection DbConnection { get { return _dbConnection; } }
        
        private AdminDb()
        {
            _dbConnection = new EntityFrameworkConnection(
                ConfigurationManager.ConnectionStrings["adminEntities"].ConnectionString);
        }

        # endregion 

        # region Static Stuff
        private static AdminDb _manager;

        public static EntityFrameworkConnection Connection { get { return _manager._dbConnection; } }
        
        static AdminDb()
        {
            _manager = new AdminDb();
            // Manually add the servers
            Connection.Servers.Add("localhost");
        }

        public static T RunQuery<T>(QueryDelegate<T> del, bool isReadonly = true)
        {
            while (_manager._dbConnection.Servers.Any())
            {
                try
                {
                    using (
                        var db =
                            new Models.adminEntities(
                                _manager._dbConnection.ConnectionString))
                    {
                        return del(db);
                    }
                }
                catch (Exception ex)
                {
                    if (ex.InnerException is MySqlException &&
                        ex.Message == "Unable to connect to any of the specified MySQL hosts.")
                        if (_manager._dbConnection.GoToNextServer())
                            continue;

                    throw;
                }
            }

            return default(T);
        }
        # endregion
    }
}
This class acts as a layer between Entity Framework and my app, enabling me to easily do things like failover while still keeping the simplicity of EntityFramework. For each EF model I simply have to create a version of this class that uses the proper connection string and model. Example time:
 
// Standard entity framework call:
using (var db = new estatements_adminEntities())
{
    var usersList = db.users.Include(u => u.clientgroup).Include(u => u.client).ToList();
    // do stuff..
}

// The same call using AdminDb:
var usersList = AdminDb.RunQuery(db => db.users.Include(u => u.clientgroup).Include(u => u.client)).ToList();

Wednesday, November 23, 2011

Serializing dates in MVC (update)

As I was falling asleep in bed last night, a thought went through my mind: "Since I'm using this Regular Expression every time I load the page, isn't it rather wasteful to be compiling it every time?" So when I got up this morning, I looked up "Compiled Regular Expressions", and read through this page: http://www.dijksterhuis.org/regular-expressions-advanced/. Not only did I pick up some tips on compiling regular expressions, I also discovered a much simpler (and likely quite more efficient) way of replacing the MS-formatted date with my date string. In my previous method, I was casting the Regex matches to an IENumerable and using Linq to iterate through them; in the updated version, the iterative process is handled internally by the Regex object. All I have to do is tell it to use my FixDates method whenever it encounters a match. In the process of updating my code, I also added support for custom Date Formats and set the default to "yyyy-MM-dd".
private static readonly Regex DateRegex = new Regex(@"\\/Date\((?<ticks>\d+)?\)\\/", RegexOptions.Compiled);
/// <summary>
/// If true, date-specific serialization code will be run;
/// If false, date-specific serialization code will not be run.
/// </summary>
public bool HasDates { get; set; }
/// <summary>
/// The date format string to be applied. Defaults to "yyyy-MM-dd".
/// </summary>
public string DateFormatString { get; set; }

/// <summary>
/// Replaces MS-formatted dates with date strings
/// </summary>
/// <param name="match"></param>
/// <returns></returns>
public string FixDates(Match match)
{
    return new DateTime(1970, 1, 1)
        .AddMilliseconds(long.Parse(match.Groups["ticks"].Value))
        .ToString(DateFormatString);
}

/// <summary>
/// Serialize the object to JavaScript and
/// perform extra formatting on the serialized string as necessary
/// </summary>
/// <returns></returns>
public string Serialize()
{
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    var serializedData = serializer.Serialize(Data);
    if (HasDates)
        serializedData = DateRegex.Replace(serializedData, FixDates);

    return serializedData;
}
Click here to download the updated code.

Monday, November 21, 2011

Serializing dates in MVC

Update: I've rewritten the code for simplicity and efficiency. You can check it out here.
Ah, dates. Simple little things, really, especially when working with .Net and JavaScript, right?
Well, sort of. See, Microsoft decided that when serializing DateTime objects, they should be formatted like this:
"\/Date(12345678)\/". Unfortunately, without running eval() on that, that format is useless.
I've never really had this issue before, because when working with dates on the client side, I always use strings.
So why the issue now?
Because, along with using MVC, I decided to use the Entity Framework, which made it really easy to return a bunch of objects from the database:
return Json(db.Tasks.ToList());
In the past, this would have been more like:

DataTable dt = new DataTable();
dt.Load(command.ExecuteReader());
return dt.Rows.Cast<DataRow>().Select(
                r =>
                new
                    {
                        id = (int) r["id"],
                        name = (string) r["name"],
                        date = ((DateTime) r["date"]).ToString("yyyy-MM-dd")
                    });

Now, I could simply go on using the select statement, but I just couldn't bear the thought of doing that everytime I had to work with dates (since that is all the time). So instead I wrote a custom Json serializer derived from JsonResult. I've uploaded the source code (link at bottom), but the real magic is in these lines:

public bool HasDates { get; set; }

public override void ExecuteResult(ControllerContext context)
{ 
    //... a bunch of code ...
    if (Data != null)
    {
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        response.Write(HasDates ? FixDates(serializer.Serialize(Data)) : serializer.Serialize(Data));
    }
}   

public string FixDates(string data)
{
    var matches = Regex.Matches(data, @"\\/Date\((?<ticks>\d+)?\)\\/").Cast<Match>().ToArray();
    for (int i = matches.Length - 1; i >= 0; i--)
    {
        var match = matches[i];
        data = data.Remove(match.Index, match.Length)
            .Insert(match.Index,
                    new DateTime(1970, 1, 1).AddMilliseconds(long.Parse(match.Groups["ticks"].Value))
                        .ToString("yyyy-MM-dd HH:mm:ss"));
    }
    return data;
}

The code simply loops through the standard serialized result and replaces any MS-formatted date strings with my kind of date string (yyyy-MM-dd HH:mm:ss eg. "2011-11-21 19:48:13").

Updated return call:
return new ProperJsonResult() { HasDates = true, Data = db.Tasks.ToList() };

Click here to download ProperJsonResult.cs

Wednesday, October 26, 2011

Rectangle.ReallyContains()

So I just wrote an extension method, Rectangle.ReallyContains(Point p).
Seems the XNA folks and I disagree on what Contains() really means. For example, let's say a rectangle has a left value of 0, a top value of 0, a right value of 5, and a bottom value of 5.
To me, the corners of this rectangle are as follows: (0,0), (0,5), (5,5), (5,0).
So then, rectangle.Contains(new Point(0,5)) should be true.
According to the XNA folks, this is not correct. From what I can tell, the bottom and right values are the numbers directly after the rectangle ends (so the rectangle goes from 0 to - but not including - 5).
I'm sure their way makes sense in a lot of scenarios. It doesn't make sense for mine, and I just spent a good 10 minutes figuring that out.
*rant finished*

Nate's Roguelike Game

So I recently rediscovered ADOM (http://www.adom.de/) and after playing it for a while (and dying many times) I've decided to create my own roguelike game.
The game is located here: http://natesroguelikegame.codeplex.com/.
There are no releases as yet - so far, the only thing working is random room generation.

Friday, September 30, 2011

Morgan wrote a program!

Thanks to Microsoft SmallBasic, I coached Morgan through writing her very first program today!
It was a lot of fun to show her a bit of the development world and explain a little bit about OOP.

AStar in Java.. and this WYSIWYG editor sucks

I'm on another game programming kick. This happens every several months or so, I play around with it for a while before getting lost in the enormity of it all and wandering away again.
This semester, I'm taking a programming class which uses Java. Not being at all familiar with Java, I was pleasantly surprised to discover that it is very similar to my main language, C#.
While investigating Java game programming I came across jMonkeyEngine (a Java 3d game engine), and while going through some tutorials on their site I came across an AStar tutorial.
I decided to gain some Java experience by implementing AStar in Java. I got a basic version working pretty quickly, but it wasn't taking the fastest route - it was taking 9 blocks to do what should only have taken 8.
I kept playing around with it and got it down to finding the fastest route, but it wasn't nearly as efficient as it could be (it kept searching blocks that it didn't need to). I fixed this by recording what iteration the algorithm was on when each block was discovered, then weighting my search to sort first by distance (asc), then by iteration (desc).
So, given the following blocks:

BlockDistance From TargetIteration
1101
3102
2201

the old version would pick either block 1 or block 3 when searching; the new version would always pick block 3. Anyways, the end result is that the path my program finds is identical to the one in the tutorial:

Not really a big accomplishment, but it's exciting for me, so I figured I'd post it.


On a side note, I just changed the font to Arial then went back to the HTML and ugh! It took my nice simple text and added a span on every line with inline styles all over the place. Blechh.


Download Sample (Open the HTML page)
Download Source Code (Netbeans project)

Thursday, December 24, 2009

My Fair Lady (Morgan's Song)

December '08

My fair lady looks at me
My breath is swept away
Lost in her eyes, drowning in them
I'm mesmerized by her gaze.

My fair lady smiles at me
Like the sun in the spring
I can't resist the curve of her lips
I smile back helplessly.

My fair lady sings to me
Her voice so sweet to hear
So soft, so pure, it rushes o'er me
And drives away all my cares.

My fair lady comes to me
And 'tis my joy to tell
With her in my arms and God by my side
I'll ne'er need anything else.

My fair lady loves me
And I love her, you see.
The queen of my heart, forevermore -
She's my fair lady.

Tuesday, December 8, 2009

Just a quickie..

Some good news, and some bad news.

The bad: my iPod went through the washer AND spent 7 minutes in the dryer in this past weekend.
The good: I pulled it out and stuffed it into a bowl of rice for a day, and it works fine.

The bad: My PC's 550 watt power supply is dying due to a swollen capacitor.
The good: I found a good 600 watt power supply on Newegg for only $49.99, with free 3 day shipping.

Thursday, September 24, 2009


I'll start things off with something good - the food I ate last night. I scrambled eggs in soy milk, and stuck 'em in a wrap with tomatoes, spinach, black olives, and cottage cheese. It was quite delicious.

I decided to try out soy milk as I feel that I currently have too much milk in my diet.. normally I have milk in at least two meals a day in order to get a good enough fat and protein.
I certainly don't plan on eliminating milk, as I enjoy the taste far too much, but cutting back seems like a good idea.

Tonight's meal was good as well, but nearly as delicious - I made cream of wheat with soy milk and added a little real milk once I was done cooking it. The soy milk made it sweeter so I didn't need to add honey, and then the bit of milk I added gave it the proper taste.

I spoke with my Principles of Management professor tonight about my test. I actually wrote down my student ID wrong (I put "592" in one spot instead of "152". I can't understand how I messed that up as I remember thinking it as "152" right before I filled out the scantron sheet. Anyways, I got a 19 out of 20 on the exam, plus 1 bonus point, so I would have had 20 out of 20, but I'm getting docked a point for messing up my ID number, so it's back to 19. *sigh*
The worst part was that I had to wait in line forever to see him. He's an extremely talkative old fellow (he spent 15 minutes before the exam telling us how to fill out the scantron - perhaps I can blame my mess-up on the fact that he bored me to death - or not..) and there were eight other people who also needed to see him.

Since they all had places to go afterward, and I didn't, I let them all go first. It should've been fairly quick (go into the office, see the grade, and leave) but the professor spent at least 10 minutes talking to each person, mostly lecturing them on studying, and I myself had to wait at least 5 minutes after he told me I was done because he was complaining about other students.

By the time I left it was dark, but I was in a mood to play so I practiced parkour at one of the entrances to the College of Business, then performed a Passe Muraille (vertical wall run) and got on top of the roof above my classroom. I was up there last week, it's kinda cool but not too exciting since there's no place to go from there but back down.

I went back and did some more parkour, mostly speed vaults and monkey vaults, with some lazy vaults, wall runs, and rolls mixed in. I had a couple of people stop and watch me when I was doing rolls (I was dropping about 4 feet and rolling, really no big deal) and one guy came up and asked me if I was practicing for skateboarding. I told him a little about parkour and emphasized that I was being careful, and then he stated that he wanted to make sure I wasn't going to be breaking any bones, and left.

When I got home I performed several kong vaults on the picnic tables shown in the video I posted on facebook a while back. It's gotten so much easier to do them than when I started; I think I can definitely thank my weight bench for that.

I'm also back working on computer game programming (2D right now, eventually hopefully 3D). It's hard to find time to work on it though.
I'm very glad I only went with two classes this semester. Between that, working full-time, excercising, and cooking my meals, I have very little personal time anymore.

Wednesday, July 29, 2009

Stalked by a grasshopper

I'm being stalked by a grasshopper. Well, maybe..
It started last Friday. When I parked my bike at work, I noticed a grasshopper was on my bike. I thought, "hmm, that's strange" but then forgot about it. I saw her (I think it's a female) again on Monday while I was on my way to work. When I got there, I carefully brushed her off.
Today, I found heron my sleeve when I entered the building (it was raining, too!). So I brushed her off on to the pavement, over 30 feet away from my bike.
I went to an advising appointment at Kent during lunch, then stopped by my apartment to change (more about that later) and on my way back (it was still raining) I saw the grasshopper clinging to my right mirror. It was pretty sweet to see how she flattened herself out to avoid getting blown off.
Every time I got to a stop light, she would readjust her position. I left her on my bike this time when I came into work.. I wonder if she'll be back?
I actually have 3 theories for this one:
  1. The grasshopper is stalking me.
  2. My bike is a breeding ground for grasshoppers.
  3. Rival companies have hired grasshoppers to sneak into my workplace and steal company secrets.

Tuesday, July 14, 2009

Consistently crazy

Work has been super busy of late. There's so much stuff to do and document - I love it, but it's crazy. Last Thursday our aging primary domain controller finally gave up the ghost, so we spent that day making sure the replacement DC was doing everything correctly, and spent the next day doing data recovery on the old one - which left me racing to beat a programming deadline on Monday.. =D

I've been working on my freerunning skills lately as well. The fivefingers are awesome. They give me great grip while still allowing me to feel the surface I'm on. I had a great time training at a local playground yesterday. There's an even bigger playground I'd like to check out, but it tends to have a lot of people at it. Maybe I'll go there on lunch one day.

One of my favorite things to do with fivefingers is climb. Climbing pipes up the sides of buildings is suddenly super easy. I really freaked myself out the other day, however, when I climbed down a 2-story pipe. About 5 feet down I passed over a buzzing bees nest that wasn't visible from the top or bottom. Thankfully, the bees ignored me. When I saw them, the only thought in my head was "don't let go, don't let go, don't let go..."

I'm also working on performing a front flip. So far I've only succeeded in landing on my back, but I understand what I'm doing wrong so hopefully I can change that. The technique itself is really simple; unfortunately, my confidence in the technique working is very low. I have a fear of landing on my head. This isn't a problem in rolls because I know I'm in control - I've taken 10 foot drops with no problem. But what gets me on the front flip is when I jump up, I'm not rotating. I have to generate the rotation by curling my body, but I feel like I won't rotate enough and will simply land on my head. Ah well, practice makes perfect.

On a side note, futon mattresses make good substitutes for gym mats, but bed mattresses do not. Although a bed has more padding, it is too springy; when I landed on the bed, I hit the ground with my butt, then got shot back up. With the futon mattress, there is no springiness, so although it has less cushioning, it ends up providing more.

Wednesday, July 1, 2009

You are like Nathan

I love Leverage and can't wait for season 2 to start (July 15!). I knew it was supposed to be close but wasn't sure when, so I went on TNT's website to check. While I was there, I took the "What Specialty Do You Bring to the Heist?" quiz, and got the result shown below, which I found to be rather humorous.



YOU ARE LIKE NATHAN

You’re the brains--smart, logical, and not afraid to show it. Pulling off a heist doesn’t have to be brain surgery, but you treat planning one as such just to make sure every detail is set. Even though you don’t help out at the scene itself, your crew respects you, nonetheless. Sniffing out snags and keeping the state pen out of the picture earns you that kind of appreciation. Yes, life’s good on the sidelines, especially if things go south quickly. After all, ideas can’t get you arrested, right?

"they scare me"

Well, I've had several different groups comment on my FiveFingers now. On Friday I went with Morgan and a bunch of our friends to see Transformers (great movie, by the way!) and their reactions were mostly a mix of "cool" and "weird". Saturday, Mor and I went to Border's and the lady who came over to "help" me asked me about them (judging by her interest in my FiveFingers, I think that they may have been her main motivation, but she was really nice anyways, so..). As I told her about them, I'm pretty sure she was beginning to experience a desire for a pair of her own. Her main concern was whether or not she would be able to wear them all day, to which I replied with the warning on the Vibram website about gradually getting your body used to them.
I received more comments on Sunday, mostly in the "they're ugly" category.. I don't know why people think so, I personally think they look sweet. I also got comments both Monday and Tuesday at work. One of the ladies stopped me as I was leaving on Monday and asked what they were, so I exhibited them to the group that was standing there. One of the guys said, "They must be really comfortable, but they scare me. ... They're scary.". On Tuesday she stopped me again and had me show two other people. She made a comment about how we should all get them, but that may have been sarcasm.
All in all, the reception to them hasn't been to bad. I only hope my boss doesn't have a problem with them (he gets back from vacation on Monday).

Thursday, June 25, 2009

FiveFingers Day 4

Now that I caught up to today I can drop the date in the subject.. woot!
Gah! My calves are still really tight today. Stretch, stretch, stretch... eventually they have to loosen up again, right? It's a good thing that walking in VFF's is practically effortless.
I'm having a good day at work, but I just realized I forgot to make up a report so I'm going to end my break now and knock this thing out before the end of the day.

6/24/2009: FiveFingers Day 3

Argh! My calves are so tight today after yesterday's run. Wow, this is crazy. I've never had them this tight before. I drink a lot of water at work, so every time I took a bathroom break I also stopped and stretched my legs. Hopefully they'll loosen up pretty soon.
As always, the FiveFingers are great. No one has mentioned anything about them yet, so I'm not sure if they are just accepting them or have yet to notice them.
On a side note, my coworker brought his dog to work today.

I made a pot of rice for lunch - I took a box of rice and pinto beans from Save-A-Lot and added black beans, corn, and stewed tomatoes. Yummy! Hmm, saying "Yummy!" in my head made me think "Timmay!".
My bike is still not done, but it should be done sometime this week. I can't wait to ride it again.

This spring, I was planning on joining ARMA (http://www.thearma.org/) and learning how to use a sword. Then I got laid off and that got shoved to the wayside. As I now have a steady income again, I am once again looking into this. I think I will start by focusing on the Scottish Claymore Broadsword, which is really a basket-hilt broadsword and not a claymore... I'll have to get a wooden waster (http://www.woodenswords.com/WMA/baskethilt.broadsword.htm) and figure out something for a pell, but I'm quite excited. Eventually I'd also like to tie in the targe and dirk.

The Scottish Basket-Hilt Broadsword:



While I was looking up Scottish stuff, I looked up clans. The Reid surname is apparently claimed by Clan Robertson.. whether or not I'm related to that or not is unknown. My mother will likely know, as she is a genealogy guru. All I know right now is that I have both Scottish and Irish blood and some others that I can't remember.

6/23/2009: FiveFingers Day 2

I wore my FiveFingers to work today. On Vibram's website they recommend only wearing them for short periods of time, but since I already go barefoot a lot, I figured it wouldn't be an issue - and I was right. It was awesome to not have big, clunky shoes on all day. I'm able to step so much lighter that it's hard to keep from running everywhere. With the socks on, it feels a lot like wearing a pair of slippers - except my toes are free. Hopefully wearing these will help my toes spread out, as my two smallest toes have become squished from years of shoe wearing. I used to tie my shoes super tight so that my feet wouldn't slip around at all - too bad I didn't have these as a kid...

Work was great, I love the variety of things I get to do, the fact that I get to spend a lot of time programming, and the knowledge that my work is appreciated. They are very into expressing thanks here.

After work I went to the park to work out. When it came time for running, I ran 1 lap (1/2 mile) in my FiveFingers. As awesome as they are, they are definitely not the same as barefooting. I run in them the same I run barefoot, but while I was able to feel the ground underneath of me, it was a muted sensation; and although the FiveFingers are light and form-fitting, I was still well aware that my feet were not free. At the end of that lap, I stripped off my VFF's and tossed them in the car, then ran 3 more laps barefoot for a total of 2 miles. Not as good as my 2.5 mile run on Sunday, but on Sunday 4 of the laps were with shoes on so I was ok with it.
I felt really good when I finished my run, but my calves were quite tired. I wonder how they'll feel tomorrow.

I took my iPod out of my waistband to shut it off, and the screen was blank! When I pressed Pause, the song started stuttering. About this time I noticed the iPod was wet from sweat as well as being really hot. I stuck it in my car and pulled on my VFF's, then went over to the empty playground (although I was tired, the playground is never empty so I couldn't pass it up) and played around. I walked across the monkey bars, swung across their swingie thing (it's like monkey bars but with the round handles on chains that guy gymnasts do really cool stuff with) and then jumped and rolled off the other side. I decided that was enough for tonight and headed home, where I stuck my iPod in a bowl of rice to dry out.

I then jumped in the pool for a little while to cool down. I love swimming...
I spent the rest of the night playing Prototype and talking to Mor.

6/22/2009: FiveFingers Day 1

I picked up my first pair of FiveFingers (http://www.vibramfivefingers.com/) today. I was already enamored with the idea of them; in the time it took to run out to my car from the store, I fell in love with them.
I hope this feeling lasts as I continue to use them.
I looked for toe socks while I was at it, but the store didn't have any all black ones, so I decided not to get any. However, I changed my mind once I reached my car - after all, if I'm going to wear them to work I should probably have socks to go with them.
I went back and got a tan pair of socks; hopefully they don't feel weird.

When I got home, I went over to the back of the Save-a-Lot plaza and did a wall-run at my normal spot. I had previously tried to do this barefoot but failed as my feet are not yet tough enough. With the VFF's on, the wall wasn't an issue. The soles gave me great grip and I didn't feel any discomfort at all. I wanted to try it out more but I was a little sore from my run on Sunday so I decided not to.