Enjoying Git

My current client uses an (onsite?) enterprise github thingy. We do basically branch-per-feature, which means a lot of merging.  And surprisingly few conflicts.   I find myself constantly going back to this graph:

image

It’s not available on the free public github, AFAIK.    You can see where people pulled from Refactor back into their feature branch, and how much context switching there is (we have two folks working on the project).

A video that really explained git to me was this:

[youtube=http://www.youtube.com/watch?v=1ffBJ4sVUb4&w=448&h=252&hd=1]
Awesome Git Video!

It highlighted the directed graph structure, and the role that nodes and labels play.  After watching it, I understood Fetch, Pull, Push, Add, etc – it all made sense! 

However, I’ll confess – I’m using tortoiseGit, not the git command line.  

FortressCraft Evolved: Tier 1 Tour

I am continuing to thoroughly enjoy FortressCraft Evolved, an early-access game on Steam.   Just about every week, I wait in anticipation of the stuff that DJ Arcas is putting into the game.  This last time, it was an auto-excavator to automate creating large vertical shafts and a conveyor belt builder. 

The final vision of the game is something where there is a definite resource-gathering, base-building, automating story, combined with a Tower-Defense game as the local Fauna try to dispatch your base (and you).  

I’ve probably worked on 4 or 5 worlds now.  Every time, I learn of something I could do better, and then I have the desire to start over and be more “perfect”.   68 hours into the game now.  And I only just (last game) got down to Tier 2 technology, and there are three Tiers so far that I could play with.

Here’s a tour of my latest world, with my preferred way (so far) of doing things.  This is at Tier 1 level, probably 3-4 hours into the game.

Central Power Hub and Smelter

image
Back
image
Front
  • I’ve ended up putting a coal storage hopper under the Central Power Hub (CPH) (the thing with the laser shooting out of it).  The CPH draws coal from it to burn to create energy.
  • I then put a Pyrothermic Generator (PTG) next to the hopper.
  • Both the PTG and the CPH burn coal to generate energy, and charge up the battery (big block with a sphere in it).  It seems like between the two of them, they can generate energy at about 10 units per second?  (I’m averaging more like 7, but I’m not running it at max capacity yet).
  • This provides enough energy to run the smelter (front picture, “insert more ore”), as well as send enough power down the single laser to the rest of the base (only ore extractors right now).
  • The smelter takes in raw ore from the hopper below, and deposits the smelted bars into the hopper on the right (Front view).  If I need to leave for a while, the hopper on the right gets a conveyor leading to another hopper so I can keep collecting while I’m AFK without the system backing up.
  • A single conveyor belt brings the ores in.   This is enough for 4 types of ore, at the first upgraded level of drill motor (which means it generates 4 ore every N seconds instead of 2).  
    • At first, I though “meh, why build an upgraded drill motor when I can just build a 2nd extractor for cheaper”.  But, when I got to the 4x and 8x drill motors, I understood the wisdom of investing early.

Vertical Access Shaft

image
The Roof
image
Looking Down
image
Looking Up
image
Important Floor (Looking down, mid-fall)
  • My first worlds were wide more than they were tall.. at first.  What I found when digging down is, you very often hit an ore vein on the way down.  So now, I pretty much try to dig down rather than out, in search of ore. 
  • I rely on the grappling hook (F) to get me back up.  I use two torches on the roof to signify “which way is out” (its easy to get turned around) (See the “Looking Up” picture in more detail)
  • Now that we have falling damage (just this last week!), I have to build in ledges along the way to jump down to.  Note that once I have a battery at a level, I can jump and take the fall damage (energy loss) and then recharge from the battery.   I always put a torch under the ledge.
  • My guess is in the future, the grappling hook fire distance will be decreased and I’ll have to build room for lifts.
  • I line one side of the shaft with power, and the other side with conveyors.  Right now, I’m only at tier 1, so a single laser is enough going down, and a single conveyor is enough coming up.  So far, the most I’ve needed is 3 lasers and 2 conveyors, but I haven’t gotten very far.
  • Any level always has a “lip” around it, for safe landing purposes.

Floor / Level Exit from Shaft

image

  • I send power down into a battery, and then send it right back down the shaft again in the same vertical line.
  • Note that if ores block the laser’s path, sometimes I manually dig through the ore, or else I’ll shift the shaft to the left or right to accommodate. 
  • At higher power levels, I set up the lasers next to each other, and likewise a receiving bank of batteries.  Because the batteries share with each other, it evens out the power flow at that level.
  • I try to dig my conveyors one deep from the floor so I can walk over them with impunity.   I have to route them to the other side of the vertical shaft to keep them out of the way of the lasers.
  • I started to build lasers so that they were above my height, however, I’ve given up on that now.  Its just easier at ground height.

Coal Generation and PTG’s

image

  • I’ve found that for up to 5-6 PTG’s, I can have a single extractor generating coal onto a conveyor belt that then leads to the PTG’s. 
  • Long before I get to my 2nd or 3rd PTG, the coal generation has exceeded storage space and there’s plenty of coal for all the PTG’s.
  • It takes about 3 PTG’s to fuel the max capacity of 2 unaltered T1 lasers. (30 vs 32).   Until you build a second smelter, or an autoexcavator, you don’t even approach the halfway point of a single laser.
  • In this case, rather than send power to the coal extractor via laser, I just added a PTG right there.  This was the second vein of coal (having exhausted the 10-coal courtesy seam that the easy level gives you), and it was only 13-15 conveyors away from the base.

 

That’s all I have time to share at the moment.

I wanted to make an actual log of the first few hours of gameplay – like “what task was I trying to achieve” and how quickly I could achieve it – however, I have run out of time, so that level of documentation will have to wait.  What I can say is that the tasks changed very quickly, every 5-10 minutes.  Besides, this is version 1.14e, which is far from the finished version, so the task list will likely change a lot in the future.

I am still super-excited about this game, and I eagerly await the next drop (bombs!!!??) and the eventual mayhem when mobs become antagonistic.  (I hate camo-spiders already.  They scare the goobers out of me. sneaking like that.  Worse than creepers)

As I sit with an ice pack in my armpit…

image

I saw my masseuse, Travis, today.     We worked on two problem areas that I have:  a) I have lower back pain when standing, and b) I have shoulder pain when I reach for things in front of me – like putting away dishes, or retrieving a glove from the dashboard where I had it heating.   (First snowflake of the season today!)

We worked a lot on my Coracobrachialis muscle – aka “Beer Drinking” muscle.  An audio commentary of the session would have to include things like “[whimpering sounds]” and “[sobbing]”.  I have been forbidden from doing any pull-ups.

I’ve been given a list of muscles to work out before I see him again, in order of priority:

  • Lattimus Dorsi
  • Trapezius
  • Hamstrings
  • IT band stretching

The general idea is this:  Due to years of sitting, I have built up certain muscles over others.  Now that I am standing a lot more, some of my secondary muscles are having to take over for my unequal primary ones. They burn out faster, and thus – pain. 

Time to go read up on ways to lengthen and strengthen the above. 

Fortresscraft Evolved

I have been playing a game called “Fortresscraft Evolved”, an early access (developer still working on it) game that my coworker Mike mentioned at lunch the other day.  I really enjoyed Minecraft, so I decided to give it a try.

It has given me an entirely new build order to investigate.   And, there’s a lot of “routing” to think about.   I’m loving it.  (Note, I’m specifically playing survival mode)

There’s a ton of tutorials out there.  I’m not going to do a tutorial.  But I am going to mention a bunch of things that I learned about, to calculate (for myself) an optimal build order.   Granted, “optimal” really means “suited to my liking”, and granted, the furthest I’ve gotten in the game is to automate coal retrieval, but, this is where my thoughts are at.

Here were my most recent questions:

Extractor Priority

You start off with 3 extractors, but there are 4 initial ores to think about – Coal, Tin, Copper, Iron.   Which one to ignore?

At first, this question was complicated by me not knowing about super dig.  (link,  scroll down to “The Extractor”).    Given superdig, where you convert 1 energy for 1 dig (run out of energy fast) for a x% possible resource gain, I can quickly get about 40-50 ores out of a vein with the power that my suit holds.

This means that ore extractors are more for having a “passive” gathering strategy – power dumped in now, yields ores later, that you can go pick up – and in the long term a more efficient one (more ore gets salvaged, less destroyed)

To determine what I want, I choose my end goal:  I want to

  • automate getting coal from the coal vein to the furnace to generate power.  (2 storage hoppers, and 40-50 conveyor belts)
  • put a storage hopper by each extractor (tin, copper, iron = 3 storage hoppers)
  • build an extra extractor so we have an extractor on each vein (1 extractor)

I could also assign a bonus goal of automating delivery of tin, copper, iron to the smelter – I think for that I’d need 200-300 conveyor belts, and +2 storage hoppers (one for holding the ore, one for holding the bars).  I’ll also need a bunch more torches.  And some suit upgrades.   Here’s the spreadsheet I put together:

image

So, it looks like Coal, Tin and Iron should should get your initial extractors; and then Copper when you build one for it later.    This is all prior to the search for Lithium, which I’ll make a separate spreadsheet for later, if I get that far.

* Note: this list is already out of date.  Watching the author play, turns out that PTG’s are better at power generation than CPH’s, so I should really add a PTG to the above list.

Ore Discovery

Unlike Minecraft, this game has an Ore pinger/scanner.  Problem (for now) is that it either pings (a) Unknown ores, or (b) Known Ores.   Once you discover an ore, to find a second vein of that kind of ore becomes problematical – too many positives.  The solution suggested online was, when searching for a new ore, ONLY research it after you have found a LARGE vein.    Note that you will probably find things in this order:

a) Snow, Rock, Dirt, Leaves, Trees, Stone
b) Coal, Tin, Copper, Rubble
c) Deep Stone  (heh.  Nice one, DJ – pisses me off every time)
d) Iron.

Vertical Navigation / Getting to the Ores

My first attempt, I started building the standard “stairs” down to get to an ore.  It took a while.   I did not know about the grappling hook.  Which might get nerfed in the future.

Second attempt was to build an elevator shaft, but have a ledge at the top, so that I could grapple my way out of the shaft.    I would strategically place lights so that if I’m facing a light, that means it’s the way out.    However, I was being pretty at things, and that took a while.

Third attempt, I used super dig (ctrl-right) and zoom (Z) to my advantage

  • Do not dig straight down unless there was a ceiling above me that I could grapple back up to.  Instead, try to dig at an angle.
  • After locating an sizable vein of an ore, either super-dig, or hold down the dig key, and just dig towards that ore, not being pretty about it.  The idea is to be able to run/fall down to the ore.
  • Build a “wall” at the entrance of the hole to grapple back up to.
  • On subsequent visits to the ore, clean out annoying blocks and add in some lights on the way.
  • Make it pretty when doing conveyor belts.
  • Use a hill as a natural backdrop to grapple back up to.

It also appears that as you are falling, you can still control your fall using WASD.   Watching the main developer DjArcas play on twitch, he builds these large chevron beams (probably using build-to-me Ctrl-Left) that he somehow jumps down onto (without missing).   (If you watch the episode from 10/25/2014, at about 2h:30m or so, he’s building things / starting this world out)

If you are lucky enough to find a large cavern, dude, You’re in luck. 

 

Ok, enough for this blog post.   I am enjoying the game, its got a nice build order story and some nice layout challenges for laying out conveyors and power and stuff.    Recommend playing, I’ve gotten a good 10 hours of play out of it so far (and I think its $9 or so).

LA Trip: Gastronomical, Dude

imageI love to eat.

I just got back from Los Angeles – my wife had a conference (http://genblue.coldwellbanker.com/) to attend. We made sure to put in as much interesting food into the trip as we could.  In no particular order other than me remembering them;  links to the ones I would recommend.

(Note: Picture used from my wife’s instagram feed)

In & Out Burger – D Double and Fries Tasted like a Big Mac.  Fries were almost like baked fries, but fluffy and with substance.  Delicious!
Jamba Juice – B, B, B OJ x 4 Love the fresh squeezed OJ.  I think we went almost every day, except for the day we went to Vivian’s.
Starbucks – C, C, C Pike Place Coffee Better than the stuff at the Hotel; not optimal, did not have a chance to find a local roaster.
Cabo Wabo – D Corn Cob
Caborita
Delicious.  The drink was not as good.  Would not recommend, there’s much better fare around, unless you’re on foot with nowhere to go and you need to entertain people.
Bubba Gump Shrimp Co – D Shrimp Collection
Fish Taco
The Fish Taco was much better than the Shrimp
Wolfgang Puck – L Spaghetti with Meat Sauce eh, ok.  Once again, tourist trap, nowhere else to go.
Vivian’s Millennium Café – B Pancakes and Sausage and stuff Little mom and pop diner; Food Good.
Healthyca – L NoHo Sausage Sandwich Very Good. (NoHo = North Hollywood) (Sausage and caramelized onions)
Homeboy Café and Bakery at LAX Terminal 4 – L Californian (Turkey, Avocado, 7-Grain bread) Delicious
Farmer’s Market at Grove – Brazilian Buffet – L (bunch of stuff) Decent food.  I recommend going here just for the diversity.  I did NOT get to try paella, or singapore stuff, or .. (lots of choices)
Umami Burger – D Truffle Burger, Home Made Ding Dong I apparently don’t like Truffle anything.  But the Ding Dong was great.
D’Lush – S Thai Iced Tea Delicious!

Fair warning, there’s a lot of LA stuff that I could post about. 

[S|V]andalizing some Flip-Flops

I has modified some Fleep-Flawps.

2014-10-04 19.09.56

My wife thinks I’ve lost my mind.   She refuses to be seen with me, or let me be seen by others, wearing them.  That’s okay, I can live with that.   In-house only.

Points being:

  • That is elastic shoelace cord .. without damaging the shoelace (no cutting!).   They were removed from another pair of dressy brown sneaker-like things – replaced with black elastic to make them blend in a bit better.  (Once again, a stylistic difference between my grown up and my inner juvenile)
  • They don’t flip or flop anymore either.
  • It holds the flip flop sandal snug up against my inter-toe’s.  I can even run in these things.
  • I don’t have to squish my toes to hold on to it anymore.  I can let my feet spread apart.  This is functionally very good for me.  (Here’s why toe-hold is not so good)
  • It’s a zero-drop solution – which is what I’m used to.  Try finding sandals which have no drop.  Just try.  We spent the day at DSW, Off Broadway Shoes, and Quest Outdoors, and not a single fudging pair has zero drop.   (Keens has a pair that comes close, but they didn’t have it in my size)    [Drop == the front is lower than the rear, or a “heel”.  I cannot handle heels anymore, my feet have grown back to barefoot-comfortable state]
  • The backs stuck out too far – so I measured it, and cut it off, with a pair of scissors.   Yet another reason why my wife won’t let me be seen in these.

I think that if somebody came up with a simple velcro loop thing, and some good marketing, they could make a possible killing with it.   If you do this, I just want a few pairs, thanks.  Maybe I’ll learn how to sew.  Hmm.

(I love my life, and my wife, btw)

Standing Around…

imageLong story short, I’ve started trying to stand almost all the time at work.

It all started when I saw some of this show:

There are two free episodes – about 2 hours worth.  It was awesome enough that the Wife and I bought it, and we’ve been consuming it at home, an episode every few days.  Not through it yet.  However, that took me over to his website and Youtube channel:

He has SO MUCH stuff out there, it’s a bit overwhelming.

At the same time, after a lot of asking the wrong people the wrong questions, I finally got in to see a Urologist, who gave me a diagnosis:  Prostatitis.   Possible cause: sitting too much.   Lots of Truckers get it. 

So, I made the decision to stand at work, as much as possible.

In order to do this, I had to learn how to stand:

  • Tighten up the abs.  Like, lightly punch yourself in the stomach. 
  • Screw my feet into the ground so that my toes would go away from my midline – this also tightens up the butt. 
  • Bring everything back to 10%, 20% tightness
  • This is stable position.

I got (had) some equipment to help:

  • Work had already provided me with a geek desk – adjustable height desk.
  • Get a gel standing mat from Bed Bath and Beyond. 
  • Yoga block – to prop my foot up from time to time.
  • Fancy keyboard
  • Tackball
  • Eye level monitors (monitor stand provided by work)

Also some other habits

  • Walk barefoot most of the time.    Luckily, at my work environment, shoes are very optional. 
  • Switch back and forth from right hand mouse to left hand trackball, every few days. 
  • See a good Massage Therapist.  This guy, Travis: http://elementsmassage.com/louisvilleeast/our-therapists/id/5577/travis   knows his stuff.  
    • Side note: a massage with him, for me, usually involves pain-threshold numbers, and lots of muscle names.  One of these days we’ll work through everything – we’ve already visited the scapulae, the tersis major/minor, and currently working on pec minor and some calves and some hip stuff that I can’t remember the name of.
  • Continue to see a good chiropractor

The Result

  • My right hand is no longer numb
  • My lower back no longer hurts when I stand
  • My belt is tighter.  I don’t know how many pounds yet .. too much variability – but I’m definitely 1 belt notch tighter.  Without any other exercise.

Thoughts

Chiropractory vs Massage Therapy vs MobilityWod:

I used to think that Chiropractory by itself was good enough – I’d just have to go back and get a tune up every few months.   What I’m understanding now is that if I have soft tissue problems going on – and my body adapts around those creating other overly used muscles – my body will try to drag my spine out of position.  Once the spine goes out of position, then other muscle problems happen, and .. pretzel.

Now, with a) using my muscles properly – core muscles to provide straightness rather than relying on soft tissue slump;  b) not sitting – see below, and c) a therapist to squish and crush the lactic acid crunchies in my system, for the first time, after a month away from the chiropractor – I didn’t feel like I needed an adjustment.

I went anyway, and I had a beautiful adjustment.  Lots of crackling.  We started working on shoulder and hip adjustments.

Its not perfect yet – I’m doing something wrong for my Lats and my Hip, there’s a spot that keeps forming there.  And my right shoulder.   But it’s a LOT better. 

Standing, Lactic Acid, Warm Up, Walking

After standing all day, the bottoms of my feet can get a bit sore.  And then I go and see the therapist, and he has to squish all this lactic acid out of my system.   Not right.

Turns out, “warm up” and “cool down”:  Think of the Lymphatic system as a network of sponge.  It doesn’t have any motors.. it takes the body moving to start the squishying process that then moves the stuff around.   That’s the purpose of warm up and cool down – to get the lymph moving.  So If I stand for a while, and then go for a 2 mile walk – the first mile, I’m sore.  The second mile, I’m fine! 

I can’t just stand, I have to move.   And move for a while.

Standing vs Sitting Caloric Burn

Supposedly, a person burns 0.7 calories/minute more while standing than when sitting down.   Or, use this handy calculator:  http://www.juststand.org/Tools/CalorieBurnCalculator/tabid/637/language/en-US/Default.aspx

That adds up to around 1700 calories a week for me.  1 pound every 2 weeks.  That seems about right.

Sitting

What is involved in keeping your body straight while you are sitting?  Not that you keep your back straight, usually people slouch anyway.  According to that dude mentioned above, It involves your Quads (front of your thigh) and your Psoas (behind the 6-pack).   They stay on, like, all the time.   And sure enough, I had these really tight quads, and a lot of lower muscle back pain – I’m guessing the lower back strain was to counter the Psoas?

And that’s the other thing – to keep back straight while sitting, its harder than when standing?   I can’t prove any of this.. but, yah, that’s why we slouch when we’re sitting.  And if you slouch all the time, your body says: here, let me help you:  and it stiffens up the back of your neck with fatty tissue…

Yeah.  It’s a bummer.  Better to squat. Smile Or If I’m going to sit, I’m going to sit back and let my back be supported by the chair.

Do NOT walk Duck-Footed

Very much a side thing – as a result of watching @MobilityWod, I now cringe every time I see somebody walk, or run, or bicycle, duck-footed / knees bowed out.   Its pretty bad for you.    Click over to this article (from whence I grabbed the image) for more awesomeness: http://www.crossfitworks.com/archives/4797

In Other News – my Soylent Shipped!     Time to get that project off the shelf I stuck it on.

PS: That was the BEST picture I could find of me standing.   I have a ways to go yet.

OpenCV: Or Not

I was hoping this would be a blog post about some wonderful stuff I was doing in OpenCV about detecting the location of soccer balls in video.. for the purpose of writing a robot that controls the Pan-Tilt-Zoom of the video camera to automatically follow the action in a soccer game so that I don’t have to (Lazy)

However, the program keeps hanging.

I started commenting out code to figure out what I was doing wrong.

Here’s the final version that hung:

using OpenCvSharp;
using OpenCvSharp.CPlusPlus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OpenCvTest
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("Hey");
                //using (var cap = CvCapture.FromFile(@"00026.MTS"))
                //using (var cvWindow = new CvWindow("output"))
                //{
                //    var size = new Size(9, 9);
                //    while (CvWindow.WaitKey(10) < 0)
                //    {
                //        using (IplImage imgSrc = cap.QueryFrame()) 
                //        using (IplImage imgSmall = new IplImage(new Size(640, 480), BitDepth.U8, 1))
                //        using (IplImage imgGray = new IplImage(imgSmall.Size, BitDepth.U8, 1)) 
                //        {
                //            cvWindow.ShowImage(imgSrc);
                //            Cv.Resize(imgSrc, imgSmall);
                //            Cv.CvtColor(imgSmall, imgGray, ColorConversion.BgrToGray);
                //            Cv.Smooth(imgGray, imgGray, SmoothType.Gaussian, 9);
                //            using (CvMemStorage storage = new CvMemStorage())
                //            {
                //                CvSeq<CvCircleSegment> seq = imgGray.HoughCircles(storage, HoughCirclesMethod.Gradient, 1, 100, 150, 55, 0, 0);
                //                foreach (CvCircleSegment item in seq)
                //                {
                //                    imgGray.Circle(item.Center, (int)item.Radius, CvColor.Red, 3);
                //                }
                //                cvWindow.ShowImage(imgGray);
                //            } 
                //        }
                //    }
                //}
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
            }
            finally
            {
                Console.WriteLine("Done");
            }

        }
    }
}
  • If you look closely, you’ll realize that all the lines are commented out.    And it still hung.  
  • 1 Reboot later:   Nope, still hanging.
  • Remove references to OpenCV:   Still Hangs.
  • Turns out if I run it without the debugger, its okay, but running it under the debugger, it hangs.

Well, La De Derp.   I don’t like it when things like Debugging don’t work.   Makes me .. trust things less.  Granted, this is Visual Studio Express.  But still!    Back to Console.WriteLine debugging for now…

Here’s some links to some code:

What I’ve learned:

  • In the future, I’d probably use another library – EmguCV?   Seems more mature?  
  • I might be able to use a <insert technical terms here> (other forms of detection – FAST something? BURPY something?  I remember not exactly) .. something which can use a single image to train from using 64 dimensional wavelets.  Woo.    Not today.
  • I have not researched PTZ Apis
  • I don’t have a solution for splitting the stream from capture to video and capture to ball detection
  • I’m not sure about the easing functions that would be involved, there’s quite a delay from detection (if I ever do) to movement
  • I’m not sure what to do with the ball kids playing with soccer balls at the sides of the field.

Day at the Office: Naming Anonymous Types

I ran into a problem yesterday.  I’m in the middle of a large routine.  It looks at a set of projected changes and determines, if the changes were applied, what would the errors be.  Most of these errors have to do with balances going out of bounds, so there are several balances rolled up at various levels.

Where It Started

At first, I created several Dictionary<??,decimal> of balances like this:

var balance1 = .... 
 .GroupBy(t=>new { T.ClientId, T.CommmodityId, T.BucketId })  
 .ToDictionary(
    g=>g.Key, 
    g=>g.Sum(x=>x.Quantity1)
    ); 

The Problem

The code grew, exceeding 300 lines of code in one routine.  Time to refactor.  However, when I refactored, it did not know what to name my anonymous type, and I got this:

void PerformFancyMath(Trade t, Dictionary<??,decimal> balances)

More detail and other options here:   http://stackoverflow.com/questions/6624811/how-to-pass-anonymous-types-as-parameters

Not A Problem!  I’ll stop using the anonymous type, and create a helper class for it.

My first attempt was something like this:

public class DooHickey { 
    public int ClientId { get; set; }
    public int CommodityId { get; set; }
    public int BucketId { get; set; }
}

However, this does not work, because DooHickey does not define Equals() or GetHashCode(), so the dictionary doesn’t know how to match keys together.    

I hate writing those boilerplate bits of code – I like F#’s idea where it defines these for you, same as C# anonymous types.

My Solution

Rather than writing out that code, this is what I did instead:

public class DooHickey : Tuple<int,int,int> { public DooHickey(int a, int b, int c):base(a,b,c) { } /* This bit is not really necessary, but could be done

public int ClientId { get { return base.Item1; } } public int CommodityId { get { return base.Item2; } } public int BucketId { get { return base.Item3; } }

*/  }

  • I didn’t realize I could have a Tuple with 3,4,5 or more constituents.
  • The Tuple handles GetHashCode() and Equal().

Now armed with my helper class, I was able to refactor my code and bring my methods down to under a screenful each. 

Success!

A Day at the Office: Sql Loops, Dapper Query Multiple

My wife pulled me out of the office today, to take her to the State Faire.  However, right now, she’s meeting with her coffee girls.  So: I can put some stuff that’s been brewing in my mind into a blog post.

Working with somebody I had not worked with before, I am learning a lot of interesting things:

SQL Loops

We’re working on getting data from hundreds of sites, pooling it, aggregating useful information, and then reporting it.  The size of the pooled data is around 25 million rows, and will grow by several million a year.  

When we change how the aggregation works (new math, new metrics), we have to delete all the aggregated data and re-aggregate.    Due to foreign keys and such, truncating the tables is not an option (from a sproc, at least).  A straight delete took forever and gave us no feedback.

My coworker used this construct to provide a way to measure delete progress:

Version 1:

while exists(select top 1 TrooperId from Trooper where TrooperId > @TrooperID)
begin
  select @TrooperID = Min(TrooperId) from Trooper where TrooperId > @TrooperID
  DELETE FROM [aggregated].[Statistics] where TrooperId = @TrooperID
end

I have never done a while statement in SQL before.  Very elegant.  It got around most of the problem of trying to delete too much without any feedback. 

Even better, the next time I looked at the source, I found something else:

Version 2:

WHILE (1=1)
BEGIN
    DELETE TOP ( 10000 ) FROM [aggregated].[Statistics]
    IF (@@ROWCOUNT = 0)
         BREAK
    --WAITFOR DELAY '00:00:02'
END

Even simpler!

A Case for Simpler Dependency Injection

I’m used to code like this:

private readonly DbConnectionProvider _dbConnectionProvider;
private readonly ITrooperGetQuery _TrooperGetQuery;

public TrooperAccessGetQuery(DbConnectionProvider dbConnectionProvider, ITrooperGetQuery TrooperGetQuery)
{
	_dbConnectionProvider = dbConnectionProvider;
	_TrooperGetQuery = TrooperGetQuery;
}

Any dependencies your code has on other components, get “injected” into your constructor.   Usually used along with a Dependency Injection library; to call this code, you would do something like: 

var query = IoC.Get<ITrooperGetAccessQuery>();

Or, alternately, would in turn take a IITrooperAccessGetQuery parameter in their constructor, and rely on the person calling them to make the decision…

.. bubbling up all the way till you get to some magical code in the app that ties everything together.  Somewhere else.   This has always annoyed me.  

With this approach, seems to be that a) constructors get really large and unwieldy, and b) “what’s going on” is spread out between where DI is set up and where it is consumed(*)

(*) Some would argue that’s the whole point of DI. 

Anyhow, I found this style code which needed access to the TrooperAccessGetQuery:

private ITrooperAccessGetQuery _tagq;
private ITrooperAccessGetQuery TrooperAccessGetQuery
{ get { return _tagq ?? (_tagq = new TrooperAccessGetQuery()); } }

What this says: “Hey, my system is simple, I don’t need a master system putting everything together. My components know what components they normally depend on, but you have a chance to override. If you call the default constructor, I’ll give you a component with all default components.”

Thus, I added a default constructor to my component:

public TrooperAccessGetQuery() 
    : this(new DbConnectionProvider(), new TrooperGetQuery()) { }

And life proceeded.   Its pretty, and avoids ugly constructors, and arcane app bootstrap code, and having to choose a dependency injector. 

Dapper Query Multiple

I had not seen this construct before.   Useful:

public static Counts Get()
{
	const string sql = @"
select  count_big(1)
from    imported.TrooperStatistics with(nolock)
where   is_summarized=0

select  count_big(1)
from    imported.TrooperStatistics with(nolock)

select  count_big(1)
from    aggregated.StarDateHash with(nolock)
where   is_aggregated_total=0

select  count_big(1)
from    aggregated.StarDateHash with(nolock)
where   is_aggregated_time_interval=0";

	var connectionProvider = ObjectFactory.GetInstance<DbConnectionProvider>();

	using (var connection = connectionProvider.GetOpenConnection())
	using (var multiple = connection.QueryMultiple(sql))
	{
		return
			new Counts
			{
				Total = multiple.Read<long>().First(),
				NotSummarized = multiple.Read<long>().First(),
				NotTotaled = multiple.Read<long>().First(),
				NotCalculatedTimeInterval = multiple.Read<long>().First(),
			};
	}
}

I learn something new every week. Thanks, JM!</P?