Endless Sky

imageLately, I’ve been playing a game called Endless Sky.  I’m thoroughly enjoying the game.   I don’t have the time right now (15 minutes) to go into the detail details, but, I’ll throw this out if you’re interested in the game – my evolution playing the game.

First Starting Out, with a Mortgage, I had to count the hops + calculate loan payments.  Only take jobs that I could do with a positive; if I had any cargo space left, look to which system I was going to, figure out Trade differences, and buy/sell to squeeze a few more cents out.   Run away from pirates!   If you die, you restart at the last planet you were at.  Pay of as much of the mortgage early as possible – I would pay off any extra bringing my prudent reserve down to 50k. 

Sell and upgrade to a newer ship whenever you can.  There’s no Buy/Sell penalty; you can go back.  and you can save the game.

Then as you get slightly larger ships, you have the ability to take multiple jobs to multiple sectors and really explore.   You can earn maybe 1 million per transit of the system using a … it looks like an SR71 blackbird, crew of 3?  Phoenix?  Beware of keeping your ship small enough so you don’t pay too much overhead in crew.

Then, you get to maybe 10million in net worth or so – you can get a really big ship, where the profit from a meager +100 credit/ton times 500tons of cargo gives you a nice $50k, in 4 hops.  At this point, missions / jobs don’t compare. 

This is where I am now.  Next up – I plan to get up to maybe 3 large ships (Behemoths) so I can earn > $500k per transaction.  As soon as I get there, I’m going to start buying a buttload of small fighters, and set myself up to have my own swarm.    I figure if I have 20 ships with missiles, any opposition will get 20 missiles at a time.   And lots of lasers.  Swarm.  Yep.

Then I’m going pirate hunting.    So I can demand Tribute Smile 

Here’s something NOT to do:   Do not run with a SR-71 + 6 berserkers.  The way that I had it set up, each berserker was about 1.5million.  When one of them got blown up and I didn’t realize it and I saved the game.. I lost 1.5 million.  I could not make that back up quickly.   So, yeah, save the swarming for later where 1-2 trades = 1 ship.

I did a  google sheet about ships, crew costs, trade potentials, DPS, etc.  Will share on request. 

Purrmutations

We have three cats *:

image
Harvey Quinn
image
Blackberry / Scrappy
image
Fifi Toupe
  • Boy, Insistent
  • Boy, Hesitant
  • Girl, Kick yo ass

Fifi just got spayed, so needed to stay from her brothers.  Just in time – Harvey has matured, and, his biology is calling for him to be very very curious about female cats.  Even if it’s a litter mate.

Harvey and Blackbery have their dates with the vet next week Wednesday.

In the mean time – Fifi’s stitches came out, but Harvey would just NOT leave her alone.   So, when unsupervised, I needed to continue to keep them separate.

We have this setup:

  • I had to keep Harvey and Fifi Separate
  • One partition of cats could roam the hallways if we let them.  Either by opening the bedroom door or the bathroom door.
  • All cats must have access to litterboxen.  (There’s also drinking fountains in each Hab.)

How many combinations could I come up with?

I think the way this breaks down is as follows:

  • 2: Either we have   F, H+B  or F+B, H. 
  • x2: Either we have F in bedroom or F in bathroom.  (and the other pair on the other side)
  • x3: Either we have the bedroom open to roam, or the bathroom open to roam, or neither.

Yielding a total of 12 combinations.

Oops.   I don’t think I have tried all 12.   Some things to narrow it down:

  • F HATES being alone – LOVES Human company.   Not so much other cats – maybe because they’re smelly boys.   So really, access to roaming doesn’t mean much to her, she just hangs with us humans.   This brings it from 12 down to 6.
  • H HATES being alone; he loves to roam.  He views closed doors as challenges to open and sneak past as soon as you open them.   So always giving him roaming, same as the above, still at 6.    No!  down to 4, because H should always be roaming, that rules out the both-locked-in version (which is the “dogs are out” configuration).
  • B loves to be near another cat.  I think he roams mostly to follow H around.    Although he has sneak attacked me at the screen door to the outside in the Family room.   Still at six, cause he’s either with H or F.

So the four workables are:

  • F+B in bedroom, H in bathroom roaming
  • F in bedroom, H+B in bathroom roaming  <—Usual
  • F+B in bathroom, H in bedroom roaming
  • F in bathroom, H+B in bedroom roaming   <—no, she cries.

Aha! ruled out another one.  So, 3 good combinations.

The standard arrangement has been (at night) F with me in the bedroom, and H+B roaming with access to the bathroom litter box.

The one time I kept H with me, and F+B in the bathroom – he snuggled with me a bit, then went off into the closet and ignored me.   Quite cat-like. If I ain’t got the pettings, he aint got time for me.  

I think tonight we’ll go with F+B with me, and H out to room with the bathroom.

 

*Yes, I’m using cat pictures in a blog post.  I’ve been told that cat pictures are what makes the internet keep working. 

Love my life.

Candy Crush Helper

I was listening to Tim Ferris interview Jane McGonigal on the neuro-programming that occurs around playing games.  One of the games mentioned was Candy Crush Saga.  Curious, I decided to start playing it – and now I find it relaxing, a good place to put my mind when my mind is obsessing about other things.

But of course, being me, I started to wonder, “can I program a solution for this?”    Well, of course not – the boards are actually random – but I could write a helper to detect available moves, and possibly future moves.

Turns out a guy already wrote one.  See his video explaining how it works here.   However, I couldn’t get it to run, and it required me running candy crush on my laptop.  And, it didn’t look ahead moves – just the currently available ones.  Still, an impressive piece of work. 

2015-09-12 22.36.39So I started coding one for fun.   I started with this screen:

Question:  How many possible moves do you see?  (A move for the uninitiated, is swapping adjacent candies so they form at least 3 in a row or 3 in a column).  I counted 11 on my initial count.

I wrote some code to load this into a class, and wrote some methods to load candies.   It was a very zen-kata-exercise thing to figure out how to save the board – turns out I didn’t know 2D arrays in C# very well at all (and I still don’t, I chose a different method): image
I wrote a some “possible candy swap” code, and wrote some stuff to find solutions, and wrapped that in a test: image
It says there are 14 moves. What?  I don’t have a clean way of outputting the moves yet, so I will have to highlight them by hand. image (89 ms)

Here’s what it found: 

image

  • Yeah. Bug in my code.  I thought I was doing a copy from one board to another, but it was a shallow copy, so all the “possible” moves were being remembered one after the other, rather than one at a time.  PANDA-MONIUM!

My attempted fix of the code didn’t work.   And its getting late.

I believe the test needs to Assert(13, allPossibleMoves.Count):

image

Or am I missing something?   I will resume this.. some day. 

In the mean time, it raises interesting things like:

  • How to represent a very complicated system in a way that makes sense while developing?
  • How to load test data into complicated systems?

Happy crushes.  I’m at level 35, FWIW.

Oh, and I’m using the test-adapter to run NUnit Tests using Microsoft’s test-running tools.

Figuring out Owin Twitter Authentication

I have been working on an Asp.Net MVC project (personal) that needed to do Twitter authentication.  I learned some things implementing it – presenting here so that I don’t forget them, and also in case anybody else runs into the same problems.

Rather than do a bunch of links below, doing it here – this code depends a lot on LinqToTwitter (https://linqtotwitter.codeplex.com/)  to talk to Twitter after getting logged in.   Also, for all the snippets of code – I could have used the “C# colorization” CSS stuff, but I chose not to.  My wordpress is set up a bit weird, and it doesn’t work quite right.

What I started out with

I created an ASP.Net MVC app with the standard starter template, which gave me an Owin layer that did registration, and allowed for adding an external login to the system.

It didn’t work well for me

  • I couldn’t follow the code well – it seemed almost magical how the authentication came back.  For another thing, I needed to grab two of the claims, save them, and use them for getting tweets from Twitter.
    • The “built-in” way to do that with LinqToTwitter relies on Session State.   And it worked well, except that, I was deploying to a “free” class Azure website, which kept recycling, and thus loosing session state.
      • Which lead to an investigation of session state in Azure.  Which led me to a pre-2012 and a post-2012 difference – SqlSession vs Azure In-role cache.  Which lead to a difference of how you tool websites, I had the wrong tooling, didn’t have Roles to add an in-role cache to.
        • All very frustrating.  And trying to get something working “in an hour” sitting at Starbucks before dinner and getting directed all different ways by various well-meaning authors, didn’t help.   Everybody had the perfect solution for their own little universe, but the black boxes they were working with didn’t line up with my black boxes.
  • So, I decided to rip it all out and start over.
  • Spoiler, and then it made sense and it worked.

Best Source of Info

I have to give kudos to @EdCharbeneau. I know him personally, and I was quite surprised to find he had written a blog post about Owin that was the perfect post for me:  https://www.simple-talk.com/dotnet/.net-framework/creating-custom-oauth-middleware-for-mvc-5/.   It cleared up several things that were not obvious to me.

Code from “scratch”

Here’s how the flow works:

// GET: Read
[Authorize]
public async System.Threading.Tasks.Task<actionresult> Index()
{

You want in, but [Authorize] says you should be authorized.     So, do something to authorize the user.

At this point, we have to step back and go to the startup.auth that MVC / Owin likes to do.  I won’t get into the details of IAppBuilder and what Owin is, but here’s the relevant configuration code:

app.UseCookieAuthentication(new CookieAuthenticationOptions {
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Login"),
    ReturnUrlParameter = "redirectUri",
    Provider = new CookieAuthenticationProvider() {

    }
});

We’re telling OWIN that we want to use a cookie to prove that the user is logged in. If the user aint got the cookie, then send them to /Login to go get them the cookie. When sending them to /Login, pass a parameter of ?redirectUri=xxxx to tell Login where to send the user back to.

So the user shows up at /Login. What happens next? LoginController:

public class LoginController : Controller
{
    // GET: Login
    public ActionResult Index(string redirectUri)
    {
        var whenDoneLoggingInUrl = Url.Action("ExternalLoginCallback", "Login", new { ReturnUrl = redirectUri });
        return new ChallengeResult("Twitter", whenDoneLoggingInUrl);
    }
    ...

So the way that Oauth works – every provider, has a slightly different way of initiating the go-log-thyself-in thing. In order to work with everybody – there’s a particular type of response that needs to get sent back. In order to hook how to send the right kind of challenge back, we have to write a custom ChallengeResult where we can execute some code as we’re building the result to send back to the browser. This is almost directly lifted from the MVC boilerplate app that ASP.Net provides:

internal class ChallengeResult : HttpUnauthorizedResult
{
    public ChallengeResult(string provider, string redirectUri)
    { 
        LoginProvider = provider;
        RedirectUri = redirectUri;
    }

    public string LoginProvider { get; set; }
    public string RedirectUri { get; set; }
    // public string UserId { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        var properties = new AuthenticationProperties { RedirectUri = RedirectUri };
        // this does the 302 or whatever the login provider wants you to do. 
        context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
    }
}

Ah, but that LoginProvider — how is there code that knows what to do there? That comes in a bit more of startup.auth.cs code:

var options = new TwitterAuthenticationOptions()
{
    ConsumerKey = ConfigurationManager.AppSettings["TwitterConsumerKey"],
    ConsumerSecret = ConfigurationManager.AppSettings["TwitterConsumerSecret"],
    Provider = new LinqToTwitterAuthenticationProvider()
};
app.UseTwitterAuthentication(options);

TwitterAuthenticationOptions is a microsoft-provided class that does the right challenge to send stuff to Twitter; it also handles when twitter redirects back to our app, and handles getting the claims and all that. Perhaps. The LinqToTwitterAuthenticationProvider might do some of that as well, I haven’t delved too deeply into what that does differently from the microsoft provided one.

There’s one more little bit of code that needs to happen to get things to work:

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

This tells the authentication provider how to hold on to information as its doing the login process.

So where does this leave us at? Well, the negotiation with twitter happens; it comes back to the Oauth provider (which we can’t see the code of), the user gets approved, and we pick up some claims from twitter, and everything calls back into the “whenDoneLoggingIn” url we defined above. That leads us to:

public ActionResult ExternalLoginCallback(string returnUrl)
{
    var owinContext = HttpContext.GetOwinContext(); 
    var loginInfo = owinContext.Authentication.GetExternalLoginInfo();
    if (loginInfo == null)
    {
        // did not survive the login process
        return View("LoginFailure");
    }

    // log them in persistently here! 
    // we have to create a new claims identity with authentication type cookie. 
    // i could probably copy the claims over easier... 
    var claims = new List<Claim>();
    foreach (var externalClaim in loginInfo.ExternalIdentity.Claims)
    {
        claims.Add(externalClaim);
    }
    var id = new ClaimsIdentity(claims,
                                DefaultAuthenticationTypes.ApplicationCookie);
    // https://stackoverflow.com/questions/23180896/how-to-remember-the-login-in-mvc5-when-an-external-provider-is-used/23228005#23228005
    owinContext.Authentication.SignIn(
        new AuthenticationProperties
        {
            IsPersistent = true,
            AllowRefresh = true
        }, id);

    return new RedirectResult(returnUrl);
}

Whoo that’s a lot of code. Lets walk it.  Side note:  Every time I find an answer that I use on StackOverflow, I try to attribute it in the code that I generate, and up arrow the answer I used.

First is, the possibility that we didn’t get a successful login from twitter. If so, login failed. Boom. Done.

Otherwise, we have a list of claims about the user. Twitter gives us about 6 claims –

image

I need to copy these claims over to a new list of claims, create a new ClaimsIdentity based on those claims (but with a different AuthenticationType – remember that you can be logged in with 3 identities at the same time), and then log that new identity in; the user gets logged in via CookieAuthentication.

The result of this is a persistent cookie in the browser which is an encrypted version of the 6 claims, plus an expiration time and several other things:

image

And finally, the user is re-directed back to where they started – the Controller which had the [Authorize] attribute that intercepted the request.

This time, when the user requests the page, the cookie is decrypted and unraveled into a list of claims that we know about the user. Then, in the page that was requested, if I want to talk to twitter to get stuff, I can do the following:

var userInfo = _cq.GetLoggedInUser();

using (var twitterCtx = await _cq.GetTwitterContextAsync())
{
    var tweets = _cq.GetHomeTweetsQueryable(twitterCtx).ToList(); 
}

The heavy lifting I’ve put into a CommandsAndQueries class (* controversial; seprate topic) –

public LoggedInUser GetLoggedInUser()
{
    if (_context == null) return null;
    var owinContext = _context.GetOwinContext();
    if (owinContext == null) return null;
    var authman = owinContext.Authentication;
    if (authman == null) return null;
    if (authman.User == null) return null;
    // C#6 will make this prettier. 

    var loggedInUser = new LoggedInUser();
    foreach (var claim in authman.User.Claims)
    {
        // Claims: 
        // http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier = 152333310 
        // http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name = sunjeevgulati 
        // urn:twitter:userid = 152333310 
        // urn:twitter:screenname = sunjeevgulati 
        // TwitterAccessToken =  ; 
        // TwitterAccessTokenSecret = ;
        switch (claim.Type)
        {
            case "urn:twitter:userid": loggedInUser.TwitterId = ulong.Parse(claim.Value); continue;
            case "urn:twitter:screenname": loggedInUser.TwitterScreenName = claim.Value; continue;
            default:
                continue;
        }
    }
    return loggedInUser;
}

This is code which looks at the logged in user, interrogates the claims, and if it finds the claim that has a particular piece of information, extracts just that claim, into a little DTO helper object.

A more complicated one to get a LinqToTwitter context:

public async Task GetTwitterContextAsync()
{

    var credStore = new SessionStateCredentialStore();  // i frequently loose session, so need to rejigger this
    if (!credStore.HasAllCredentials())
    {
        if (_context == null) return null;
        var owinContext = _context.GetOwinContext();
        if (owinContext == null) return null;
        var authman = owinContext.Authentication;
        if (authman == null) return null;
        if (authman.User == null) return null;

        foreach (var claim in authman.User.Claims)
        {
            switch (claim.Type)
            {
                case "urn:twitter:userid": credStore.UserID = ulong.Parse(claim.Value); continue;
                case "urn:twitter:screenname": credStore.ScreenName = claim.Value; continue;
                case "TwitterAccessToken": credStore.OAuthToken = claim.Value; continue;
                case "TwitterAccessTokenSecret": credStore.OAuthTokenSecret = claim.Value; ; continue;
                default:
                    continue;
            }
        }
        credStore.ConsumerKey = ConfigurationManager.AppSettings["TwitterConsumerKey"];
        credStore.ConsumerSecret = ConfigurationManager.AppSettings["TwitterConsumerSecret"];
        await credStore.StoreAsync();
        if (!credStore.HasAllCredentials()) throw new NotSupportedException("Could not get credential store to have all credentials!");
    }
    return new TwitterContext(new MvcAuthorizer() { CredentialStore = credStore });
}

Its the same idea, except that it needs a few more claims, as well as the two things stored in AppSettings.

Finally, the call to get tweets for the home screen, lifted almost directly from the LinqToTwitter documentation:

public IQueryable GetHomeTweetsQueryable(TwitterContext twitterCtx)
{
    return (from tweet in twitterCtx.Status
            where tweet.Type == StatusType.Home
            && tweet.Count == 200
            && tweet.IncludeContributorDetails == true
            && tweet.IncludeEntities==true
            select tweet);
}

Conclusion

That’s a long way to go around; but, that is what it takes, with all these different black boxes talking to each other, to get the app to work. Hope this helps you save some time doing your own things.

WIFI Tools for Windows

I had some trouble with my WIFI network a few days ago – and I got to brush up on some tools I can use in Windows to diagnoze WIFI connections.

Ekahau WIFI Mapper

The coolest one I found was the Ekahau Wifi Mapper.  Its free for personal use, limited to 15 minute mapping sessions – enough for a floor of my house!  Here’s the map I came up with of my upstairs:

image

Compare that ZMG12-24 (the 2.4 Ghz signal) with the 5.0Ghz signal –  I had to resort to my iPhone to get the screenshot, Greenshot didn’t co-operate –

image

Surprising!  It things ZMG-12 is located in the back yard?  Maybe the signal goes out the french door and reflects off the tree.   Or, my little mock-surface doesn’t have a very good 5.0Ghz antenna. 

The other thing this app told me – that I had wondered for a while – is which neighbor has which WIFI. Especially folks like “FBI Surveillance Van” who has an Open connection.  Heh.   Amazingly, in this subdivision of older folks, there were a few hidden wireless networks as well.  Didn’t know that.

Acrylic WIFI

The other tool I found was Acrylic WIFI – It can listen over time and figure out what’s using what channels, and you get a signal-strength-over-time graph:

image

I get a nifty channel spread view as well:

image

Once again, OMG the 5.0Ghz network is sucking boogers.   It might be the router.

Handy information to have.

I really want to do a WIFI heat map of my mom’s house.  She has some fun problems there.

Excellent Software Experience

I recently upgrade my mom’s store to use The Uniform Solution – it’s a point-of-sale + inventory + EDI ordering software designed specifically for stores that deal with uniforms and scrubs and stuff like that.   And speaking as a software developer, the experience was awesome

I want to call them out on some of the stuff they did well:

Appropriate System Design

They don’t do anything overly fancy.   They have a SQL Express database; they have a client that interfaces to the database.  The “main computer” has a share, other clients map to the share and run the same executable.     It’s a little unnerving – the share is wide open – however, if you’re enabling WIFI at your store direct to your internal network, you’ve got other problems going on.   And, I’m sure it could be locked down; their target audience usually doesn’t have an IT department, so they did the right thing for their market.

For a web server, we’re not using it (yet), but it looks like a stand-alone executable that hosts the website.    Well done.

Excellent Installation

Server install – Single executable – run – it detects if its upgrading or installing.  It downloads SQLExpress 2012 and totally auto-scripts the install of it (much to my chagrin, I could not easily hack into their database and look at tables directly.. I wanted to see what their schema looked like).   

They stick everything in C:\USW. 

Client install – Map a network drive to the server share; run an executable – it makes sure that firewall settings are set up correctly, sets up an icon, done.

Once their software comes up, it has a failsafe option – if it can’t connect, you can configure it to help it find its SQL Server.    Well done!  as in, they didn’t assume that that part will work all the time.

The running software automatically keeps track of who is logged in concurrently.  I suspect they use some network broadcast type stuff.   I’m reminded of the 1990’s “net send” command, for some reason.

Backup and Restore

They provide their own backup and restore functionality – Everything gets dumped into a single file (extension .bsql – I think it’s a zip of schema + data).   They automatically take a backup first thing in the morning (first time a person logs in to the system in a day).  I found their auto-backup directory, and I added a script to it to sync the latest N files to dropbox as an off-site solution (different blog post).   I did do one restore; I need to do another with the offsite stuff. 

Side note: I tried to use an azure VM to do the DRP restore session, but their software had a hard time installing SQLEXPRESS on Windows Server 2012 and then finding it later.   Will do the restore on my surface at some point just to make sure its possible.   Which is actually perfect – my surface was used as a client for a while – we hooked a usb barcode scanner to it and mom walked through her shop importing inventory with it (we were waiting for the bluetooth wireless scanner to arrive.  Prime is only so fast.)   Ie, just like in the real world, if the server dies, we’ll probably promote client #1 to be the server – so test restoring on that laptop would be the ideal DRP test.

Excellent Technical Customer Service

I had to call them a few times.  Freaking awesome – they people I talked to, not just some help desk lackey.  These were highly competent technical people (I can tell the difference).  At the first sign of miscommunication, they immediately went into “let me remote in and look at your screen” mode and took it from there.    

I could also tell that these people are a team.  They trust each other.   They like what they do.   They don’t want to grow big and take over the world, they want to be excellent and do excellent and completely solve the one corner of the universe that they have adopted.

Well-Iterated UX

After using the software for a bit – especially on their point of sale screen – I came to appreciate the love and care they have put into their product.  Little things, like “type in stuff in the text box – if its decimal and less than 1, it’s a %off; if its integer between 1 and 99, it’s a quantity” etc – made the system very efficient to use.    I came home and used the same idea on our fridge-inventory-scanner app at work.  (different blog post)

Some of the Finer Points of their System Design

  • “Catalogs” = people out there in the world that they maintain catalogs for.  If they maintain a catalog for it, it means they know all the bar codes for everything in that catalog.
  • “Inventory” = things that you might or might not have in your store.   Breaks down to Vendor, Product, Size, Color.    
    • You can add your own Vendor, Product, Size, Color, etc to inventory – you just don’t get the pre-loaded data from the catalog. 
    • Mom does carry other stuff in her store that they don’t have in their catalog – notably, SAS shoes.
    • Everything that gets added to inventory gets its own unique custom bar code number as well.     Think “SKU” from BestBuy.
    • You get to set the prices for inventory (there are standard formulas for per-vendor markups that you can tweak)
    • USW (that’s what they call it) can and will print out a shop-specific bar code + price to stick on the item.
  • Hardware wise, the app knows how to talk with:
    • Barcode scanners (basically, they work as USB keyboard-entry-devices; when you scan something, it types the stuff in and presses enter)
    • Pole Displays (we didn’t get one)
    • Receipt Printers (just another printer, but with a possibility of controlling a cash drawer)
    • Cash Drawers (it tells the receipt printer “open the drawer now”, and there’s a cable between the cash drawer and the printer which sends that signal across)
    • Zebra Thermal Label printers (for printing out cute little labels OMG so cute)
  • At the checkout, you can scan:
    • the original bar code that came with the item (if its something in a known catalog)
    • OR the shop-specific price tag + bar-code
    • OR search inventory to find the thing
    • OR just type in “*9.95” and get a miscellaneous item for $9.95. 
      • But then inventory doesn’t get tracked correctly if the item was actually in inventory.
  • You can set up customer tracking
    • Special customers, for example, don’t get charged sales tax (governmental things)
    • Or, maybe you just want a list of customers to keep track of what they ordered.
    • typing in 3 letters of customer’s name triggers a customer search in the sales entry screen.  (nice touch)
  • There are special modes for dealing with “sucking inventory in the first time”
  • There are special modes for placing orders, and then printing tags specific to the order that was placed.
  • There are user permission levels (initially turned off) to allow for managers vs clerks, etc.
  • There’s a built-in time-card check in/out thing.
  • There’s cash drawer check in / out things.
  • There’s end of day reconciliation reports and all kinds of other reporting.
    • With a Print Preview for seeing it on screen
    • and everything has a Print to PDF option
    • and some of the reports are aware of if you are printing to a receipt printer vs a regular page; and self-format accordingly.
  • They chose to integrate with X-Charge as a credit card processing system – it was a little bit involved, but in the end, how it works:
    • The XCharge guys installed the xcharge server + client on the machine(s).  It can run as a service, but in our case it sits in the system tray.  It deals with talking over the internet, running cards, that kind of thing.
    • USW just knows a username/password to log into the local xcharge thing and posts things that way.
    • USW doesn’t hang on to any credit card information.  That’s all XCharge’s thing.
  • Their pricing model is simple:   Monthly, $250/month, +$25/mo for each additional concurrent user.   Simple, straight forward, and definitely worth the less-than-$10-per-day that its costing my mom.   (Well, one-time cost on the computer hardware)
  • They provide 250 minutes per month of technical support as part of this. And looking at the emails I get, the service they provide is impeccable:
    • The person you talk to very quickly drops down to “here let me show you how this works” mode and remotes in to look at your screen.
    • After the support session, everybody gets an email saying “here’s what I helped you with”
    • And they clearly mark how many minutes of support were used, and how many are left, for the month.
  • Did I mention Video Training on topics of all sorts?   (It needs a little update, but overall, pretty good).

All in all, a big huge THUMBS UP for these dudes.    If I ever get into providing a specific solution to a specific market, I’m totally going to try to live up to these folk’s standards.

The only thing that I would suggest to them – because they have such a wide-ranging system – is perhaps a “day in the life of” video series for prospective customers.  Ie, show a real life scenario of “here’s how a clerk uses the system” vs “here’s how an owner users the system”, etc.    Especially if its people who like using the system, who can show off their favorite shortcuts, etc.    

More perspective about blood sugar

imageReading a book called “The Four Hour Body”.  It pointed out that even in really high GI things like Orange Juice, it might take 30 minutes for the full blood sugar thing to take effect.  And pasta, 1.5 hours. This was based on a normie  wearing a CGM and measuring. 

Then, separately? not in the book? doing the math:  100 mg/dL vs 5 L of blood (at best) = 5g of “sugar stored in the blood” buffer.   That’s way less than a meal.

So, I used to think that my blood was like this bucket that sugar got dumped into, and it hung out there till insulin took it somewhere else.  Well, that is kinda what happens, but “bucket” is incorrect.

Its more like a temporary sponge, a small buffer, that happily holds about 5g.  Its a transport.   It can overflow.  at 7.5g, bad things start to happen.  at 15g (300 mg/dL) really bad things happen.

The things that deposit into it:  

Liver during glucogenisis (body saying holy shift too low need more glucose), and digestion.

Things that consume it:

Ah, so here’s the happy little insulin thing.  Insulin definitely acts as the door-knocker that knocks on doors and tells them to open up and let the sugar in.  Which doors, one might ask?

Apparently there’s the doors on the Fat cells.  Yay Fat Cells!  Helping me survive the next famine, when all the little hamburgers are migrating off on the west coast at the In and Out watering hole.

But there’s also another door – the doors in active muscle tissue.

So if you do 40 air squats  (i can do 10, need to build up), that activates something in your muscles, specifically your big thigh quadriceps, that says “HOO BOY does ANYBODY have any GLUCOSE please?” .. and the insulin happily helps deliver it.    Drains the buffer, clears the sponge, ready for more digestion.  Follow that up with some nice pushups – or pullups, dude, if you can do them .. targeting the nice big muscles. Nice big sponges.    Or go walk up 12 flights of stairs.  Oh yeah.

I’m not sure how long after the exercise that receptor (he mentions it in his book, but not at the tips of my fingers) stays on.  I don’t have a CGM to help tell me, and I’m not spending the $, as I’m not type I, its not covered.

I’m also not sure if the action of delivering sugar to the blood is entirely osmosis or not.  Ie, there could be a large store of sugar in your digestive tract at some concentration, and when your blood drops below that concentration, then it migrates over.  Which lends itself to, what gut bacteria exist, and do they consume any of that sugar, and what’s the effects of that.   I don’t know the answers to that.

The point is, 1-2 hours after a meal which might have too much carb, one can use exercise to help “soak up” the sugar.  One does not have to burn that many calories, just activate it enough so that the muscles soak the sugar up.  Note that muscles can only hold a certain amount, though, i think its up to 100g?  your whole body can do about 400g total storage? 

The key numbers I’ve heard is that you want to get down below 140 mg/dL, to prevent certain kinds of cell death; and then below about 100 mg/dL  the body (for normals) stops putting out chunks of insulin; and once the insulin is gone, then your body can get back to finding other sources of glucose, like burning Fat.

What brought this up:

We went to see Marvel Age of Ultron on Wednesday night.    We had Noodles & Co for dinner, and then shared a large popcorn and M&M’s and a coke.   LOTS of sugar.  

After the movie, got home, took my sugar.  If it was over 140, i was going for a walk.  It was 235.   I went for the walk.  Got back 40 minutes and 2 miles later, 171.  Waited 30 minutes.. check again, is my body still dumping it into my system?  No, 146.  So its getting soaked up.  Good.    I don’t feel so helpless.

Note: my perspectives only.   Not a scientist, no research, just reading.  Could be wrong.

French Press Coffee Grounds Disposal Process Optimization

At work we have a slight problem.  We like our high quality coffee, we use a french press, but we do not have a garbage disposal.

This was my process solution for the problem of how to get the liquids down the drain, but the solids down the garbage.

I guess its not clear – the problem is that if you drain all the liquid down the drain, the solids are very sticky and “stick” to the bottom of the carafe.  Then you have to find the appropriate utensil to try to scoop the stuff out, and its very messy.   This is an attempt to have gravity and air pressure do the work.

Oh, who am I kidding.   I have a solution in need of a problem. 🙂  Live to Geek, Geek to Live, as my wife points out.

[youtube=http://www.youtube.com/watch?v=adH_r9_5fLA]

Teaching .Net–my role as Teacher

Earlier this year, I started practicing some affirmations.   They were along the lines of “There is opportunity everywhere”, and “I do not know myself.”  The intention was that if there’s some way that I could be growing, that the Universe will guide me to it.

There are so many subtle (and possibly not-so-subtle) things that have changed for me since then.  Or, rather, I haven’t changed – I’ve always been me – but I’ve discovered new modes in which I am comfortable.

One of these is regarding my role as a teacher.   There’s a long story arc – it probably starts at helping new wizards to code LPC on a Mud in 1991, stops by at creating training materials for Perl at a startup in 1997, touches on creating Unit Testing and Integration Testing video lessons for a company in 2009.   This latest leg of the story involves:

  • Assisting (briefly) with being a mentor for Code Louisville, and being sad that there was not a .Net curriculum, and attempting to design one;
  • Being considered by a company to be a lead .Net instructor at a bootcamp that’s coming to Louisville. 
  • Having a serious chat with a dude who knows how to teach teachers; getting introduced to Madeline Hunter’s “Mastery Teaching”. To be honest, only got through the first 4 chapters or so, but wow.   (Note: link to the book I COULD have gotten; I got an older and much more bare-bones book).
  • Being asked to help a guy with learning IoT specifically.  I got paid in Qdoba and Starbucks.  Turns out he knew it already, didn’t know that he knew it.  THAT’S ALL?  I giggled and continued eating my burrito, and then we talked about bunches of other stuff.
  • And today, helping a person start to crash-learn .Net.   No, Double-A, I did not Video, so I guess it didn’t happen.

How did it Go?

I had designed a curriculum; given the learner is an experienced programmer, I was hoping that we’d be able to blaze through the material.   However, ‘twas not so.   We blazed, yes; but being a .Net programmer for 15 years, there are so many things I take for granted that we ended up discussing.  For example:

  • Assemblies vs File boundaries vs Namespaces  (did you know ildasm.exe not on disk anymore automatically? when did they change that? A little harder to get a visual on things now)
  • Solutions vs Projects and why oh my?
  • bin vs obj
  • PDB files
  • rearranging the Visual Studio panes and tabs and “Reset Window Layout”
  • Keyboard shortcuts (for somebody used to vi, it’s a learning experience!)
  • GAC references vs project references; when does the public key token come into play?  (and then, also, NuGet)
  • Appropriate .gitignore files, no, you don’t need to save the packages/ directory
  • int vs System.Int vs boxing vs DateTime vs String, and how that plays out with ref & out; when is it a pointer or not?
  • .Net framework versions
  • Garbage Collector internals, as compared to other languages; generational collection; finalization.
  • Assembly version mappings, the new DLL hell.  (We never talked about DLL hell)
  • Stream vs StreamWriter vs TextWriter and the amazingnessballs of System.Io
  • Reflection, typeof(), GetType(), serialization
  • String.Compare(,,true) vs StringComparison.InvariantCultureIgoreCase, and culture, and evolution of the .Net framework.

So in 4 hours, we got a good amount done – enough to get them dangerous – a console app that kept track of a todo list and persisted between runs.   I hope it got him to a spot where he could investigate MVC on his own.  I also pointed him at Pluralsight, and we’re going to follow up via email for the rest of this week.     Btw, Pluralsight is the densest stuff I’ve seen; second runner up is Lynda, then we start talking Microsoft Virtual Academy.  

How did it map to Mastery Teaching?

As a thought experiment to myself, I am attempting the mapping.  How did I do?  How could I improve?

1.  Content, Behavior of Learner, Behavior of Teacher

I think the layering of content worked fairly well.  For example, used int.TryParse() to introduce out parameters, and String.Format() to introduce “params”.   A little slow at times; but we kept improving a program, which gave a nice feedback cycle for success.

Learner and Teacher behaved mostly well.    There was no dancing in chicken-suits.

2. Level of Concern, Feeling Tone, Success.

Already talked about success.  The ongoing concern mapping was to take a known body of information (“how to program in Go and PHP”) and to map the concepts to .Net.    Feeling Tone was ongoing successes, was pretty good, though after about 3.5 hours, definite brain depletion.

3. Interest, Knowledge of Results, Intrinsic/Extrinsic

By keeping the functionality of the program we were working on as a dangling carrot, interest stayed high.  The way we worked it is, I would write some code on my laptop demonstrating something, then he would write similar (sometimes the same) code on his laptop, trying to achieve the same result.  On the way, there were fun little learning things (keyboard shortcuts, debugging, inner exception drilldowns, etc) that kept the learner’s implementation “fresh” rather than a copy – when it worked, they KNEW how they got it to work.     All the motivation was Intrinsic.

4. Review, Anticipatory Set, Objective

I had the curriculum broken out into sections.  For example: “Hello World” followed by “console app in a while loop accepting commands from user”.   I think I could have done a better job bookmarking the sections, and doing the anticipatory set.  I didn’t bother with Review because we were both firing on top cylinders.. or .. maybe I did.  After we did a block, I’d go back to the curriculum and see if we had covered all the topics for that round.     And the end of each block, there was a definite objective – “having a working program that does X, where X is useful in a geek evolution way”.

5. Basic Info / Organization, Simplest form, Modeling.

Each module introduced a very small set of new things.  Some chunks were larger than others, for example:  using(), IDisposable, System.Io.StreamWriter, Xml Serialization, gettype() all went together – I couldn’t think of a meaningful way to make that smaller.   

Because we started from a console app, we were able to hit concepts in small buildable chunks.  For example, int.Parse() => exception => try/catch to deal with exception => int.TryParse => out parameters.   We evolved the code and ran it each time, enjoying the error messages given.

I did NOT want the first .Net code they saw to be a Controller + View + Entity Framework.  (Except they ran ahead and created a project as such already.  Holy crap that’s a lot of firehose)

That’s as far as I’ve really gotten through the Mastery Teaching stuff;  And that’s pages 1-38 of that book.  Pretty crazy, huh?    This is some good Shizzle.

Finishing the rest of the book is still on my list; however, its one of those where you read a chapter – and only a chapter – and then it has to stew in your head for a weekend.  So, it will be a little bit.

In Conclusion

I did not choose to become a full-time instructor.  I’m sad about that… it has to do with schedule and availability-of-free-time and mobility than it does about whether I like it or not.  I love organization of information and teaching somebody who wants to learn.

But, hey, maybe I can do this one-on-one kind of tutoring instead.  

And if there’s demand for it, maybe I’ll make some spending money at it too.   Smile   (Relax, U.S. – using you as a guinea pig to prove out my curriculum.  Thank you.)

Future Tweaks

  • I  think I’d have to budget about 3 hours for .Net basics, 3 hours for MVC/web, and 2 hours for EF?  Oh, another 1 hour for SqlCommand.  This is paired-time.
  • I’m not sure if the loading could/should be “watch pluralsight first then we code together” or “code together then watch pluralsight then write your own” or what.      I think there’s definitely “parrot the instructor but you type it yourself and enjoy it yourself” and then “do the same thing on your own project.” steps that could be played as well.  (At no point will I touch the learner’s keyboard/mouse – everything they do is by their own typing).
  • I think a limit of 1-2 hours per day of active instruction time seems right, to give brain-sink-rearranging time to gel.

Super Excited. Feeling Mighty. 

Anybody else want to be my guinea pig, see if I can fine-tune my .Net tutoring / teaching skills?   I think 1 more test subject before I would start charging.   

Note to self:  him vs they – I kept switching.  I’ve spent 30 minutes or more on this post, so I need to post it and move on.    Kitten just tried to walk across keyboard.  Red heart

Louisville Downtown Exit Coverage Map

Here’s a quickie but oldie.  When I started going downtown more often for various reasons, I decided to study the layout a bit.  I ended up drawing this map:

image

I did this by having two google maps open; I would then do a route in one, and drag the endpoint around; as I discovered when things “switched”, I would update the map in the other window.  I often had to stop and wait because I ran out of API calls per minute.  I’d love to write (or have someone write) an equivalent program, something that colorizes the 2D space of google maps by some function of a route to that spot.

Here’s a readonly link to the map that I made.

It will be fun to re-update this after the bridge work is done to see how things might have changed.