Tuesday, May 9, 2017

a hack to doctor up reference type records midstream in a lambda expression in C#

Consider this code from this blog posting:

List<Om> thinYin = yinList.Result.Where(i => !yangList.Any(a => a.OmId ==
      i.OmId)).ToList();
List<Om> yinYang = yangList.Concat(thinYin).OrderBy(y => y.OmId).ToList();

 
 

Why don't we put it in a method like so:

public List<Om> Whatever(List<Om> yinList, List<Om> yangList)
{
   List<Om> thinYin = yinList.Result.Where(i => !yangList.Any(a => a.OmId ==
         i.OmId)).ToList();
   List<Om> yinYang = yangList.Concat(thinYin).OrderBy(y => y.OmId).ToList();
   return yinYang;
}

 
 

Alright, imagine a Venn (named for John Venn) diagram in which a yinList circle overlaps with a yangList circle. Well, above we are keeping all of the yangList and appending to it just the piece of the yinList that does not overlap with it. (That way there are no dupes in the list we ultimately craft.) There might be reasons why a yang would beat a yin. Perhaps its properties are better baked and farther along in a workflow if both the yang and yin come from different web services while being aggregated in a common report. And yet, let's say that a Zen getsetter on an Om object is always going to be considered more fresh on a yin than a yang due to a shortcoming of the yang web service. What should we do? Let's try this:

public List<Om> Whatever(List<Om> yinList, List<Om> yangList)
{   
   List<Om> throwAwayList = yangList.Where(a => yinList.Any(i => i.OmId == a.OmId
         && DoctorUp(i,a))).ToList();
   List<Om> thinYin = yinList.Result.Where(i => !yangList.Any(a => a.OmId ==
         i.OmId)).ToList();
   List<Om> yinYang = yangList.Concat(thinYin).OrderBy(y => y.OmId).ToList();
   return yinYang;
}
 
private bool DoctorUp(Om yin, Om yang)
{
   yang.Zen = yin.Zen;
   return true;
}

 
 

If Om is a reference type (a class not a struct) then it should be doctorupable inside a method without explicitly coming back from a method as a return type and then getting reassigned to the original variable. You can use the ref keyword if you like too. I guess you'd have to if Om were a struct, though I have not tried that firsthand to confirm it would work.

Monday, May 8, 2017

console.log has many cousins!

console.log('log');
console.info('info');
console.debug('debug');
console.warn('warn');
console.error('error');

 
 

...will produce this at Google Chrome's Web Developer Tools' console:

 
 

Note the different themes for the different things. The warn and the error are expandable to show some metadata like the name of the JavaScript method that threw the error, etc. I've seen a StackOverflow thread that suggested that this too was legit:

console.exception('exception');

 
 

...and that it behaves just like console.error might, but for me console.exception causes an error in at Google Chrome's Web Developer Tools' console.

Saturday, May 6, 2017

Make a ghetto endpoint in a .NET Core app!

I need to figure out how to make controllers in a .NET Core app. In the short term however...

  1. Get Visual Studio 2017!
  2. Install .NET Core. Per this it's the ".NET Core cross-platform development" workload. Everything is modular in Visual Studio 2017 with containers of funtionality optional opt-ins.
  3. Under Visual C# Templates there is a .NET Core subsection with a "ASP.NET Core Web Application (.NET Core)" option nested further inside when you create a new project assuming you got on the other side of the first two steps above alright. Make a new project of this ilk.
  4. Just use the "Empty" template. It will make mostly nude app with two C# classes. One is Program.cs which is the front door to the application. It looks like...
    using System.IO;
    using Microsoft.AspNetCore.Hosting;
    namespace Whatever
    {
       public class Program
       {
          public static void Main(string[] args)
          {
             var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .Build();
             host.Run();
          }
       }
    }

    ...and can mostly just be left alone, truth be told. The other file is Startup.cs which Program.cs designates as the outmost Russian doll in the middleware paradigm. In our case there are no other Russian dolls. I'll get to Program.cs later on.
  5. Run Install-Package Microsoft.AspNetCore.Cors at the NuGet console to add Cors so that we may open up our endpoint to the world beyond our app.
  6. Open PowerShell and enter the dotnet restore command at the folder holding the .sln file. This will restore any missing NuGet dependencies in what is sort of like an npm install fashion. We may not really need it in this immediate case, but this is a good practice before...
  7. Running the dotnet run command. Do note .UseKestrel() in Program.cs which means we will be using the Kestrel web server and not IIS Express! You will want to run this command in the same folder that Program.cs lives in. The web server will run until you press Ctrl-C and it should tell you what port the app is running at at localhost. http://localhost:5000 probably has your app and if you look at it in a browser you will probably see "Hello World" spat back to you from the Startup.cs default placeholder code.

 
 

Alright we are going to leave the ability for the application to tell us "Hello World" alone, but we are also going to add a second endpoint at http://localhost:5000/whatever which will give us a string of pipe-separated metasyntactic variables. Revamp Startup.cs like so:

using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Whatever
{
   public class Startup
   {
      public void ConfigureServices(IServiceCollection services)
      {
         services.AddCors();
      }
      
      public void Configure(IApplicationBuilder app, IHostingEnvironment env)
      {
         app.UseCors(builder =>
         {
            builder.AllowAnyHeader();
            builder.AllowAnyMethod();
            builder.AllowAnyOrigin();
         });
         app.Map("/whatever", HandleWhateverRoute);
         app.Run(async (context) =>
         {
            await context.Response.WriteAsync("Hello World!");
         });
      }
      
      private static void HandleWhateverRoute(IApplicationBuilder app)
      {
         var metasyntactic = new List<string>()
         {
            "foo",
            "bar",
            "baz",
            "qux"
         };
         var flattening = metasyntactic.Aggregate("|", (x, y) => x + y + "|");
         app.Run(async context => {
            await context.Response.WriteAsync(flattening);
         });
      }
   }
}

 
 

You should be able to see the |foo|bar|baz|qux| copy if you run the app and hit the endpoint. With Cors opened up another app could scrape this content in and break up the string based on the pipe symbols. This is weak, I know. It's a start. :)

Friday, May 5, 2017

Drop a pin in Visual Studio 2017!

When debugging and stopped at a breakpoint mouse over a variable and you should see an icon to click to drop a pin.

Click it, the icon that looks like a rightward pointing pushpin.

This drops a pin and in effect makes a little UI element near the variable that is watching the variable and reporting the value. All this happens without a secondary watch window taking up a lot of screen real estate.

When the variable's value changes the watcher will turn red to alert you. In this case I just pressed F5 to hit the same breakpoint in the foreach loop for the next item.

Thursday, May 4, 2017

Keep only the items in a list which to do not have dupes in a sister list and then merge the sister list and the truncated list into one master list without any dupes in C#.

Use LINQ, like so:

List<Om> thinYin = yinList.Result.Where(i => !yangList.Any(a => a.OmId ==
      i.OmId)).ToList();
List<Om> yinYang = yangList.Concat(thinYin).OrderBy(y => y.OmId).ToList();

Doing a .ToList() off of a list in C#, yes, makes a new reference type with a new pointer.

That said, the objects in the collection, should they be reference types, are going to be the same objects with the same pointers in the two lists. Anyways, beyond that caveat, note that this...

List<Whatever> yinlist = yangList.ToList();

 
 

...is basically the same thing as this...

List<Whatever> yinlist = new List<Whatever>();
foreach (Whatever yang in yangList)
{
   yinlist.Add(yang);
}

 
 

...and that ReSharper will even suggest changing the later to the former. Neither is the same though as:

List<Whatever> yinlist = yangList;

 
 

The last blob of code above will make a separate variable with a pointer to the same spot on the heap as yangList. (a separate variable without a separate pointer)

Tuesday, May 2, 2017

Share a folder on your laptop across the LAN to another user in Active Directory with Windows 10.

  1. right-click on the folder and pick "Properties" from the little menu that appears
  2. go to the "Sharing" tab of the dialog box that appears
  3. click the "Share..." button
  4. type in the name of your friend and be sure it match exactly what Active Directory expects
  5. click the "Add" button

You'll ultimately get a //Whatever path for the share. Communicate this to the other party you are sharing with.