<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Honest Illusion</title>
 <link href="http://HonestIllusion.com/atom.xml" rel="self"/>
 <link href="http://HonestIllusion.com/"/>
 <updated>2025-09-11T13:49:31+00:00</updated>
 <id>http://HonestIllusion.com/</id>
 <author>
   <name>James Curran</name>
   <email>james.curran@gmail.com</email>
 </author>

 
 <entry>
   <title>Inside a Where() - Understanding IEnumerables</title>
   <link href="http://HonestIllusion.com/blog/2024/12/05/inside-a-where-understanding-ienumerables/"/>
   <updated>2024-12-05T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2024/12/05/inside-a-where-understanding-ienumerables</id>
   <content type="html">&lt;h2 id=&quot;inside-a-where---understanding-ienumerables&quot;&gt;Inside a Where() - Understanding IEnumerables&lt;/h2&gt;

&lt;p&gt;This post is for day 5  of the &lt;a href=&quot;https://www.csadvent.christmas/&quot;&gt;2024 C# Advent Calendar&lt;/a&gt; operated by &lt;a href=&quot;https://crosscuttingconcerns.com/&quot;&gt;Matthew Groves&lt;/a&gt;. Thanks for letting me participate! (I’m filling in for someone who dropped out at the last minute.)&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; is one of the most basic elements of the .NET framework (and really Computer Engineering itself), so I’m often surprised when I see some commentator giving a rather confused description of it.&lt;/p&gt;

&lt;p&gt;I found this especially true when IEnumerables are chained together, say in&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; var newList = 
     myCollection
         .Where(x =&amp;gt; x &amp;gt; 5)
         .Where(x =&amp;gt; x % 3 == 0)
         .ToList();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(Yes, that’s silly, but I kept it simple). I’ve heard people claim that the first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Where()&lt;/code&gt; is building a whole new list, which it passes to the second &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Where()&lt;/code&gt;, which passes it on the the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ToList()&lt;/code&gt;, which apparently they think builds a new list out of the list….&lt;/p&gt;

&lt;p&gt;That’s not at all what’s happening.&lt;/p&gt;

&lt;p&gt;At it’s most basic level, an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt; is simple a object generator, which, when asked, will give you the next item in a sequence.  How exactly “the next item” is defined depends on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The important thing to remember, is that it is &lt;em&gt;not&lt;/em&gt; limited to getting the next item from a collection. The basic case of this is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Enumerable.Range()&lt;/code&gt; method, which is essentially this (simplified for the example):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; IEnumerable&amp;lt;int&amp;gt; Range(int start, int count)
 {
    while(count-- &amp;gt; 0)
        yield return start++;
 }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;No collection behind it.  Just “the next item”, which in this case is the next higher number.&lt;/p&gt;

&lt;p&gt;Now, with the case of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Where()&lt;/code&gt;, and other LINQ methods like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Select&lt;/code&gt;, which take a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt; as a parameter, and returns an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt;, the method really just creates a new IEnumerable object which wraps the given &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Essentially what is happening in the example I wrote above, is that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ToList()&lt;/code&gt; says “I need to build a list. Give me the first item to start”, and asks its input &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt; for some item.  This input &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt; is the object created by the second &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Where()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;This &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt; says “I have no object to complete that request, so I must ask &lt;em&gt;my&lt;/em&gt; input &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt; for one”. That input &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt; is, of course, the object created by the first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Where()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And so on.  That &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt; similarly says “I have no object to complete that request, so I must ask &lt;em&gt;my&lt;/em&gt; input &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt; for one”. That input &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt; is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;myCollection&lt;/code&gt;, which we’ll assume is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List&amp;lt;int&amp;gt;&lt;/code&gt; holding [4, 7, 2, 6, etc] for this example.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;myCollection&lt;/code&gt; (which, here, is just another &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt;) cordially offers up its first element, 4, when asked. To which the first Where() says “Nope, not what I was looking for”, and asks for another.  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;myCollection&lt;/code&gt; then gives up 7, which the first Where() likes, so it passes it onto the second Where().&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But&lt;/em&gt;, the second Where rejects the 7, and thus must ask the first Where() for another &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;. For this, the first Where() must go back to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;myCollection&lt;/code&gt;, first for the 2 (which the first Where rejects), and then for 6, which it likes and passes onto the second &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Where()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The second Where() also like the 6, and therefore passes it onto the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ToList()&lt;/code&gt; which finally can place a value into the list it’s building. But then, it immediately starts the whole process over — asking for an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; from the second Where(), which then asks the first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Where&lt;/code&gt;, which asked &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;myCollection&lt;/code&gt; and so on, until &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;myCollection&lt;/code&gt; says it has no more, and that information is passed down the chain.&lt;/p&gt;

&lt;p&gt;We can see this by taking our example from before and augmenting it with some logging in the predicate lambdas.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int[] myCollection = {4,7,2,6};

var newList =
	myCollection
		.Where(x =&amp;gt;
		{
			Console.WriteLine($&quot;is {x} greater than 5?&quot;);
			return x &amp;gt; 5;
		})
		.Where(x =&amp;gt; 
		{
			Console.WriteLine($&quot;is {x} divisible by 3?&quot;);
			return x % 3 == 0;
		})
		.ToList();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And we’ll get the output:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Is 4 greater than 5?
Is 7 greater than 5?
Is 7 divisible by 3?
Is 2 greater than 5?
Is 6 greater than 5?
Is 6 divisible by 3?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>Percentage --- Simplifying Progress Reporting</title>
   <link href="http://HonestIllusion.com/blog/2024/11/18/percentage-simplifying-progress-reporting/"/>
   <updated>2024-11-18T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2024/11/18/percentage-simplifying-progress-reporting</id>
   <content type="html">&lt;h2 id=&quot;percentage--simplifying-progress-reporting&quot;&gt;Percentage — Simplifying Progress Reporting&lt;/h2&gt;

&lt;p&gt;A few years, I wrote a post about a simple class a wrote called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Every&lt;/code&gt; (&lt;a href=&quot;https://honestillusion.com/blog/2017/10/12/every-doing-something-occasionally/&quot;&gt;Every – Doing Something Occasionally&lt;/a&gt;). It’s purpose was to ease handling, if you had, say, 50,000 records to process, and you wanted some notification after every 1000 were complete.&lt;/p&gt;

&lt;p&gt;That’s all well and good, but sometimes, rather than knowing some fixed number of records is complete, you prefer knowing what percentage is complete.&lt;/p&gt;

&lt;p&gt;I came upon that need recently at work, so I created this class, which builds on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Every&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Use is simple:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;   var progress = new Percentage(numRecords, 
        (count, percentage) =&amp;gt; Console.WriteLine($&quot;We&apos;re at {percentage}% done.&quot;);
   foreach(var item in MyLongList)
   {
          Process(item);
          ++progress;
   }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s rather straightforward, much like it predecessor, except for one tricky part, which causes it to have two basic modes.&lt;/p&gt;

&lt;p&gt;If the total number of items being processed is greater than 100, then the provided &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Action&amp;lt;int, double&amp;gt;&lt;/code&gt; will be called 100 times, once every time another percent of the total is complete.  The two parameters are the number of items processed, and the percentage complete, which will increase by one each time.&lt;/p&gt;

&lt;p&gt;If the total is less than 100, then then action is called every time the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator++&lt;/code&gt; is called, in this case, with the percentage increased appropriately.  For example, if you only have 17 steps, then the percentage will step about 6 each time.&lt;/p&gt;

&lt;p&gt;Of course, that is handled internally, so you don’t have to worry about it.&lt;/p&gt;

&lt;p&gt;Source code is available here: &lt;a href=&quot;https://github.com/jamescurran/Every&quot;&gt;https://github.com/jamescurran/Every&lt;/a&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>The Oregon Trail Project - Part 5 - Shooting</title>
   <link href="http://HonestIllusion.com/blog/2023/12/27/oregon-trail-project-5-shooting/"/>
   <updated>2023-12-27T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2023/12/27/oregon-trail-project-5-shooting</id>
   <content type="html">&lt;ul&gt;
  &lt;li&gt;Part 0 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/07/oregon-trail-project-intro/&quot;&gt;Intro&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 1 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/26/oregon-trail-project-1-text/&quot;&gt;Markdown to Spectre Console &lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 2 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/27/oregon-trail-project-2-date/&quot;&gt;Dates&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 3 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/29/oregon-trail-project-3-data/&quot;&gt;Data&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 4 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/30/oregon-trail-project-4-events/&quot;&gt;Trail Events&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 5 : Shooting   (this one)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At various time in the course of the game, you’ll have to shoot things, either to hunt for food, or to defend yourself against bandits or wild animals.  This is handled by asking you to type a word, and timing how long it takes you.  This is scaled by a rating you gave yourself.  At the start of the game, you are asked how good a shot you are;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;710  PRINT &quot;HOW GOOD A SHOT ARE YOU WITH YOUR RIFLE?&quot;
720  PRINT &quot;  (1) ACE MARKSMAN,  (2) GOOD SHOT,  (3) FAIR TO MIDDLIN&apos;&quot;
730  PRINT &quot;         (4) NEED MORE PRACTICE,  (5) SHAKY KNEES&quot;
740  PRINT &quot;ENTER ONE OF THE ABOVE . THE BETTER YOU CLAIM YOU ARE, THE&quot;
750  PRINT &quot;FASTER YOU&apos;LL HAVE TO BE WITH YOUR GUN TO BE SUCCESSFUL.&quot;
760  INPUT D9
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Due to the way it is handled, the better a shot you claim to be, the worst shot you actually are.  And this rating it used nowhere else in the code, so there is zero advantage to claiming you are a good shot. But, regardless….&lt;/p&gt;

&lt;p&gt;Now, the actual code handling shooting take advantage of a specific feature of HP Timeshare Basic.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;6180  S$=&quot;WHAM&quot;
6200  PRINT &quot;TYPE &quot;;S$
6210  ENTER 255,B1,C$
6240  B1=B1-(D9-1)
6250  PRINT
6255  IF B1&amp;gt;0 THEN 6260
6257  B1=0
6260  IF C$=S$ THEN 6280
6270  B1=100
6280  RETURN
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Fortunately, I was able to track down a manual for the version of Basic online:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;TSB includes ENTER, a variation on the standard INPUT statement that continues after a time limit is reached.  ENTER has three inputs, a time limit in seconds, a return variable containing the actual time elapsed (or a status code), and then finally the user input. 
 For instance, ENTER 15,T,A$[1,1] will wait 15 seconds for the user to type in a single character.  T will contain the actual time they took, -256 if the timer expired, or -257 or -258 to indicate problems with the terminal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, on line 6210, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ENTER 255,B1, C$&lt;/code&gt; means wait up to 255 seconds (4+ minutes) for the player to type a line, returning the line typed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C$&lt;/code&gt; and the length of time (presumably in seconds) in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The timing in fairly simple in .NET.  But, we have to be concerned about making it device independent. Which give us this:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/jamescurran/b56bc09895d386b564ed8bdf3566c541.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;And this bring us to the rather mysterious &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IO&lt;/code&gt; property in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;context&lt;/code&gt; object, which will be the subject of our next update.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>All Purpose Object Updater</title>
   <link href="http://HonestIllusion.com/blog/2023/12/15/All-purpose-object-updater/"/>
   <updated>2023-12-15T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2023/12/15/All-purpose-object-updater</id>
   <content type="html">&lt;p&gt;This post is for day 15  of the &lt;a href=&quot;https://www.csadvent.christmas/&quot;&gt;2023 C# Advent Calendar&lt;/a&gt; operated by &lt;a href=&quot;https://crosscuttingconcerns.com/&quot;&gt;Matthew Groves&lt;/a&gt;. Thanks for letting me participate!&lt;/p&gt;

&lt;p&gt;In past years, when I’ve written for the Advent Calender (this is my sixth year participating), I’ve noted how many weeks, months or …um… years, since my last blog post. &lt;em&gt;But not this year!&lt;/em&gt; I actually did &lt;strong&gt;SIX&lt;/strong&gt; last month! In fact, I’m in the midst of a series where I refactor the classic game &lt;em&gt;Oregon Trail&lt;/em&gt; into modern C#. &lt;a href=&quot;https://honestillusion.com/blog/2023/11/07/oregon-trail-project-intro/&quot;&gt;Check it out!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, now back to the matter at hand, a one-off bit coding for those just popping up for the holidays.&lt;/p&gt;

&lt;p&gt;In my day job, we had a need to test a object for some condition, and if true, make some change to the object.  For example, if in an order record, a credit card number is given, then the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PaymentType&lt;/code&gt; property must be set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CreditCard&lt;/code&gt;.  The trick is that both the condition (there are many of them) and the changes to be made are stored in a database as JSON.&lt;/p&gt;

&lt;p&gt;Testing for the condition is handled by the &lt;a href=&quot;https://github.com/runxc1/MicroRuleEngine&quot;&gt;MicroRulesEngine&lt;/a&gt;, an open source project I’ve contributed heavily to.&lt;/p&gt;

&lt;p&gt;The method to handle updating the object had to be home-grown, and now is time to share it with the world.&lt;/p&gt;

&lt;p&gt;Perhaps you are familiar with the “non-destructive mutation” syntax added in C# v 9:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var me = new Person { FirstName = &quot;James&quot;, LastName =&quot;Curran&quot; };
var sister = me with { FirstName = &quot;Jean&quot; };
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is conceptional similar, except it’s a &lt;strong&gt;&lt;em&gt;destructive,&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;in-place&lt;/em&gt; mutation, which actually means it’s quite different.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var me = new Person { FirstName = &quot;James&quot;, LastName =&quot;Curran&quot; };
me.Update( new { FirstName = &quot;Jean&quot; });
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;script src=&quot;https://gist.github.com/jamescurran/c5e4887a3a688e397528fd8a8d581e1b.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;The process is quite simple: Iterate over the properties in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;changes&lt;/code&gt; object, look up the same-named property in the target object, and update it, with some sanity checks along the way.&lt;/p&gt;

&lt;p&gt;Now that’s fine if you have an object with the changes (or can deserialize a bit of JSON), but sometimes it’s easier to have the changes in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dictionary&amp;lt;string,object&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/jamescurran/2579061be5b5e74257aae8eb5068f26e.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;This runs basically the same way, except now we are iterating over the items in the dictionary.  It has a couple special features: You can use the word “null” instead of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt; value to set the property to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt;. (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt; itself also works)  And you can use “Y” or “N” (or “Yes” or “no”) to set a boolean to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Which brings us to another special case we had.  Sometimes there was only one property to change, but it had to be set to one of two values depending on condition.  Again, the changes were stored as text in the database, so we settled on the format: “{propertyname}={truevalue} | {falsevalue},  e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mode=3|5&lt;/code&gt;.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/jamescurran/8ed9ad531d799e17091bd30f19cb9d83.js&quot;&gt; &lt;/script&gt;

</content>
 </entry>
 
 <entry>
   <title>The Oregon Trail Project - Part 4 - Trail Events</title>
   <link href="http://HonestIllusion.com/blog/2023/11/30/oregon-trail-project-4-events/"/>
   <updated>2023-11-30T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2023/11/30/oregon-trail-project-4-events</id>
   <content type="html">&lt;h2 id=&quot;oregon-trail-project&quot;&gt;Oregon Trail Project&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Part 0 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/07/oregon-trail-project-intro/&quot;&gt;Intro&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 1 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/26/oregon-trail-project-1-text/&quot;&gt;Markdown to Spectre Console &lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 2 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/27/oregon-trail-project-2-date/&quot;&gt;Dates&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 3 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/29/oregon-trail-project-3-data/&quot;&gt;Data&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 4 : Trail Events  (this one)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://virtualcoffee.io/&quot;&gt;Virtual Coffee’s&lt;/a&gt; Blogging Challenge is on it’s last day! And we’re still quite a ways short of the 100K words goals, so we’re gonna work this down to the last minute….&lt;/p&gt;

&lt;p&gt;Ya’know, I think it about time that we actually get to some real &lt;em&gt;code&lt;/em&gt; for this project.  An important element of gameplay are the occurrences that happen to you along th trail, which the source code refers to as “&lt;em&gt;events&lt;/em&gt;”, but which I’ll call “&lt;em&gt;trail events&lt;/em&gt;”, to avoid confusion with delegates and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;event&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;There are sixteen different things that could happen to you each turn, such as “WAGON BREAKS DOWN–LOSE TIME AND SUPPLIES FIXING IT” and “OX INJURES LEG—SLOWS YOU DOWN REST OF TRIP”.  The selection of which trail event happens on any given turn is handled by this bit of code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;3550  LET D1=0
3560  RESTORE
3570  R1=100*RND(0)
3580  LET D1=D1+1
3590  IF D1=16 THEN 4670
3600  READ D
3610  IF R1&amp;gt;D THEN 3580
3620  DATA 6,11,13,15,17,22,32,35,37,42,44,54,64,69,95
3630  IF D1&amp;gt;10 THEN 3650
3640  GOTO D1 OF 3660,3700,3740,3790,3820,3850,3880,3960,4130,4190
3650  GOTO D1-10 OF 4220,4290,4340,4560,4610,4670
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you’re not familiar with Basic code, let me explain.  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RND(0)&lt;/code&gt; return a random floating point value between 0 and 1, so R1 is between 0 and 100.  The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DATA&lt;/code&gt; value on line 3620 correspond to the percentage chance for each trail event being selected. Each time the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;READ&lt;/code&gt; is executed, the next &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DATA&lt;/code&gt; value is assigned to the variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt;.  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RESTORE&lt;/code&gt; reset the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DATA&lt;/code&gt; so the next &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;READ&lt;/code&gt; would start again with 6.&lt;/p&gt;

&lt;p&gt;So, first pass thru, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D1&lt;/code&gt; is 1, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt; is 6, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R1&lt;/code&gt; is a random number [0..100). If that random number is less than or equal to 6, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GOTO .. OF&lt;/code&gt; lines will direct execution to the first trail event.  If it is greater than 6, it tries again with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D1&lt;/code&gt; as 2, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt; as 11.&lt;/p&gt;

&lt;p&gt;It tries this up to 16 times, with the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt; increasing each time until one hits.  On the 16th iteration, if the random number less than 100, is also less than 95, we go to trail event at line 4610 (line 3650).  On the next time thru the loop, we go directly to line 4670 (“HELPFUL INDIANS SHOW YOU WHERE TO FIND MORE FOOD”).&lt;/p&gt;

&lt;p&gt;So, the percentage chance of any particular trail event happening is the difference between it’s corresponding value in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DATA&lt;/code&gt; line, and the value below it. Which means we can just use the difference, and the order doesn’t matter. This makes the next step possible.&lt;/p&gt;

&lt;p&gt;I want to isolate each of those trail events into individual classes (and then organize them using .NET’s &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/framework/mef/&quot;&gt;Managed Extensibility Framework (MEF)&lt;/a&gt;).  This is major over-engineering, but that pretty much describes this entire project, so we’re not going to let that stop is.&lt;/p&gt;

&lt;p&gt;A typical trail event looks like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;4560  PRINT &quot;HAIL STORM---SUPPLIES DAMAGED&quot;
4570  M=M-5-RND(0)*10
4580  B=B-200
4590  M1=M1-4-RND(0)*3
4600  GOTO 4710
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To translate this into C# with MEF, first we define an Interface to be used by each of the trail events:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public interface ITrailEvent
{
    string Occasion(GameContext context);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(I couldn’t stand calling the method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Invoke&lt;/code&gt;, which led to a trip to a thesaurus, hence &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Occasion&lt;/code&gt;.  That interface may change as this project develops. I think particularly that return value will change.)&lt;/p&gt;

&lt;p&gt;This will make the code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public string Occasion(GameContext context)
{
    context.Miles -= Random.Shared.Next(5, 15);
    context.Resources.Bullets -= 200;
    context.Resources.Misc -= Random.Shared.Next(1, 4);

    return &quot;Hail Storm---Supplies damaged&quot;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, we have to mark this as part of our MEF system.  This involve adding a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[Export]&lt;/code&gt; attribute giving the interface it implements.  Later we’ll ask MEF to gather up all classes that export that interface.  But, also want to know what percent of time that trail event should occur – before we actually load it.  For that we can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[ExportMetadata]&lt;/code&gt; attribute.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[Export(typeof(ITrailEvent))]
[ExportMetadata(&quot;Weight&quot;, 10)]
public class HailStorm : ITrailEvent
{
    ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;MEF will create an object on the fly with the metadata, but we’ll need to define an  interface that represents it:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public interface ITrailEventData
{
    int  Weight { get; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ok, we’ve get the piece there, now we have to work on loading and invoking them.  First we’ll need a place to store them:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[ImportMany]
List&amp;lt;Lazy&amp;lt;ITrailEvent, ITrailEventData&amp;gt;&amp;gt; trailEventsImport;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And then you need to load it up.  Here we just take all trail event defined in the same assembly as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GameContext&lt;/code&gt; class, which is where I’ll all the trail events defined in the original game.  But the advantage here is that we can add another &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;catalog.Catalogs.Add( )&lt;/code&gt; line, pointing to a folder, and it will scan all the assemblies in the folder for more components, so we can extend this with many events, without ever having to recompile the game.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(typeof(GameContext).Assembly));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next build a new list, replacing the individual weights, with a running total, so each gets it own piece of the total range.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var trailEvents = new List&amp;lt;(int weight, ITrailEvent)&amp;gt;(trailEventsImport.Count);
int totalWeight = 0;
foreach (var item in trailEventsImport)
{
    totalWeight += item.Metadata.Weight;
    trailEvents.Add(ValueTuple.Create(totalWeight, item.Value));
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then to randomly select one, at the same frequency at defined in the original code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var val = Random.Shared.Next(totalWeight);
var todaysEvent = trailEvents
    .SkipWhile(te =&amp;gt; te.weight &amp;lt; val)
    .Select(te =&amp;gt; te.evtTrail)
    .FirstOrDefault();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then we just call that&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GameContext context = new GameContext();
// :
// :
todaysEvent.Occasion(context);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>The Oregon Trail Project - Part 3 - Data</title>
   <link href="http://HonestIllusion.com/blog/2023/11/29/oregon-trail-project-3-data/"/>
   <updated>2023-11-29T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2023/11/29/oregon-trail-project-3-data</id>
   <content type="html">&lt;h2 id=&quot;oregon-trail-project&quot;&gt;Oregon Trail Project&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Part 0 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/07/oregon-trail-project-intro/&quot;&gt;Intro&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 1 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/26/oregon-trail-project-1-text/&quot;&gt;Markdown to Spectre Console &lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 2 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/27/oregon-trail-project-2-date/&quot;&gt;Dates&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 3 : Data  (this one)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://virtualcoffee.io/&quot;&gt;Virtual Coffee’s&lt;/a&gt; Blogging Challenge has just a couple days left, and we’re still quite a ways short of the 100K words goals, so lets see how many I can get out before time runs out…&lt;/p&gt;

&lt;p&gt;One of the four principles of Object-Oriented Programming is &lt;em&gt;Encapsulation&lt;/em&gt;, also known as (well, closely related to) &lt;em&gt;Data Hiding&lt;/em&gt;.  Basically, bundling all the data used by one section of the application together, and hiding it away from the rest.&lt;/p&gt;

&lt;p&gt;Programs written for computer languages like the HP TIME-SHARED BASIC used for this version of Oregon Trail are pretty much why that tenet was added.&lt;/p&gt;

&lt;p&gt;In Basic compilers of that era (actually, most were interpreters) &lt;strong&gt;ALL&lt;/strong&gt; variables were global.  (In C# these days it’s actually impossible to have an actual global, and even simulating one is difficult — and very much frowned on). And variable names could only be a single letter, or a single letter followed by a single digit.  Numeric variable were all floating point (no true integers). String variables were available, indicated by a trailing dollar sign (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A$&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;This led to such a mess in most programs, that the Oregon Trail source code helpfully include a map in the comments at the end.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;6470  REM ***IDENTIFICATION OF VARIABLES IN THE PROGRAM***
6480  REM A = AMOUNT SPENT ON ANIMALS
6490  REM B = AMOUNT SPENT ON AMMUNITION
6500  REM B1 = ACTUAL RESPONSE TIME FOR INPUTTING &quot;BANG&quot;
6510  REM B3 = CLOCK TIME START OF INPUTTING &quot;BANG&quot;
6520  REM C = AMOUNT SPENT ON CLOTHING
6530  REM C1 = FLAG FOR INSUFFICIENT CLOTHING IN COLD WEATHER
6540  REM C$ = YES/NO RESPONSE TO QUESTIONS
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(that continues on for another 25 lines)&lt;/p&gt;

&lt;p&gt;So, one of our primary tasks as we port the code is fixing all that.  I’ll give each variable a real name, and limit it’s scope to just the locality where it’s used.&lt;/p&gt;

&lt;p&gt;The first thing done when playing the game, is that you are given some money ($700), and you allocate that to supplies you will need along the trip (Oxen, Food, Clothes, Bullets, and Miscellany plus remaining Cash).  These fluctuate over the course of the game, and their level determine if you win or lose, so I figure they belong in an class of their own.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public class Resources : IFormattable
{
	public int Oxen { get; set; } // 200-300
	public int Food { get; set; } // 0 -
	public int Bullets { get; set; } // 0-
	public int Clothes { get; set; } // 0-
	public int Misc { get; set; } // 0-
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Each turn begins by running through this block of code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1750  IF F &amp;gt;= 0 THEN 1770
1760  F=0
1770  IF B &amp;gt;= 0 THEN 1790
1780  B=0
1790  IF C &amp;gt;= 0 THEN 1810
1800  C=0
1810  IF M1 &amp;gt;= 0 THEN 1830
1820  M1=0
1850  F=INT(F)
1860  B=INT(B)
1870  C=INT(C)
1880  M1=INT(M1)
1890  T=INT(T)
1900  M=INT(M)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If it’s not obvious to you, that ensuring that the levels of Food (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F&lt;/code&gt;), Bullets (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt;), Clothing (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C&lt;/code&gt;) and Miscellany (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M1&lt;/code&gt;) are at least zero, and then truncates each of them as well as the leftover Cash (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;) and distance travels in Miles (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M&lt;/code&gt;) to whole numbers.  Since C# allows us to use true integers, we don’t need the second part, but the first section needs to be moved to a member method of our Resources class:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;	public void Clean()
	{
		if (Oxen &amp;lt; 0) Oxen = 0;
		if (Food &amp;lt; 0) Food = 0;
		if (Bullets &amp;lt; 0) Bullets = 0;
		if (Clothes &amp;lt; 0) Clothes = 0;
		if (Misc &amp;lt; 0) Misc = 0;
	}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, before we move on, I must tell a story from programming assignments past.  In the early 1990s, I was working for a company that was very much mainframe-centered, and very reluctant to change. They had started introducing PCs, and had a PC development team, but you can tell they weren’t happy about it.  Their IT department had just approved Windows 2.0 for use on office machines, despite Windows 3.0 having been out for over a year.&lt;/p&gt;

&lt;p&gt;We (myself and another new hire) were supporting one application and developing another application in C.  The first app was written by a few of the existing developers, where it was their first C program after years of working in Fortran for a mainframe.  It was a paragon of monolithic spaghetti code.  At one spot, I found a 100-line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if()&lt;/code&gt; block, inside a 200-line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for()&lt;/code&gt; loop, inside a 300-line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;while&lt;/code&gt; loop, inside a 400-line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;case&lt;/code&gt; statement, inside a 1000-line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch&lt;/code&gt; block.  The idea of a simple function to do one small task was completely alien to them – partly because any code “entry-point” (which in Fortran would be the program start, but in C was a function), require &lt;em&gt;literally&lt;/em&gt; &lt;strong&gt;seven pages&lt;/strong&gt; of documentation.&lt;/p&gt;

&lt;p&gt;The point of my reliving nightmares of the past, is this: The project leader on writing the new application was one of those hold-overs from Fortran.  But, he’d been trying to keep up with software development trends, and knew global variables were bad, and he wanted to minimize them as much as possible in the new code – but he didn’t quite get it.&lt;/p&gt;

&lt;p&gt;In his design, each section of the application would define a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; to hold all the data needed for that section.  These structs would hold dozens of unrelated variables, which were essentially just a bunch of globals for that module.  But, at least they were localized.&lt;/p&gt;

&lt;p&gt;But it gets worse.  All of these structs were allocated at program startup, and pointers to them were stored in another struct, which we called the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SAAB&lt;/code&gt;, which was officially the “Structured A{something} Allocation Block”, but was really just named after my car. The we had one global variable, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pSAAB&lt;/code&gt;, which held a pointer the that struct.&lt;/p&gt;

&lt;p&gt;The project leader was overjoyed.  He’d had reduced the application to just a single global variable.&lt;/p&gt;

&lt;p&gt;But that was nonsense.  The program had hundred of global variables, just like it’s predecessor; we had just renamed them to something long &amp;amp; complicated.  But whether you call something &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WidgetThingee&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pSAAB -&amp;gt; pWidgetBlock -&amp;gt; pThingeePtr&lt;/code&gt;, if it’s globally accessible, it’s a global variable.&lt;/p&gt;

&lt;p&gt;Which brings us back to the present (where we are dealing with code even older than we were in the above).  We now have to create the classes used by the rest of the code, and in the original, everything was a global, so every variable was used all over the place.  We have to resist the urge to create a class that just holds every variable, and pass that object around like a global.&lt;/p&gt;

&lt;p&gt;The heart of the game are 16 “events” (Wagon breaks down, bandits attack, etc) which could happen to you along the trail. In our final design, each of those will get its own class (actually, a whole module, but that’s getting ahead of ourselves), so we’ll need a game context object which can be passed to and from any of the Event classes, holding all the information that class would need about the status of the game, but no more, lest we fall into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pSAAB&lt;/code&gt; problem of yore.&lt;/p&gt;

&lt;p&gt;After a bit of analysis, I came up with this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public class GameContext
{
    public Resources Resources { get; set; }
    public int TurnCounter { get; set; }
    public int Miles { get; set; }

    public bool ClearedSouthPass { get; set; }       //  REM F1 = FLAG FOR CLEARING SOUTH PASS
    public bool ClearedBlueMountains { get; set; }   //  REM F2 = FLAG FOR CLEARING BLUE MOUNTAINS
    public bool  ClearSouthPassSettingMileage  { get; set;}   //  REM M9 = FLAG FOR CLEARING SOUTH PASS IN SETTING MILEAGE

    public bool AreInjured  { get; set;}   //  REM K8 = FLAG FOR INJURY
    public bool AreIll  { get; set;}       //  REM S4 = FLAG FOR ILLNESS
    public bool HadBlizzard  { get; set;}  //  REM L1 = FLAG FOR BLIZZARD
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And we start on those Event modules (using &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/framework/mef/&quot;&gt;MEF&lt;/a&gt; !)  next time.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Oregon Trail Project - Part 2 - Dates</title>
   <link href="http://HonestIllusion.com/blog/2023/11/27/oregon-trail-project-2-date/"/>
   <updated>2023-11-27T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2023/11/27/oregon-trail-project-2-date</id>
   <content type="html">&lt;h2 id=&quot;oregon-trail-project&quot;&gt;Oregon Trail Project&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Part 0 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/07/oregon-trail-project-intro/&quot;&gt;Intro&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 1 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/26/oregon-trail-project-1-text/&quot;&gt;Markdown to Spectre Console &lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 2 : Dates (this one)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After spending nearly three weeks getting installment #1 out, I figured I should get the next one out quickly, especially since &lt;a href=&quot;https://virtualcoffee.io/&quot;&gt;Virtual Coffee’s&lt;/a&gt; Blogging Challenge have only a few days left.&lt;/p&gt;

&lt;p&gt;Fortunately, the next topic is one I can crank out fast: Fixing how the BASIC code handled dates.&lt;/p&gt;

&lt;p&gt;It goes like this: given an integer number of weeks, return a string of the date that many weeks from the start of the trek (27-Mar-1847), in the form &lt;em&gt;MONDAY MARCH 29 1847&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In the original, it took  quite a bit on rather monotonous code to handle this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1250  D3=D3+1
1260  PRINT 
1270  PRINT &quot;MONDAY &quot;;
1280  IF D3&amp;gt;10 THEN 1300
1290  GOTO D3 OF 1310,1330,1350,1370,1390,1410,1430,1450,1470,1490
1300  GOTO D3-10 OF 1510,1530,1550,1570,1590,1610,1630,1650,1670,1690
1310  PRINT &quot;APRIL 12 &quot;;
1320  GOTO 1720
1330  PRINT &quot;APRIL 26 &quot;;
1340  GOTO 1720
1350  PRINT &quot;MAY 10 &quot;;
1360  GOTO 1720
1370  PRINT &quot;MAY 24 &quot;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That goes on for 50 lines — in a program that’s only 695 lines total — that’s over 7%.&lt;/p&gt;

&lt;p&gt;Fortunately, .NET build date handling and format right into the framework.  All of that can be replaced by:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public static string CurrentDate(int fortnights, int extraDays = 0) 
    =&amp;gt; new DateTime(1847, 3, 29)
        .AddDays(fortnights * 14 + extraDays)
        .ToString(&quot;dddd MMMM d yyyy&quot;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>The Oregon Trail Project - Part 1 - Text (Markdig.SpectreConsole)</title>
   <link href="http://HonestIllusion.com/blog/2023/11/26/oregon-trail-project-1-text/"/>
   <updated>2023-11-26T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2023/11/26/oregon-trail-project-1-text</id>
   <content type="html">&lt;h2 id=&quot;oregon-trail-project&quot;&gt;Oregon Trail Project&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Part 0 : &lt;a href=&quot;https://honestillusion.com/blog/2023/11/07/oregon-trail-project-intro/&quot;&gt;Intro&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 1 : Markdown to Spectre Console (this one)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Continuing my attempt to port the 1978 BASIC code for the Oregon Trail game to C#, the first step is &lt;em&gt;quite simple&lt;/em&gt;. We need a way to display text.&lt;/p&gt;

&lt;p&gt;The original game just had some basic text.  Mostly just a sentence or less at a time.  The largest block was the instructions and it’s not even 300 words. But I wanted to added some formatting to it – in a way that could be adapted to whatever output media this was eventually going to be used.  That was going to be console text in this first version, but HTML or WPF versions might be in the future.  I figured the best way would be to use &lt;a href=&quot;https://en.wikipedia.org/wiki/Markdown&quot;&gt;MarkDown.&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;and-then-i-went-down-a-rabbit-hole&quot;&gt;And Then I went down a rabbit hole&lt;/h2&gt;

&lt;p&gt;I started looking for a markdown component to output to the console. The problem here is that Markdown was intended to translate to Html, so a parser to do that is easy to find. It was also intended for formatting which just can’t be done on a text console.  So, no one tried.&lt;/p&gt;

&lt;p&gt;I did, however, discover &lt;a href=&quot;https://github.com/spectreconsole/spectre.console&quot;&gt;SpectreConsole&lt;/a&gt;, which makes it easier to create beautiful console output.&lt;/p&gt;

&lt;p&gt;So, I could get a really nice output, if I was willing to give up the possibility of non-console output – or I could keep looking for a markdown solution.&lt;/p&gt;

&lt;p&gt;But then I discovered &lt;a href=&quot;https://github.com/xoofx/markdig&quot;&gt;MarkDig&lt;/a&gt;, which is a parser for markdown, which has a number of renderers for output media (Html, Wpf, Xml), but more importantly, it’s essentially a toolkit for building a renderer for other media.&lt;/p&gt;

&lt;p&gt;So, I just used &lt;a href=&quot;https://github.com/Kryptos-FR/markdig.wpf&quot;&gt;Kryptos-FR’s Wpf renderer for Markdig&lt;/a&gt; as a model – really, I stole &lt;em&gt;a lot&lt;/em&gt; from that project – and created a renderer for SpectreConsole.&lt;/p&gt;

&lt;p&gt;For the most part, the translation was straightforward and simple.  For example, a simple bit of markdown like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;This is *emphasized*&lt;/code&gt; becomes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;This is &amp;lt;em&amp;gt;emphasized&amp;lt;/em&amp;gt;&lt;/code&gt; in Html (or, if you prefer, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;This is &amp;lt;span style=&quot;font-style:italic&quot;&amp;gt;emphasized&amp;lt;/style&amp;gt;&lt;/code&gt;), in Spectre, in needs to be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;This is [italic]emphasized[/]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The tricky part was ordered and unordered lists.  In Html (and Markdown), you just say “This is a list, and these are the items”, and the browser takes care of the details of indenting and bullets and sequential numbering and all that – all of which I had to handle directly in the renderer. Which led to another problem.  The parser treats all the text of an item as a block, or, more specifically, as a paragraph. And paragraphs start and end with a newline.  Now, browsers know to strip this whitespace off. But consoles are much more literal when it comes to spaces and new lines. And these line breaks were messing out the flow of the list:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    1.

This is the text for bullet #1

    2.

This is the text for bullet #2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It took me a while to figure out that the solution wasn’t in the list handling code, but involved changing the paragraph handler.  Once I came to that realization, the fix was easy, which just shows how robust the MarkDig parser is.&lt;/p&gt;

&lt;p&gt;And those pretty much handled everything I needed for Oregon Trail.&lt;/p&gt;

&lt;h2 id=&quot;and-the-rabbit-hole-got-deeper&quot;&gt;And the rabbit hole got deeper&lt;/h2&gt;

&lt;p&gt;While that was enough, I wasn’t quite satisfied. I really should to something for headers, but we can’t change the font size in text mode, but SpectreConsole did have a feature called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Figlet&lt;/code&gt; which could be used.  And both MarkDown and Spectre had Tables, and Code Samples.&lt;/p&gt;

&lt;p&gt;But, the problem here is that those features didn’t use the markup style the other features did. Using the advanced features entails creating a object and rendering it, which didn’t really play well with the markup style.  After playing around for much too long, I decided to give up of those, and come back to them later.&lt;/p&gt;

&lt;p&gt;The code for this is available at: &lt;a href=&quot;https://github.com/jamescurran/Markdig.SpectreConsole&quot;&gt;https://github.com/jamescurran/Markdig.SpectreConsole&lt;/a&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>The Oregon Trail Project - Part 0 - Intro</title>
   <link href="http://HonestIllusion.com/blog/2023/11/07/oregon-trail-project-intro/"/>
   <updated>2023-11-07T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2023/11/07/oregon-trail-project-intro</id>
   <content type="html">&lt;p&gt;You might notice that I don’t write much on this blog.  My last entry was the written last Decemeber for the &lt;a href=&quot;https://www.csadvent.christmas/&quot;&gt;2022 C# Advent Calendar&lt;/a&gt;, and I’ve already signed up for the 2023 version, and I had a idea for that.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Side note:  While not writing to this blog, I missed the 20th anniversary of my starting it in &lt;a href=&quot;https://honestillusion.com/blog/2003/08/01/first-things-first/&quot;&gt;August of 2003&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But then, &lt;a href=&quot;https://virtualcoffee.io/&quot;&gt;Virtual Coffee&lt;/a&gt; announced that this month’s Challenge, inspired by the  &lt;a href=&quot;https://nanowrimo.org/&quot;&gt;NaNoWriMo (National Novel Writing Month) Challenge&lt;/a&gt;, would be a Blogging Challenge, where the members, collectively, try to write 100,000 words worth of blog articles.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Side note II:  I’m writing this in VS Code, which has some ChatGPT based extension loaded.  I paused for a second, and it provided me with this bit of text:&lt;/p&gt;
  &lt;blockquote&gt;
    &lt;p&gt;The Oregon Trial Project is a collection of Python scripts that I’ve written to help me understand the trial process in the state of Oregon.&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;This is not even close to what this is going to be about (But then, it is based on my original misspelling of “Trail” in the title.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I came up with one idea for that (which I think I’ll write up after this – but post it first –  just to keep you guessing), and was just going to leave it at that, when I recalled this project, which I had been thinking about for a few months, but hadn’t spend any actual time working on it.  It seemed like it could make a nice serial, which would rack up the word count.&lt;/p&gt;

&lt;h2 id=&quot;the-oregon-trail--background&quot;&gt;The Oregon Trail : Background&lt;/h2&gt;

&lt;p&gt;The Oregon trail, of course, was an actual historical route real American settlers used in the 1800s, but no one cares about that.  The important one was a computer game used in schools in the 1970s &amp;amp; ’80s, to teach history (or something like that).  It was apparently written in 1971, but didn’t go nationwide until 1978, when grammar schools were being given Apple II computers, and Oregon Trail was pretty much the only thing they had that ran on them.&lt;/p&gt;

&lt;p&gt;Or at least, that’s what I’ve been told.  By 1978, I was already in high school, and I missed all that.  I didn’t hear about it until the 2000s, when I was quite surprised to learn it was some sort of cultural phenomenon.  And it mostly involved dying of dysentery.&lt;/p&gt;

&lt;p&gt;So, I was a bit delighted to find copy of the original BASIC source code on the Interwebs a few months ago.  (OK, not the “original-original” – &lt;a href=&quot;https://archive.org/details/200106-tops10-in-a-box&quot;&gt;The one I found claims it was from 1978&lt;/a&gt; (thanks to Jimmy Maher for posting it)).&lt;/p&gt;

&lt;h2 id=&quot;the-project&quot;&gt;The Project&lt;/h2&gt;

&lt;p&gt;The bad news is that I don’t have access to a computer running a HP Timed-Shared BASIC from the 1970s.  The good news is that I learned BASIC back in the ’70s, and it’s simple enough to understand.  So, I can read this source, but can’t run it.&lt;/p&gt;

&lt;p&gt;So, the plan is to port it into a language/environment that I do have access to, specifically C#.&lt;/p&gt;

&lt;p&gt;Now, I’ve been involved in a project very much like this before.  Back in 2008, (&lt;em&gt;could it really be 15 years already?&lt;/em&gt;) I was part of a contest on CodeProject to port a Basic version of a &lt;strong&gt;Star Trek&lt;/strong&gt; game.  Usually, when someone attempts something like this, they usually just work on getting a modern compiler to accept old code, by tricking it into forgetting 40 years of software development techniques.&lt;/p&gt;

&lt;p&gt;You see, back then Basic didn’t have a concept of functions/methods, let alone &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;objects&lt;/code&gt;.  (Neither did Fortran or COBOL or most other languages at the time)  Basic had a keyword &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GOSUB&lt;/code&gt; for calling “subroutines” but they had only the barest resemblance to what we now call a function.  Particular, there was no way to pass arguments to a subroutine, nor a way of return a value. The work-around for this that we all accepted was using global variable to handle those tasks.  Further, most Basic interpreters  only allowed one statement per line. These limitation, plus a few others, led to a code-style known as “spaghetti code”.&lt;/p&gt;

&lt;p&gt;So, when people wanted to port a basic program to modern language, they just made a single class with a single method with hundreds of local variables, and overuse the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;goto&lt;/code&gt; command which most languages still have (but don’t talk about).  An example of this can be seen in one of the other entries in the &lt;strong&gt;Star Trek&lt;/strong&gt; contest (&lt;a href=&quot;https://www.codeproject.com/Articles/28228/Star-Trek-1971-Text-Game&quot;&gt;Star Trek 1971 Text Game&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This always impressed me as a big waste of time. If I was going to port a program to a new language, I was going to take advances of all that language had to offer.  For the &lt;strong&gt;Start Trek&lt;/strong&gt; contest, I completely rewrote the code, giving it a modern Object-oriented design — &lt;strong&gt;&lt;em&gt;but,&lt;/em&gt;&lt;/strong&gt; retaining the exact same look and game play. You can see that here: &lt;a href=&quot;https://www.codeproject.com/Articles/28399/The-Object-Oriented-Text-Star-Trek-Game-in-C&quot;&gt;The Object-Oriented Text Star Trek Game in C++&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That’s my goal for this project:  Oregon Trail, exactly as people remember it, but a completely new (and &lt;em&gt;better&lt;/em&gt;) design under the covers.  Further, I want to separate the actual processing in its own assembly, apart from the UI, so that it can be uses to port the game different clients.  (There may be a Blazer version in the future.)&lt;/p&gt;

&lt;p&gt;As the series progresses, I’ll be taking you through this process…&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>What is (was) Beta Software?</title>
   <link href="http://HonestIllusion.com/blog/2023/11/05/what-is-beta-software/"/>
   <updated>2023-11-05T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2023/11/05/what-is-beta-software</id>
   <content type="html">&lt;p&gt;For &lt;a href=&quot;http://virtualcoffee.io&quot;&gt;Virtual Coffee’s&lt;/a&gt; &lt;a href=&quot;https://dev.to/virtualcoffee/blogging-2023-monthly-challenge-3kng&quot;&gt;November Blogging Challenge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I just wrote another blog article which I’ll post tomorrow, which explains a bunch about this, but since I decided to slip this one in first, you’ll just have to wait for it.&lt;/p&gt;

&lt;h1 id=&quot;what-is-beta-software-and-why-do-we-call-it-that&quot;&gt;What is Beta Software, and Why Do We Call It That?&lt;/h1&gt;

&lt;p&gt;These days, when we refer to “beta” software, it’s generally means some half-baked, buggy, pre-release version of the code, where the developers are still working on it.  This is a bit different from it’s original meaning.&lt;/p&gt;

&lt;p&gt;It started in the dim dates of computing, in the 1960s &amp;amp; ’70s.  Back then we didn’t have the fancy graphical user interfaces on our software as we do now.  (I use “we” and “our” to refer to our collective consciousness – I’m not quite that old.)&lt;/p&gt;

&lt;p&gt;In those days, programs were more like what we’d call a “console” or “command-line” program today – although that still implies the existence of a video display, which there wasn’t. These would be loaded from a stack of punch cards.&lt;/p&gt;

&lt;p&gt;Lacking interactivity, programs tended to be single-purpose.  You run it, it does something, it reports what it did (which came via a printout, often came off the printer hours after the program was actually run).  Also, there wasn’t much retail software.  Most was either included as part of the operating system, or written in-house.&lt;/p&gt;

&lt;p&gt;In-house software didn’t have the formal QA process we have today, as the users were generally the authors of the code.  But it’s always good to have a second set of eyes looking at something, so if someone else needed that functionality, they could often get a copy of the code, with the promise that they would report back any problems.   This became known as the “Beta site” for the code — the second place the code was used.  The author’s workplace would, in theory, be the “Alpha site” but no one called it that.&lt;/p&gt;

&lt;p&gt;The point is that the code that went to the beta site was the complete, final version of the program.  If someone at the beta site find and reported a bug, it might be fixed in version 2 – if there was a version 2.  (We hadn’t got to point-versions yet.)&lt;/p&gt;

&lt;p&gt;It was only is the packaged software era, which basically started when we moved from mainframes to PCs in the ’80s &amp;amp; ’90s, and particular as we moved to graphical interfaces – where the user interface, separate from the basic function of the application, grew in importance, requiring design input from many people, and being a source of many bugs, did the idea of release unfinished software to a select group of people rise.  And this is when we coined the back-formation “beta software” for this half-baked code that went to the beta site.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>A  Literary Clock in Blazor</title>
   <link href="http://HonestIllusion.com/blog/2022/12/13/blazor-literary-clock/"/>
   <updated>2022-12-13T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2022/12/13/blazor-literary-clock</id>
   <content type="html">&lt;p&gt;This post is for day 13  of the &lt;a href=&quot;https://www.csadvent.christmas/&quot;&gt;2022 C# Advent Calendar&lt;/a&gt; operated by &lt;a href=&quot;https://crosscuttingconcerns.com/&quot;&gt;Matthew Groves&lt;/a&gt;. Thanks for letting me participate!&lt;/p&gt;

&lt;p&gt;When I last blogged (um.. four &lt;em&gt;months&lt;/em&gt; ago…), we discussed putting time-related quotes into your PowerShell prompt (Click the left arrow at the top of the page to see that one), and I mentioned a Blazor version.  It’s time to present that.&lt;/p&gt;

&lt;p&gt;Some background: back in 2011, &lt;a href=&quot;https://www.theguardian.com/books/table/2011/apr/21/literary-clock?CMP=twt_gu&quot;&gt;The Guardian&lt;/a&gt; built a list of literary quotes containing a time of day, from reader contributions, and made the lists publically available.  They been re-used on a &lt;a href=&quot;https://www.instructables.com/Literary-Clock-Made-From-E-reader/&quot;&gt;number&lt;/a&gt; of &lt;a href=&quot;http://jenevoldsen.com/literature-clock/&quot;&gt;projects&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One such project is &lt;a href=&quot;https://github.com/JohannesNE/literature-clock&quot;&gt;https://github.com/JohannesNE/literature-clock&lt;/a&gt;, which uses Javascript to present the appropriate quotes on a webpage.  The repository also maintains a pipe delimited list of all the quotes, and has a program written in R to read that file and generate individual json files for each minute.&lt;/p&gt;

&lt;p&gt;That’s all well &amp;amp; good, but I do C#, so I figured I’d port that in Blazer (while making the R program into a C# console app).&lt;/p&gt;

&lt;p&gt;After that app runs, for each minute (well, for 958 of the 1440 minutes in a day), there’s a json file with a name in the form “HH_MM.json”, which holds an array of objects which look like this:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/jamescurran/11d9dea47ef0741128fcc0959afb2ce1.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;Not sure how fast the R version is, but on my PC, the C# version takes 13 seconds to produce the 958 files.&lt;/p&gt;

&lt;p&gt;So, let’s look at the Blazor page, a piece at a time. We need to do something once every minute, so on start, we set up a timer, which calls the method which does the real work:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;protected override  Task OnInitializedAsync()
{
	_timer = new Timer(obj =&amp;gt; OnTimerCallback(), null, TimeSpan.Zero, TimeSpan.FromMinutes(1));
	return Task.CompletedTask;
}
private void OnTimerCallback()
{
	_ = InvokeAsync(() =&amp;gt;
	{
		UpdateText(DateTime.Now);
	});
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The reason we pass in the time will become clear in a minute.  In &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UpdateText&lt;/code&gt;, we read the quote file for the passed time:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;protected async  void UpdateText(DateTime time) 
{
	var strTime =time.ToString(&quot;HH_mm&quot;);
	Quote[] quotes = await Http.GetFromJsonAsync&amp;lt;Quote[]&amp;gt;($&quot;times/{strTime}.json&quot;) ?? Array.Empty&amp;lt;Quote&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But, since not every minute has a quote, if we don’t find any for the current minute, we’ll hold on to and use the previous minutes – or, if we don’t have any already (i.e., we just started), we just go backwards in time until we find one:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;	if (quotes.Any())
		_quotes = quotes;
	else if (_quotes == null)
	{
		UpdateText(time.AddMinutes(-1));
		return;
	}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then we just randomly pick a quote from the array&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;	_quote = _quotes[Rnd.Next(quotes.Length)];
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And bind it to the page:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;	&amp;lt;div id=&quot;main_text&quot;&amp;gt;
		&amp;lt;blockquote id=&quot;lit_quote&quot;&amp;gt;@_quote.Prefix&amp;lt;em&amp;gt;@_quote.Quote_time_case&amp;lt;/em&amp;gt;@_quote.Suffix&amp;lt;/blockquote&amp;gt;
		&amp;lt;cite&amp;gt;
			-
			&amp;lt;span id=&quot;book&quot;&amp;gt;@_quote.Title&amp;lt;/span&amp;gt;,
			&amp;lt;span id=&quot;author&quot;&amp;gt;@_quote.Author&amp;lt;/span&amp;gt;
		&amp;lt;/cite&amp;gt;
	&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The javascript version includes a formula to adjust the font size to accomodate the widely differing quote lengths.  This is easily transaled into C#:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;	var quote_len = _quote.Quote_first.Length +
	                 _quote.Quote_time_case.Length +
	                 _quote.Quote_last.Length;

	_fontSize = 7.000864 - 0.01211676 * quote_len + 0.00001176814 * quote_len * quote_len - 1.969435e-9 * quote_len * quote_len * quote_len;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And Blazor:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &amp;lt;style&amp;gt;
    	#lit_quote {
    		font-size: @(_fontSize)vw
    	}
    &amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can see the clock in action (along with two other online clocks of mine) here: &lt;a href=&quot;https://noveltheory.com/clock/&quot;&gt;https://noveltheory.com/clock/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The full project repository (which includes a folk of the original Javascript version) is here &lt;a href=&quot;https://github.com/jamescurran/literature-clock&quot;&gt;https://github.com/jamescurran/literature-clock&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Putting quotes in your Powershell prompt.</title>
   <link href="http://HonestIllusion.com/blog/2022/08/13/Powershell-quote-prompt/"/>
   <updated>2022-08-13T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2022/08/13/Powershell-quote-prompt</id>
   <content type="html">&lt;p&gt;I just discovered my friend Meg Gutshall has a blog, and was reading her latest entry (from last year – she updates hers about as often as I update this one): &lt;a href=&quot;https://meghangutshall.com/2021/07/08/random-quotes-generator/&quot;&gt;A Random Quote Generator for Your Terminal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It displays a quote as part of the prompt in a BASH shell.  I thought this was a cool idea, but I don’t use BASH – I use PowerShell, so I figured I port hers to PS. I’d also found this project on Github (&lt;a href=&quot;https://github.com/JohannesNE/literature-clock&quot;&gt;Literature Clock&lt;/a&gt;) which collects quotes based on the time (e.g., “At 7:32, he suffered a fatal stroke,” &lt;em&gt;IT&lt;/em&gt;, Stephen King), and I thought it would be cool to use those.&lt;/p&gt;

&lt;p&gt;But, I’m getting a bit ahead. Let’s first talk of changing the PowerShell prompt.  The prompt is produced by a script which is held in a file named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Microsoft.PowerShell_profile.ps1&lt;/code&gt;, which, on my system is located in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WindowsPowerShell\&lt;/code&gt; subfolder of my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Documents&lt;/code&gt; folder.  I’m not sure how standard that is, but try looking there for it.&lt;/p&gt;

&lt;p&gt;The default prompt is the current folder name followed by a “&amp;gt;”.  This is fine if you have short folder names, but no one has short path names anymore.  So now it looks something like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;PS C:\Users\James\Source\repos\Tests\MyBlazorApp1&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And you’ve already used half the line before you typed anything.  The simplest command wraps to the next line.  That’s too messy for me.  So, I first put the current directory on it’s own line, and then threw in the current date &amp;amp; time for good measure:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:\Users\James\Source\repos\Tests\MyBlazorApp1
12-Aug-2022 18:52:29
PS&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(The path is in magenta and the date in green, but I don’t seem to be able to color text in markdown.)&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/jamescurran/43824e609e8f2858be5665ad4d02f95b.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;Ok, now we move to adding the quotes. The Literature Clock project has a large collection of time-based quotes from books, organized by minute.  They have at least one quote for 950 of the 1440 minutes in a day. Some are duplicated if it’s unclear if the time refers to AM or PM.  And while many minutes have no quote, others (like midnight or 3 o’clock) have dozens. The quotes are kept in a CSV (actually pipe-separated) file.  The project includes a javascript program to display the clock on a webpage, and a script written in the R language to convert the CSV file into a collection of JSON files.  It’s the json files that the javascript and this project will use.&lt;/p&gt;

&lt;p&gt;I’ve also ported the clock webpage into Blazor (as well as port the R program into C#) so that might be a future blog story.&lt;/p&gt;

&lt;p&gt;For each minute, there’s a json file with a name in the form “HH_MM.json”, which holds an array of objects which look like this:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/jamescurran/11d9dea47ef0741128fcc0959afb2ce1.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;So, our steps will be: Get the time, format it like the filename, read the file, deserialize it into an array of objects, pick one randomly, and display it.  Except for the last step, the PowerShell is just as straightforward as the description:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$quote = get-content &quot;C:\Users\zames\OneDrive\Documents\times\$(Get-Date -Format &quot;HH_mm&quot;).json&quot;  | ConvertFrom-Json  | Get-random
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The rest just is formatting and coloring it to look nice.  Full script here:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/jamescurran/3110a8dfbb1ba85a6e5f6de41c7edbdd.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;&lt;img src=&quot;/images/PowerShellPrompt.png&quot; alt=&quot;PowerShellPrompt&quot; /&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>TaskCollection - Making your async code parallel</title>
   <link href="http://HonestIllusion.com/blog/2021/12/17/TaskCollection/"/>
   <updated>2021-12-17T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2021/12/17/TaskCollection</id>
   <content type="html">&lt;p&gt;When I wrote an article for the &lt;a href=&quot;https://www.csadvent.christmas/&quot;&gt;2021 C# Advent Calendar&lt;/a&gt; on Tuesday, I promised to post a couple days in a row.&lt;/p&gt;

&lt;p&gt;That didn’t work out.&lt;/p&gt;

&lt;p&gt;But at least I eventually got to it.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async\await&lt;/code&gt; keyword added to C# a few years ago greatly simplified use asynchronous code in our applications.  However, asynchronous code is inheriently tricky, and in trying to make it simple, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async/await&lt;/code&gt; sometimes undermines itself.&lt;/p&gt;

&lt;p&gt;Consider the code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;_cacheCustomers = await LoadTableAsync(&quot;Customers&quot;);
_cacheProducts = await LoadTableAsync(&quot;Products&quot;);
_cacheOrders = await LoadTableAsync(&quot;Orders&quot;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Fairly typical code to preload three tables from a database that we are going to use.  Three separate round-trips to the data server with much waiting for the response from that server. So the perfect situation for those actions to be run in parallel, which is why we used the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;...Async&lt;/code&gt; version of the method, and used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Note that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadTableAsync&lt;/code&gt; is just generic example representative of long-running non-CPU bound method. Could be a database, could be a Web API, etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But they &lt;em&gt;aren’t&lt;/em&gt; going to be run in parallel, because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; means, well, await.  Wait for the first call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadTableAsync&lt;/code&gt; to complete before we start the second call.  Now, granted, &lt;em&gt;something&lt;/em&gt; will be run at the same time as each of those calls, but since you probably have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt;s going all the way up the call chain back to the Main() function, it’s probably going to be the operating system.  But, importantly, it won’t be the other calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadTableAsync&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What we need to do is start them all first, and then wait for them to finish.  Something like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var taskCustomers = LoadTableAsync(&quot;Customers&quot;);
var taskProducts = LoadTableAsync(&quot;Products&quot;);
var taskOrders = LoadTableAsync(&quot;Orders&quot;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And then, at some point later,&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;_cacheCustomers = await taskCustomers;
_cacheProducts = await taskProducts;
_cacheOrders = await taskOrders;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;or alternately,&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Task.WaitAll(taskCustomers, taskProducts, taskOrders);
_cacheCustomers = taskCustomers.Result;
_cacheProducts = taskProducts.Result; 
_cacheOrders = taskOrders.Result;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The advantage of this is that between the LoadTableAsync()s, and the waits, you can put some cpu-bound actions, so that when you get to the waits, your data is already waiting for you.  The database calls become &lt;em&gt;free&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;Now, this is all well &amp;amp; good, but we’ve added a bunch of lines of code, and that gets messy, particularly if the return value of the method isn’t being used.  Consider:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;await FillListFromTableAsync(&quot;Customers&quot;, _cacheCustomers);
await FillListFromTableAsync(&quot;Products&quot;, _cacheProducts);
await FillListFromTableAsync(&quot;Orders&quot;, _cacheOrders);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To make these parallel, now we have to create the local task variables, just to use the the Task.WaitAll. And if you have more than three, it really starts to get out of hand.&lt;/p&gt;

&lt;p&gt;Which brings us to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TaskCollection&lt;/code&gt;, a simple class to manage that for you.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var tasks = new TaskCollection();
tasks += FillListFromTableAsync(&quot;Customers&quot;, _cacheCustomers);
tasks += FillListFromTableAsync(&quot;Products&quot;, _cacheProducts);
tasks += FillListFromTableAsync(&quot;Orders&quot;, _cacheOrders);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and then,&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;_logger.LogInformation($&quot;{tasks.Count} tasks queued, waiting on {tasks.Running}&quot;);
tasks.WaitAll();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It includes the properties:
     &lt;strong&gt;Count&lt;/strong&gt; - total number of tasks in the collection (running and completed)
     &lt;strong&gt;Running&lt;/strong&gt; - number of tasks still running.&lt;/p&gt;

&lt;p&gt;And the methods:
    &lt;strong&gt;RemoveCompleted&lt;/strong&gt; - Removes completed tasks from internal list.  Afterward, Count == Running.
    &lt;strong&gt;WhenAll&lt;/strong&gt; - Returns a task which completes when all tasks on the list has completed.&lt;/p&gt;

&lt;p&gt;Full code given here:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/46d90e84646c3c308cdea0d664addd1d.js?file=test.md&quot;&gt; &lt;/script&gt;

</content>
 </entry>
 
 <entry>
   <title>TimeThis! - Simple timings for code blocks (Fun with IDisposable)</title>
   <link href="http://HonestIllusion.com/blog/2021/12/14/Simple-timings/"/>
   <updated>2021-12-14T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2021/12/14/Simple-timings</id>
   <content type="html">&lt;p&gt;This post is for day 14  of the &lt;a href=&quot;https://www.csadvent.christmas/&quot;&gt;2021 C# Advent Calendar&lt;/a&gt; operated by &lt;a href=&quot;https://crosscuttingconcerns.com/&quot;&gt;Matthew Groves&lt;/a&gt;. Thanks for letting me participate!&lt;/p&gt;

&lt;p&gt;After I reserving my spot for this year, I realized two things:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;I forgot to sign up last year, after participating the first three years and&lt;/li&gt;
  &lt;li&gt;Largely due to that, I haven’t written &lt;em&gt;anything&lt;/em&gt; to my blog in &lt;strong&gt;two years&lt;/strong&gt;!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, to make up for that, I figured, “Let’s post a couple in a row”.  So, if you like this, check back here tomorrow and Thursdays for more!&lt;/p&gt;

&lt;hr /&gt;
&lt;p&gt;Sometimes, you want to know long a bit of code it taking to run.  Maybe not a full code analysis, but a read-out of how many second something is taking, particular if your not sure which section is the problem, or if one section varies a lot from run to run.&lt;/p&gt;

&lt;p&gt;Doing this in C# is rather straight-forward : Just create and Start() a Stopwatch object before the code you want to time:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var sw = new StopWatch();
sw.Start();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And then afterwards, Stop() the timer, and report the results:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sw.Stop();
Console.WriteLine($&quot;It took {sw.Elapsed}&quot;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(Plus you have to remember to include “using System.Diagnostics” in your code.)&lt;/p&gt;

&lt;p&gt;Two simple steps, but that’s the problem – &lt;em&gt;Two&lt;/em&gt; steps, with your code in between, which makes it tricky to package into a neat library function.&lt;/p&gt;

&lt;p&gt;One could make it into a method which takes a lambda, which would be the code you’re trying to time, but that messy – all local variables used need to be passed in, and all outputs need to be passed out.  And now you’re changing the code you want to test.&lt;/p&gt;

&lt;p&gt;Now, bak when I was wrting C++, this was simple.  Just create a class, which did the setup in its constructor, and the reporting in its destructor.  We create an object of that class where we want to start it, and it is automatically destroyed (and reports the results) when it goes out of scope.&lt;/p&gt;

&lt;p&gt;Unfortunately, in C#, we don’t have destructors that work like C++’s.  But we do have the IDisposable.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;using (var tt = new TimeThis(_logger, &quot;My Complex code&quot;))
{
    // my complex code here
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will add to your logs something like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Complete:My Complex code: Elapsed: 00:00:01.3521282
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The message (“My Complex code” in the example), is optional.   That’s nice, but we can make it a bit neater with an extension method.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;using (_logger.TimeThis())
{
    // my complex code here
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here’s the full code.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/jamescurran/dbb537c68d2fd898178b4b3d4ef6f290.js&quot;&gt; &lt;/script&gt;

</content>
 </entry>
 
 <entry>
   <title>Cleanup Scaffolded Code with modelbuild</title>
   <link href="http://HonestIllusion.com/blog/2019/12/12/cleanup-Scaffolded-Code-with-ModelBuilder/"/>
   <updated>2019-12-12T00:00:00+00:00</updated>
   <id>http://HonestIllusion.com/blog/2019/12/12/cleanup-Scaffolded-Code-with-ModelBuilder</id>
   <content type="html">&lt;p&gt;This post is for day 12  of the &lt;a href=&quot;https://crosscuttingconcerns.com/The-Third-Annual-csharp-Advent&quot;&gt;2019 C# Advent Calendar&lt;/a&gt; operated by &lt;a href=&quot;https://crosscuttingconcerns.com/&quot;&gt;Matthew Groves&lt;/a&gt;. Thanks for letting me participate!&lt;/p&gt;

&lt;p&gt;Now, this isn’t specifically about C#; it’s more directly about .NET Core and Visual Studio tooling, but we use C# in it, so it counts….&lt;/p&gt;

&lt;p&gt;EntityFramework would really like you to use the “code first” approach to defining your database.  In fact, EntityFramework.Core seems to have removed support for the “Database First”  method.  Unfortunately, in my experience, in at least 90% of projects, the database already exists, and we have to work with that, and reverse engineer Code First classes from our database.&lt;/p&gt;

&lt;p&gt;Fortunately, .NET Core offers us the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scaffold-DbContext&lt;/code&gt; command of the EF Core Package Manager Console to do that reverse engineering for us.   It will generate a DbContext-derived class for the database, plus one file (with one class) for each table, defining the fields. But this article is not about that, you can read more about it &lt;a href=&quot;https://docs.microsoft.com/en-us/ef/core/managing-schemas/scaffolding&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately, the code for all the other details about each table — Keys, indexes, relationships –  are put entirely in the OnModelCreating() method of the DbContext class.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/jamescurran/d70cc694d379878542d7cb998b0645b2.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;There are two problems with this: First, any reasonable database will probably have a couple dozen tables, meaning that method will be several hundred lines long — I never want to have a method that long. More importantly, the properties and the other data are both equal parts of the schema, and they should be recorded in the same place (or at least the same file).&lt;/p&gt;

&lt;p&gt;So I devised a plan to do just that.  For each  table/class, I’d create a secondary static class holding just a single extension method.   I’d move the schema defining code for that table into the extension method, and then call  it from the dbcontext’s OnCreate.  That leaves the OnCreate with essentially just a list of the tables in the database.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/jamescurran/20f6744169bffa6586c8fc86792d10be.js&quot;&gt; &lt;/script&gt;

&lt;script src=&quot;https://gist.github.com/jamescurran/c07052a6279f41c1c4996ddc228d509b.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;However, writing the boilerplate code for this got rather tedious, especially since the rest of the work was mostly just cut’n’paste.  So I figured I’d create a code snippet to provide the framework.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/jamescurran/9177395e9a4d7e89a230b101612fca9a.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;Do use, crate a file, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modelbuild.snippet&lt;/code&gt;, out of the gist, then install it as a code snippet: Tools/Code Snippet Manager…/Add.&lt;/p&gt;

&lt;p&gt;Then, in a source file for one of the classes for a table, just before the final closing brace (closing the namespace), type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modelbuild&lt;/code&gt;, &lt;em&gt;[tab]&lt;/em&gt; &lt;em&gt;tablename&lt;/em&gt; &lt;em&gt;[enter]&lt;/em&gt;, and Visual Studio will fill in the boring part, then you just have to cut’n’paste from the DbContext class to this class, and replace the code with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modelBuilder.Configure&lt;/code&gt;&lt;em&gt;tablename&lt;/em&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;()&lt;/code&gt;&lt;/p&gt;

</content>
 </entry>
 
 
</feed>