Derek Sivers put it beautifully, here: http://sivers.org/io
This is my expiration.
Thank you Derek. Some day, I would like to buy you a coffee, and listen to how your week has been, in person.
Hey! I learned something!
Derek Sivers put it beautifully, here: http://sivers.org/io
This is my expiration.
Thank you Derek. Some day, I would like to buy you a coffee, and listen to how your week has been, in person.
I dug out my “massive” music collection, copied some good stuff over, and am currently running beaTunes – to detect BPM. Once that’s done, I have a smart playlist for the right ranges of BPM – I’ll use that to sync to the iPhone (I have an order of magnitude more music available than space) – then run PaceDJ to pick the songs at or near the pace that I want (I usually start at 160 and speed up to 180 during a longer run).
I’m already liking the music it has chosen so far.
First run with the co-workers tomorrow. I am a little nervous. They are all so athletic.
I was thinking ahead to next week, about what gear I will be running in. It got confusing, so I made a chart.
(Click to zoom in to the larger image)
S1 | Suunto Chest Strap | Captures heart rate data, sends to S2. Helps me regulate my pace and gives me blog posting material for the future. Deploys a protective armor nanoshield in case of attack. |
S2 | Suunto T6d | Super computer watch which receives all the data and logs it. It will also act as defensive laser in case of alien attacks. |
S3 | Suunto Foot Pod | Has a built in Accelerometer and FancyMoMancyMeter to tell me how fast I’m running, accurate to +/- 10% depending on calibration. Provides extra jumpjet fuel. Uses invisible ants to send signals up your leg and down your arm to the watch. No joke. ANTS protocol. |
SH1 | Technical Shorts. | TMI: These are the kinds with the built-in sweat wicking underwear. They have pockets that are designed to loose things when you sit in your car. I wish that were a joke. |
SH2 | Technical Shirt. | Probably from the Bourbon Chase or one of my other favorite race shirts. I like the loose mesh ones better than the tight mesh ones. Designed to make me radar invisible to the aliens. |
MS9 | Motorola S9 Bluetooth Headset | For listening to ma’ tunes from the Pace DJ. Also used for communication with central agency in case of emergencies. Volume and Track buttons. Skips in high humidity. Can be used on single ear only. |
TFMH | Tin Foil Metal Hat | Hopefully the aliens don’t invade on Saturday. |
IFB | iFitness Belt | To Store the I4S and some ID/Cash. If taken off and whirled in a circular motion, can create a kinetic shield to ward off flying kitten attacks. |
G1 | Powerbar Gel – Green Apple – With Caffeine | 25mg baby |
G2 | Powerbar Gel – Vanilla – No Caffeine | ‘cuz Caffeine is a Diuretic, and the aliens may mistake porta-potties as enemy tanks and destroy them first. |
G3 | GU Powergel – Espresso flavor | Hip Hip Hipster Hooray! (less runny than Powerbar gel) |
GCS | GoPro Chest Strap | I didn’t want the head mount, makes me look too techy and attract attention to myself. Seriously. Can double as an ammo belt for paper clips. |
GP | GoPro | Because recording video on my iPhone is not sexy enough. Will also spot creatures using phased light invisibility techniques because of the parralax they cause in the 117-th degree FOV filter. |
PDJ | Pace DJ | Scans existing music library for tempo – you don’t have to choose the music. Hopefully its all good. |
CB1 | CamelBak Hydration Pack | Only need to stop every 6 miles, and I never have to ask when the next water station is. Can also hold keys in the zipper part. Can be used to squirt water at the aliens, because most aliens are allergic to water, and they forget to scan before they invade. |
LSTS | Long Sleeve Technical Shirt | For when temperatures including wind chill drop below 50F |
TFFFHP | Tight Form Fitting Flab Hiding Pants | For when temperatures (including wind chill) drop below 40F |
GL | Gloves | To prevent attempting to warm hands in more publicly embarrassing ways. |
SJ | Sport Jacket | The kind with Mesh on the inside. Combine with LSTS to get it down to 35F or so. You generate a lot of body heat when running. |
WRH | Winter Running Hat | Keeps them ears and the bald spot warm. Bald spot is the center of brain activity, if it gets cold, the eyes glaze over. Machine Washable! Didn’t know I had sweat glands there. Oh wait, Thai Food. |
IEB | IPhone Ear Buds (new kind) | Cuz my ears are shaped funny, very few earbuds work; when wearing the WRH, the MS9 doesn’t fit, so I have to go wired. The square shape of the container helps differentiate them from a hockey puck. |
GAUBAC | Gawd-Awful-Ugly Big-Ass-Coat | Purchased at goodwill, to stay warm before the race and during the first few miles; abandoned during the route; also a decoy to confuse the aliens. Pink with leopard spots is awesome. |
Yep, I’m crazy. What the heck, I’m owning it.
In case you hadn’t figured out, italics = for fun, not real.
About a week ago, I participated in a 10k run.. and I happened to bring a (partially charged) camera. Turns out they’re a small organization, so after chatting to a volunteer, I took video of the race, and put this together to help promote them: (less than 3 minutes):
Geeky: It was challenging to put this together – I had to renew my subscription to Adobe Premiere CS6 to get access to the Warp Stabilizer effect to calm the running parts of the video down. (It worked very well).
Some other stuff I learned:
There’s a (much) longer video with all the footage I got, unedited, unstabilized, where you can learn more from the people who talked to me: http://www.youtube.com/watch?v=qtQm5Tu7WGM
The bicycle lady.. I had dropped my GoPro, she rescued it and brought it up to me. Thank you!
I’m thinking, this year as I do races, I’ll do little glimpses into the races .. to promote them. Because I think they are beautiful and cool and worthy enterprises. Especially the smaller ones.
Be good.
I don’t even know anybody who was running. My wife does. Yet I have been so freaked out?
I think I’m grieving the loss of innocence. Certainly not in me.. but maybe about this sport, Running, that I’ve just started doing. I don’t know what it is, but my heart is heavy. And my emotions have been coming out sideways… like really weird, wavy, driving, slamming the salt shaker down harder than normal, etc.
I had a different blog post in mind, something about a race I ran over the weekend. That can wait for later this week.
Geeky Side Notes:
Enough for today. Will try to focus back to work tomorrow.
I’ve lived near Louisville since 2006, yet, I am somewhat lost around downtown. I blame having a GPS – I never had to learn it.
Well, I’ll be spending more time downtown – with http://codepalousa.com/ and the KDF Mini Marathon being on the same day, I need to get back and forth between them without a car, and stop by the Downtown YMCA for a shower.
So I started playing to learn downtown better:
I almost always approach from I-71, so I set a start point there, and played with “to get to XYZ place, which exit does it have me take?” – the result is the above map (done by hand, though would be nice to have a program that did something similar.. showing the tree of routes, perhaps, into an area?). I was surprised at how versatile the Brook street / Jefferson street (green) exit was – and how much the 9th street exit (tan?) plays into it as well.
Would anybody with more time than me be interested in writing a google app that could represent the same information as above?
I had a project in mind – to pull information from basecamp classic (todo items, with metdata embedded), massage it in Excel, and then upload it back to basecamp.
I have always used Excel (or some equivalent spreadsheet) for project tracking – I never know which columns I need to add, when I need to highlight things in different colors, what kinds of charts I need to pull. So the decision to bring the information down to Excel was an easy one.
That cost me 1.5 days of pain.
In retrospect, it would have been much easier to use EF Code First against .\SQLEXPRESS and use SSMS to do the bulk of my editing. But, not having the time to re-tool, I pushed forward, and I did get it to work well enough to help me next week as I start work with that project…
Anyway, this is what I learned along the way:
Workbook.Save(); Workbook.Close(false); Application.Quit();
The recipe for closing down the instance of Excel that had been open. Without getting asked if I want to save.
Marshal.ReleaseComObject(sheets);
You have to do this for pretty much ever object you dink with, else the COM Excel wrapper stays open in the background. Reference: http://stackoverflow.com/questions/158706/how-to-properly-clean-up-excel-interop-objects). I haven’t fixed this yet.
Sheet.Cells[1,1].Value Sheet.UsedRange.Cells[1,1].Value
Cells start at index 1, not 0. UsedRange is faster than Cells.
var connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fullName + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES\"";
You can use ACE to query spreadsheet data, however, type-coercion is sketchy. As in, if you have no data, that long field will come back as string. I ended up ditching that and reading/writing my lists of stuff directly from the worksheet so I could have direct control over the types:
Worksheet sheet1 = b.Worksheets["Tasks"]; t2 = sheet1.ReadListFromSheet<MyTask>(); sheet1.UpdateListToSheet(t2, "TodoItemId");
public static List<T> ReadListFromSheet<T>(this Worksheet sheet) where T:new() { var nameToCol = GetNameToColumnDictionary(sheet); var colToSetter = GetColToSetterDictionary<T>(nameToCol); var result = new List<T>(); var rowCount = sheet.UsedRange.Rows.Count; for (int row = 2; row<=rowCount; row++) { var item = new T(); foreach (var e in colToSetter) { var col = e.Key; var setter = e.Value; var o = sheet.Cells[row, col].Value; if (o == null) continue; Type source = o.GetType(); var target = setter.GetParameters()[0].ParameterType; try { object o2 = null; if (target == typeof(bool?)) { o2 = Convert.ChangeType(o, typeof(bool)); // bypass the null stuff } else if (target == typeof(int?)) { o2 = Convert.ChangeType(o, typeof (int)); } else if (target == typeof(DateTime?)) { o2 = Convert.ChangeType(o, typeof (DateTime)); } else { // this generic conversion seems to catch most everything o2 = Convert.ChangeType(o, target); } setter.Invoke(item, new object[] {o2}); } catch (Exception ex) { Console.WriteLine("Need to handle from type: {0}, value:{1} to setter type: {2}", source.FullName, o.ToString(), target.FullName); } } result.Add(item); } return result; } public static void UpdateListToSheet<T>(this Worksheet sheet, IEnumerable<T> lists, string pkColumnName) { pkColumnName = pkColumnName.Trim().ToLower(); // Grab the list of columns var nameToCol = GetNameToColumnDictionary(sheet); // get a mapping from list member to column number / vice versa var colToGetter = GetColToGetterDictionary<T>(nameToCol); // grab the mapping of pk to row number if (!nameToCol.ContainsKey(pkColumnName)) throw new Exception("Could not locate primary key " + pkColumnName + " on sheet " + sheet.Name); var pkColumnNumber = nameToCol[pkColumnName]; var pkToRow = new Dictionary<string, int>(); var emptyRows = new List<int>(); for (var r = 2; r <= sheet.UsedRange.Rows.Count; r++) { var pkValue = sheet.Cells[r, nameToCol[pkColumnName]].Value; if (pkValue == null) { emptyRows.Add(r); } var test = pkValue.ToString(); if (test == String.Empty) continue; pkToRow[test] = r; } // get a direct line to the getter of the pk if (!colToGetter.ContainsKey(pkColumnNumber)) throw new Exception("Could not locate primary column in DTO????"); MethodInfo pkGetter = colToGetter[pkColumnNumber]; // write the list contents into matching column names in the spreadsheet, updating as we go foreach (var item in lists) { var pkVal = pkGetter.Invoke(item, null).ToString(); if (String.IsNullOrEmpty(pkVal)) continue; // inbound item has no PK // figure out which row to write to int rowToUpdate = -1; if (pkToRow.ContainsKey(pkVal)) { // row already exists .. update it rowToUpdate = pkToRow[pkVal]; } else { // row does not exist .. append it if (emptyRows.Count > 0) { rowToUpdate = emptyRows[0]; emptyRows.RemoveAt(0); } else { rowToUpdate = sheet.UsedRange.Rows.Count + 1; } } // write it out foreach (var e in colToGetter) { int col = e.Key; MethodInfo getter = e.Value; var o = getter.Invoke(item, null); // any translations from .Net to Excel would happen here - none so far sheet.Cells[rowToUpdate, col] = o; } } } #region Private private static Dictionary<string, int> GetNameToColumnDictionary(Worksheet sheet) { var nameToCol = new Dictionary<string, int>(); for (var c = 1; c <= sheet.UsedRange.Columns.Count; c++) { var columnName = sheet.Cells[1, c].Value; if (!(columnName is string)) continue; if (String.IsNullOrEmpty(columnName)) continue; columnName = columnName.Trim().ToLower(); nameToCol[columnName] = c; } return nameToCol; } private static Dictionary<int, MethodInfo> GetColToGetterDictionary<T>(Dictionary<string, int> nameToCol) { var colToGetter = new Dictionary<int, MethodInfo>(); var properties = typeof (T).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var p in properties) { if (!p.CanWrite || !p.CanRead) continue; MethodInfo mget = p.GetGetMethod(false); if (mget == null) continue; var lowerPropName = p.Name.ToLower(); if (!nameToCol.ContainsKey(lowerPropName)) continue; // not present in target xls colToGetter[nameToCol[lowerPropName]] = mget; } return colToGetter; } private static Dictionary<int, MethodInfo> GetColToSetterDictionary<T>(Dictionary<string, int> nameToCol) { var colToGetter = new Dictionary<int, MethodInfo>(); var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var p in properties) { if (!p.CanWrite || !p.CanRead) continue; MethodInfo mset = p.GetSetMethod(false); if (mset == null) continue; var lowerPropName = p.Name.ToLower(); if (!nameToCol.ContainsKey(lowerPropName)) continue; // not present in target xls colToGetter[nameToCol[lowerPropName]] = mset; } return colToGetter; }
I’ll post more later on what I was trying to do. I did finally get it to work. Sketchy as it all is. I love that word Sketchy… thank you Rutledge Wood!
Now I have to go pick up my race bib for a 10 mile race tomorrow.
I found an app, The Photographer’s Ephemeris, and in playing with it I figured out that I could predict when the Sun would line up with certain landmarks. So I decided to try it with Downtown Louisville. I set a reminder to myself.
And promptly forgot to bring my Video Camera in that day. It was Friday 3/29/2013, and the sunset was gorgeous.
No problem, I’ll just catch it the next day.
Saturday 3/30 – Overcast and hazy. That’s #3 in the video.
Sunday 3/31 – Beautiful Sunset. I skipped part of Louisville NCAA Madness to set this up. User error – it didn’t record.
Monday 4/1 – Pretty good. That’s #1 in the video. Pulled back from my first attempt. Every 5 seconds
Tuesday 4/2 – hazy, skipped.
Wednesday 4/3 – Not quite as good. #2 in the video. Pulled even further back. Every 2 seconds, but I sped it up for the video.
The video is in 1080, so fullscreen is best.
By this point, the sun had slipped away from being lined up with downtown; and I had figured out that the stock zoom lens on my camcorder does not make for a great picture in low light conditions. So ends that project; I’ll resume from a Tripod on the Pedestrian Bridge later in the summer… sun reflecting off the buildings.
a. I have been very impressed by the “Crash Course” channel on YouTube – http://www.youtube.com/user/crashcourse
b. When I first started using FL-Studio, most videos were either too slow, too vulgar, or not broad enough. So, once I learned to use the system, I felt the need to make my own crash course video on the subject.
c. After two takes and a lot of editing, I think its “good enough”.
d. If I could make my living at making instructional things fro people who wanted to learn them, wow, sign me up.
Here it is:
[youtube http://www.youtube.com/watch?v=OoGCbciUQ0c&w=560&h=315]
I did learn while doing this:
1. Its better to talk and demo at the same time, rather than reading off a script and then trying to match the demo to the script later.
2. Youtube “links” to things can only go to other Youtube or Google things. So, I couldn’t link to a wikipedia article, for example.
3. I’m an engineer, not an artist.
In 2010, I started running. I started at a max distance of 0.25 miles; ran into shin-splints; did a bunch of research, bought some Vibram Five Fingers, and ran my first 5k in 36 minutes or so. I (too) rapidly progressed to running the Bourbon Chase that year, and in 2011, I competed in the Louisville Triple Crown of Running. At the time, I was pretty well conditioned (for me).
2012, nada. I had a knee injury late in 2011, and didn’t do much of anything.
2013, I’m back in running form.. just barely. I started a few weeks ago, I’m barely keeping up with the distance I need for the Triple Crown. The 10k is tomorrow morning.
I have heart rate data from both years:
My take-away is that purple is shifted to the right of blue – I could go faster at the same heart rate, back then.
Here’s a slightly different view, courtesy of the free-compare tool at www.movescount.com – which came with my kick-ass Suunto t6d watch.
There is a direct relationship between heart rate and speed.
According to the book “Total Heart Rate Training” there’s also markers of heart rate zones to be found. Here’s my interpretation of it, augmented with data collection devices:
Anyway, the heart rate training book talks about this in depth. My understanding:
To improve performance, you need to keep your heart rate UNDER that elbow of “B” but near the top of it. This helps nudge it upwards, which gives you more range to go faster for longer. And it will get your muscles accustomed (built up) to that kind of workload.
To improve endurance, you need to train with your heart rate closer to “A” (just north of it). This also helps improve “B”, but then your (leg) muscles will need time to catch up.
Caveat: I tried this out with a friend who is VERY much out of shape. While Walking, he got to his A point. As SOON as he started jogging, he crossed “B”. He needed a lot more heart toning before he would be ready for jogging. My suggestion to him was: Get to walking 4 miles comfortably, before you start trying to jog for one. And then when you jog, jog slower than you walk.
Double Caveat: The other really awesome exercise for running if you can stand it, is the Hundred Up. Helps with all the muscles and landing your feet.