Jon Rumsey

An online markdown blog and knowledge repository.


Project maintained by nojronatron Hosted on GitHub Pages — Theme by mattgraham

Occasional Retrospective Notes

Semi-regular notes taken during my software developer journey.

Final Entry of 2023

I've been considering changing-up this semi-irregular blogging style note taking for something that will be more helpful when I need to reference it in the future. While it is good for me (generally) to continue to write about my experiences in tech, the future me usually gets frustrated searching through past-me notes because the solutions aren't always documented in a reproducable way. This will take some time to sort out, and will be part of what I hope will be a slight reconfiguration of my routines and methodologies, so I can continue to improve and not get stuck in any ruts.

The Mobile Weather App color and theming and tabbed-based navigation have been implemented and there appear to be very few issues. Next step is to produce a point build for on-phone testing (upgrading the current point-release version) and moving forward with the next goals for the app. Hopefully I'll have the app in a useable state before the end of January 2024. Meanwhile, I have several other tasks to accomplish especially around the house here, so I have plenty to do!

Happy new year! :tada:

Thursday 28-Dec-2023

I managed to work through designing a functional Merge-Sort algorithm, started yesterday, and lots of sketching and planning then and this morning, and my custom-designed Jest tests are passing. However, it does not pass the same test when run on the FreeCodeCamp webpage. Not sure what that is about, but I'm going to move on to other challenges so I don't get stuck.

The next challenge was Binary Search. This wasn't too difficult, but I could not complete it within 45 minutes so it is difficult to say if I'd complete it during an actual technical whiteboard session.

Wednesday 27-Dec-2023

Compared TabBar and Flyout Shell view implementations for my mobile weather app.

The TabBar implementation is closer to what I envisioned:

The problem is it does not support custom color images and instead relies on black and white or font-based icons. :upside_down_face:

Flyout seemed to be a good enough fit and actually has a few perks that TabBar does not:

Tuesday 26-Dec-2023

Started redesigning the weather app navigation, with the goal of including a navigation bar at the bottom of the app. This requires designing some icons, updating AppShell, among other things.

Friday 23-Dec-2023

Completed Quick-sort and Insertion-sort at FreeCodeCamp.

Quick-sort is a divide-and-conquer algorithm that utilizes recursion to split values within the array between larger-than, and smaller-than values. A pivot value is determined (carefully) so that all values greater than or equal to it are moved into a right array, and those lower than it are moved to a left array. The reason the pivot is so crucial is a poorly selected pivot will allow the recursive calls to exhaust the stack, rather than pick sets of values to put into each sub-array (left and right). Until today I wasn't aware of the Big O complexity in time of spread syntax (aka spread operator) in JavaScript, but I assumed it would be no worse than simply iterating over each array that I intend to merge. According to this StackOverflow conversation, it is O(n) in time.

One hurdle was determining how to define a sensible pivot. It took a while to find one that would work on the small datasets i was working with:

// two items in the array and not the same number
let pivotVal = ((array[0] + array[1]) / 2);

// three or more items in the array
let last = array.length - 1;
let pivotVal = ((array[0] + array[1] + array[last]) / 3);

These codelines are not necessarily robust solutions for any input, but they worked for the existing data-sets. For a more robust algorithm, it would be beneficial to use a randomized value, or a more mathematically-derived number, given all values in the array.

As an aside, I ran into a sub-challenge where JavaScript would treat a single-item array in a function argument as a String or Number instead of an Array. Before I gated the Quick-sort function with a minimum 2-item array limit, I was forcing a re-cast or verifing the Type ahead of taking actin on the input:

function func1(inputArr) {
  if (inputArr.length == 1) {
    if (Array.isArray(inputArr)) {
      ...
    }
    ...
  }
  ...
}

Insertion-sort is a small, stable sorting algorithm that also utilizes a common value-swapping algorithm. Frakly, it is easy to confuse this one with Bubble-sort, however it tends to sort items toward the "left" side of the array rather than buble high-values up to the top. Time effeciency is O(n^2) and space O(1), and is good enough for small arrays so it can easily be used as an alternative to another algorithm or perhaps as part of a recursive portion of a larger sorting algorithm.

Thursday 22-Dec-2023

After struggling with the NWS API for several hours, I discovered it has experienced a partial outage. Being relatively new to the API, I wasn't sure my code was doing the right things so I was focused on debugging and other troubleshooting steps. The NWS says the partial outage will continue until early 2024, so development on the weather app will be on hold for at least another couple weeks.

Meanwhile, I completed several FreeCodeCamp challenges including a bubble-sort algorithm.

Bubble-sort Key Takeaways:

private static void BubbleSort(int[] arr)
{
  ...
  while (unchanged == false)
  {
    ...
    if (idx+1 < arr.Length && arr[idx] > arr[idx+1])
    {
      // this is a common swapping algorithm
      int temp = arr[idx];
      arr[idx] = arr[idx+1];
      arr[idx + 1] = temp;
      itemSwapped = true;
    }
    // track the inverse of itemSwapped outside of the swapping loop
    unchanged = !itemSwapped;
  }
  return; // in-place array sorting algorithm
}

Tuesday 20-Dec-2023

Working on adding NWS Alert information to the mobile weather app. One approach has been devised in a separate dev/test project. I also explored using Google's Geocoding API to get Lat/Lon for a city name. The API isn't perfect (and in fact the API and the JSON output are both fairly complex), but for most common US city names it works well enough. I might look into alternatives or skip requesting a city name and instead try to use a map-based geocoding solution. MAUI 8 appears to have library functions that will help with that.

The basic idea for gathering and displaying any weather alert is to:

An alert JSON object is actually an array of objects, so in the event there are multiple alerts my app will need to iterate through them all and ensure readable output to the mobile app UI.

I've been wanting to clean-up some of the code and UI look-and-feel in the mobile weather app:

Another feature that needs to be implemented: Applying secrets and configuration to the app. If I'm going to use my own secrets, I don't want to store them with the code.

Now I've been humbled: While exploring the NWS API some more, I've come to realize my weather app is looking at only forecast data and not current conditions or observation station data. I'll be able to use the existing code for the most part, but I will need to insert the current observations code into the app and move the forecast data to other pages. This means navigation will be necessary, so I'll have to start working on navigation sooner than later.

Saturday 16-Dec-2023

Completed initial color scheme and light/dark theme implementation for the mobile weather app. Some key takeaways:

The mobile weather app has been deployed a few times for Android now. Here are some take-aways:

Thursday 14-Dec-2023

Time is going by pretty fast. Lots happening the last week or so slowed or blocked coding progress. Nonetheless I eeked out some time to:

What I've learned while exploring the .NET MAUI Community Toolkit:

Future .NET MAUI Community Toolkit exploration:

Sunday 3-Dec-2023

One of the challenges of designing a MAUI app is how to handle platform-specific actions, such as accessing Location Services. Windows, macOS, and iOS all handle such features differently and they are not completely abstracted in the framework. So #if #else and #endif statements must be sprinkled through the code so that these platform-specific calls can be made when they return true, e.g. #if ANDROID.

I experience some challenges in this context:

  1. Barring previous experience with basically all involved platforms, it is not always obvious that a platform-specific call must be made. To be fair through, many platform-specific features and capabilitys have been abstracted especially in the UI, and in the build processes.
  2. Intellisense and the C# Language tools do a very poor job of linting and formatting code when the platform-specific logic code blocks are added. First of all, they are all left-aligned all the way to the gutter, which breaks continuity within the class and method of the current statement/code block it is surrounding. Secondly, Visual Studio tries to reconcile brackets while writing code and usually will get the wrong (inserting or deleting them while typing) when the platform-specific decision syntax is added or moved.

/soapbox

Saturday 2-Dec-2023

A few days ago I completed an MS Learn training module "C# Null Safety" and added my thoughts.

Wednesday 29-Nov-2023

I've had a few adventures in MAUI over the last several days. Here's an overview with key takeaways:

Adding a Test Project

MAUI build definitions return binary executables, not DLL libraries, because it is building for platforms. A Test Project wants to consume a DLL to perform tests against, so a couple things need to happen besides just making the target project a dependency:

More on this as I work on unit testing MAUI in the future.

Displaying Image Icons from the NWS API

The API requires the caller to include custom Accept and UserAgent headers to define application/ld+json and (its just me, name@email.etc) identifiers. There is no API Key at this time (although the documentation promises that will be necssary "in the future"). This is true of the several endpoints I have worked with so far.

One call has perplexed me, however. Here is an overview of my movements through wondering, confusion, and finally realization:

One additional note: I tried to leverage the MAUI Lifecycle eventing system, but the associated ViewModel was already inheriting ObservableObject (for simplified property update notifications) and in order to register and consume Lifecycle Events it would need to inherit from Window. Multiple inheritance is not supported in C#, and I wasn't willing to factor-out the ObservableObject inheritance to create a base implementation to provide the capability. That's okay, I don't need to leverage lifecycle events just yet.

Mobile Location Feature

Started looking into enabling the Android built-in location capability. Since this might take a while, and right now the app is working and looks okay, I also initialized a GitHub repo to track changes, helping me to document actions going forward, or roll-back dev branches that don't need to be completed.

Sunday 26-Nov-2023

More investigating MAUI Mobile Weather App design and implementation: Using DI and a collection based on Collection<T>, in conjunction with an MVVM design model, data from a web API can added to a page. The Collection base class provides generic storage of custom Types - value or reference, includes an indexer, and implemented methods following IList and IEnumerable interfaces (among others), like Add, Clear, IndexOf, Remove, and several more.

Friday 24-Nov-2023

I ran into a common issue in MAUI when leveraging Dependency Injection: "Missing default constructor for {viewModel name}". This happens when a new constructor is implemented. MAUI ContentPage.BindingContext expects a ViewModel codepage to have a parameterless constructor for initializing the object. The error also mentions a missing type converter.

For example, instead of doing this:

<ContentPage
  ...
  >
...
<ContentPage.BindingContext>
  <viewModels:MyViewModel />
</ContentPage.BindingContext>
...

...remove <ContentPage.BindingContext> element(s) and update the DI Container (in MauiProgram.cs) to register the Views and ViewModels:

...
  // add the view
  builder.Services.AddTransient<MainPageView>();
  // add the view model
  builder.Services.AddSingleton<MainPageViewModel>();
...

...and then add to the code-behind of each registered View, a BindingContext assignment to the CTOR-injected view model:

public partial class MainPage : ContentPage
{
  public MainPage(MainPageViewModel viewModel)
  {
    BindingContext = viewModel;
    InitializeComponent();
  }
}

Dealing with Null values and Nullable Types:

public class ReceivedApiObject
{
  // when the API responds with null value types the class can be instantiated 
  // and its members called without having to catch NullValueExceptions
    public string? UnitCode { get; set; }
    public int? Value { get; set; }
    public override string ToString()
    {
      // check for null and use a temporary value type to store an appropriate value
      string tempUnitCode = string.IsNullOrWhiteSpace(UnitCode) ? ":null" : UnitCode;
      // same for the Value property
      string? itemValue = Value == null ? "null" : Value.ToString();
      // trim the temp value without mutating the source property
      string fixedUnitCode = tempUnitCode.Substring(tempUnitCode.IndexOf(':') + 1);
      // return values despite possible null Properties
      return $"{itemValue} {fixedUnitCode}";
    }
  }
}
public class AnotherApiObjectThatReturnsAnDouble
{
  public string? UnitCode { get; set; }
  public double? Value { get; set; }
  public override string ToString()
  {
    // Similar idea here as to the previous example
    string tempUnitCode = string.IsNullOrWhiteSpace(UnitCode) ? ":null" : UnitCode;
    // again, avoid mutating the Properties
    string? itemValue = Value == null ? "null" : Value.ToString();
    string fixedUnitCode = UnitCode.Substring(UnitCode.IndexOf(':') + 1);
    // return the replacement value as soon as possible
    if (itemValue != null && itemValue.IndexOf('.') < 0)
    {
        return $"{itemValue} {fixedUnitCode}";
    }
    // in this case I only want no more than 2 hundredths decimal places
    string trimmedValue = itemValue!.Substring(startIndex: 0, length:itemValue.IndexOf('.') + 3);
    return $"{trimmedValue} {fixedUnitCode}";
  }
}

When these code blocks run, and either UnitCode or Value are null, they are replaced with a printable string value that should be safe for the calling method to use. The actual returned values also provide evidence of null-returns without having to catch an Exception.

Thursday 23-Nov-2023

Completed "Get Started with C#" learning path hosted by Microsoft Learn. Also passed the FreeCodeCamp Foundational C# with Microsoft Certification Exam with a score of 90% in 40 minutes. There was at least one question that was not covered in the course content, and three other questions that were not phrased well and/or the "best answer" didn't appear to be syntactically correct. Glad I did it, and will continue to look for other opportunities like that one.

Back to work on the MAUI Weather App. I discovered my REST call Headers were not quite right, so I was getting JSON back that was more difficult to work with than I had hoped. All of my models needed to be updated so that the parsing mechanism can capture the data properly. Next step is to rework the Page ViewModels to correctly use the model data, and go from there.

Thursday 16-Nov-2023

I've been watching .NET Conf 2023 videos and working through more MS Learn Modules focused on C#.

Today's most interesting .NET Conf session was on .NET Community Toolkits. These toolkits could be useful for my mobile weather app and the future file sync tool v1 projects.

Open source collaboration is welcome:

Monday 13-Nov-2023

In between other tasks I worked through Copilot Adventures to gain more experience with GH Copilot and learn a few things. I still need to get Copilot to write tests for me (my last attempt resulted in a non-functional test project in VS Code) but I'll work around that in Visual Studio and try again. Key lessons:

An example of the last point: Printing emoji to a Console window requires a little know-how and some visual padding.

// this icon will take up a certain amount of character space
public static string DragonIcon => "🐉 ";

// this icons takes up a certain amount of character space
public static string AlphaCharacter => "a ";

// net result of printing 3 of each:
🐉 🐉 🐉
a a a

// the Console class must be configured to display UTF8 or other non-standard encoded characters
Cosnole.OutputEncoding = System.Text.Encoding.UTF8; // for the dragon icon above

// then the spacing must be fixed for the output to line up in an expected way
public static string AlphaCharacter => " a ";

// net result of printing 3 of each:
🐉 🐉 🐉
 a  a  a

// note: the MD rendering environment does not do the demonstration any justice.

Tomorrow through Thursday is .NET Conf 2023! I'm looking forward to seeing what .NET 8 and the latest release of C# have to offer.

Wednesday 8-Nov-2023

Completed a few code challenges provided by MSFT Reactor - CoPilot Adventures. The purpose is to exercise using GitHub CoPilot and learn some of its commands and capabilities. For example:

Tuesday 7-Nov-2023

Completed a code challenge developing a custom Stack. I wasn't able to write any code after designing and analyzing a solution so that is a failure. However, it's been some time since I've challenged myself in this way. A few hours later I wrote the code solution using TDD and within about an hour had a working library with unittests.

Saturday 4-Nov-2023

Accessing the filesystem can be tricky. There are things to remember:

// this function creates a new file and adds data to it while respecting the Dispose() pattern
private void CreateFile(string filename, byte[] utf8buffer)
{
  using (System.File.IO.FileStream fs = File.Create(filename))
  {
    fs.Write(utf8buffer, 0, utf8buffer.length);
  }
}

// this function creates a new file and closes so another process can access the file
private void CreateFile(string filename)
{
  System.IO.File.Create(filename).Close();
}

Friday 3-Nov-2023

Finished up some initial "V1" planning for the sync tool. There are some challenges to overcome, but nothing a little planning ahead and maybe some additional design drawings and test-driven development can't help out with. Some takeaways:

Indexing with a string instead of an integer:

public class MyWrapperClassCollection : IList<MyWrapperClass>
{
  private IList<MyWrapperClass> _myWrapperClasses
  public MyWrapperClass this[string name]
  {
      get
      {
          foreach (MyWrapperClass item in _myWrapperClasses)
          {
              // MyWrapperClass has a Name method that returns a unique string for an instance
              if (item.Name == name)
              {
                  return item;
              }
          }
          // This is where the caller needs to have an exception handler.
          throw new KeyNotFoundException($"{name} not found in collection");
      }
  }
}

Implementing IDispose() pattern on a wrapper class:

public class MyWrapperClass : IDisposable
{
  private SomeClass _someClass; // SomeClass implements IDisposable
  public void Dispose()
  {
      Stop();
      Path = string.Empty;
      Filter = string.Empty;
      ((IDisposable)_someClass).Dispose();
  }
}

Implementing Equals() override method:

public override bool Equals(object? obj)
{
  if (obj == null)
  {
    return false;
  }
  // use a cast to enable comparing instance properties
  MyWrapperClass other = (MyWrapperClass)obj;
  if (this == other)
  {
    // the items are the same
    return true;
  }
  if (this.Name == other.Name && this.Size == other.Size)
  {
    return true;
  }
  return false;
}

Alternatively, it could be necessary to include a test comparing references between this and obj other:

// method bool accepts two parameters (object a, object b) and cannot be overridden
Object.ReferenceEquals(a, b);

// NOTE: 'interned' reference types will not evaluate properly, nor will boxed value types.

Anyway, I have completed building a small Library that can serve as a model for the future sync tool, that includes disposal, collections with enumerators, equality checks, and unit tests. This work should put me on a good path toward a well-built synchronization tool.

Thursday 2-Nov-2023

Recorded videos of the setup and usage of the sync tool, demonstrating the expected straight-line workflow. After several run-throughs of the presentation deck and recoding these videos, I updated the README file because I realized it was not very concise in a few spots, and actually needed some minor corrections to be helpful.

It turned out to be a blessing that I recorded videos of what I had planned to demo, because my webcam wouldn't record video of two PCs with any clarity (just a cheap web cam), and my main computer was not allowing installation of Winlink Express to run Zoom and the demo there, instead.

The attendees were understanding, and the slide-deck presentation and demonstration went well, along with a little Q and A before 45 minutes was up. We went long with additional Q and A and basically agreed to go forward with the project! :tada: :tada: :tada:

Tuesday 31-Oct-2023

I spent half of yesterday handling administrative tasks that needed attention, and stuff around the house too. As for coding, some key takeaways:

Some better practices to use next time I have to work with deserializing JSON:

  1. Start by setting up Unit Tests and importing the expected JSON from a file. This will add clarity of what is going on, while speeding development.
  2. Look at the Root of the JSON object and just define a few simple items, run the test, resolve bugs.
  3. Repeat step 2 for the remaining necessary Root-bound element.
  4. Add child elements that don't have children, debugging along the way like in step 2.
  5. Create custom objects as needed.
  6. Move to the first grandchild element and repeat steps starting with 2, continuing until all necessary elements are deserialized successfully and there are no crashes or issues.
  7. Implement what was designed in the Unit Test(s) in the real code.

Saturday 28-Oct-2023

Working through the MAUI Weather App again. There was a bug that kept crashing the app, and it was inconsistent. Here are my key takeaways:

As it stands right now, the MAUI Wx App is moving forward, albeit a little slower than I had hoped.

I received email back from key (to bo) stakeholders of another project I'm working on. At least 1 is interested in a demo. In the next few days I will walk through my demonstration using actual PCs to verify the demo script is good, and then try to record it for posterity. Perhaps next week a live demo will be done with some of the to be stakeholders.

Friday 27-Oct-2023

Working with MAUI the last few days I have learned a bunch, after riding a roller-coaster of "this is easy and cool" to "does this really work?" to "what was I thinking?!?".

Key takeaways:

The Mobile Weather app is now in a much better place than it was at any time over the last 2 days. :smiley:

Tuesday 24-Oct-2023

The last week has been very busy will getting ready for training sessions I am running over the next 4 weeks. Last weekend was the first one and it went well. Feedback during this first 'basics' class led to some changes in the presentation content and order, so the next group that gets that presentation will reap the rewards. The 'intermediate' class won't be until November, but I have a bit of work to do:

I also want to send out PDF'd certificates of accomplishment to everyone that participates, so I need to complete filling and sending these out for the basics class, and start getting them ready for the intermediate one.

In case that's not enough, I need to exercise my newly acquired .NET MAUI knowledge, so my plan is to start developing a small mobile Weather App. Whiteboard planning is just about done already. UI wireframing, the request/response cycle, and data handling all need to be designed and debugged before I can start coding.

Investigating the NOAA Weather API has been easy. Last year I tried this and it didn't make much sense to me but today, it is simple. My experiences building and utilizing APIs is paying off. There is even a Swagger-UI-like interface for the API. It isn't as well documented as I would like, but the data schema and examples are there, along with expected Result bodies and codes. The part of the documentation that is challenging is the NOAA syntax for zones, areas, and etc. I suppose that will become apparent after additional research.

The harder part will be sorting out what data is worth caching and ready for display, and what can be skipped over. For example, if the App displays the current conditions, and the user then wants to see the forecast for the week, that data should already be available either through an advanced query or the cache already has that info from a previous call (before the cache expiration). This will take a little more work on my part to figure out. If I keep focused on the simple answer, I'll find the right solution to implement, and will go forward from there.

Tuesday 17-Oct-2023

Lots of project planning, emailing, and organizing going on the last few days. There are some good things coming up across the next few weeks including project presentations, and a few training session I will be leading. Lots more work to do (not enough coding but that will come soon enough).

Friday 13-Oct-2023

Started working on initial plan for a MAUI mobile app for Windows + Android. The goal is to make an app that can be published to Google Play Store. Expected completion is by end of 2023. There are several other projects I am currently working on that will slow initial progress of this project, but as November wraps up I expect to be able to dedicate more time through December. I'm excited! :grinning:

Thursday 12-Oct-2023

MSFT Learn took me down a strange trip as I worked through the Create Web Apps and Services with ASP.NET Core path. The learning tools they presented included React, Vite, and MaterialUI, as well as GitHub CodeSpaces. Nothing wrong with any of that, it was just unexpected given the context was ASP.NET - I would have guessed they would have done a Blazor or Minimal API framework for the training, instead.

At any rate, it was good to do that since I hadn't done much with React recently, and have not previously been exposed to Vite or MaterialUI, and had yet to take advantage of GitHub CodeSpaces. All good!

A lot of good information was contained in that module, including Front-End Development Concerns, Selecting a Design System, and SPA Frameworks.

In C#, Casting to a specific type truncates rather than rounds the value up or down:

int numerator = 5;
int denominator = 2;
int total = (int)numerator / denominator;
// total will be 2

Wednesday 11-Oct-2023

Working through more training modules. Key takeaways:

Tuesday 10-Oct-2023

Continuing MAUI training, nearly done!

Key Takeaways:

I completed the learning path and acheived the trophy "Build mobile and desktop apps with .NET MAUI"! This adds to my collection of Achievements from a couple years ago:

The Azure DevOps Learning Path was only a single module? Maybe they've been updating modules and that one was legacy. Whatever, moving on.

Monday 9-Oct-2023

The weekend was busy, mostly with other tasks and committments. I'm back on the MAUI training path again.

After completing several .NET MAUI modules, I'm learning my code style usually over-codes, and under-utilizes built-in framework capabilities for things like making REST calls to an API. A few of the concepts are relatively new like Connectivity.Current.NetworkAccess and the NetworkAccess enumeration, other Classes and Properties of System.Net.Http are not new, and I have failed to make the best use of them.

Key takeaways (so far):

Friday 6-Oct-2023

While working through more MAUI modules, a wonderful discovery is the DynamicResource Type, and the ability to edit K-V pairs in it at Run Time. Just use C# code to index into the dynamic resource collection and set each KVP accordingly, then update the XAML to use "{DynamicResource DynResName}" for the references that need a dynamically set value!

<!-- portions of this code are from MSFT Learn MAUI Modules -->
<ContentPage ...>
    <ContentPage.Resources>
        <Color x:Key="fgColor">#0000AD</Color>
    </ContentPage.Resources>
  <Grid ...>
    <Label TextColor="{DynamicResource fgColor}" FontSize="{StaticResource fontSize}">My Label</Label>
    <!-- more XAML Controls here -->
  </Grid>
</ContentPage>

...and...

public partial Class MyAppClass
{
  // CTOR etc here

  // handler for the Light button
  void OnLight(object sender, EventArgs e)
  {
      Resources["fgColor"] = colorNavy;
      Resources["bgColor"] = colorSilver;
  }

  // handler for the Dark button
  void OnDark(object sender, EventArgs e)
  {
      Resources["fgColor"] = colorSilver;
      Resources["bgColor"] = colorNavy;
  }
}

Thursday 5-Oct-2023

Completed more MAUI modules, creating Apps for Windows and Android. There is a bunch of borrowed syntax from WPF XAML that converting most of my development experience to MAUI should be fairly straightforward. There are a few changes in some of the syntax due to the extra layer MAUI adds over all 4 supported platforms, but those changes (so far) aren't too difficult to understand. Thinking ahead, even if the Bib Sync Tool doesn't get ported to MAUI (right away or ever), I have at least two backlogged mobile/Android projects I want to work on someday, and MAUI might be a good path to getting those want-to-dos done.

Wednesday 4-Oct-2023

Completed MAUI modules, creating Apps for Windows and Android. Documented learnings in a new conted file. Most of the MSFT Learn module notes are moved to this new file from the 'mobile-to-desktop' one referenced yesterday.

Tuesday 3-Oct-2023

Catching up from yesterday:

Monday 2-Oct-2023

Completed implementing hover actions over custom 'pill' shaped and round buttons used in the file sync project. In the time it took me to sort all of this out, I could have written 3 full websites with React and CSS (maybe 4 using Bootstrap :wink:). The reasons are:

  1. I've not done this much WPF customization before.
  2. It seems like XAML requires replacing events and triggers when custom animations are used to transition colors and other properties.
  3. If making simple event changes to states like 'IsHover' the process is much easier but seems to be limited i.e. cannot animate the transition.

For now, I think I have the basic gist of how XAML UI customization is done, but it will be some time before I know what I am doing. In the meantime, the project is practically at MVP!

Next steps:

  1. Script the most basic use case for demoing usage on a single computer.
  2. Script the use case of a set of computers on a LAN or local WiFi, all pointing to the same server.
  3. Record the use cases videos with walk-and-talk-through audio to use as stand-alone demo products.
  4. Develop very short, silent video demos that could work as animated JPGs.

One additional thing I am proud of in this project is implementing accessibility features. ToolTips were added to buttons and textboxes, and a color palette that maintains high contrast for users with any of the 3 types of color-blindness that 1-in-10 adults experience to some degree. These often overlooked design considerations are not difficult to implement when using resources to help implement them, and enables additional users to utilize the software.

Sunday 1-Oct-2023

After much consternation, I have a pill-shaped button with custom colors and responsive design that changes the button design between normal, hovered, and clicked. I still need to settle on color scheme and also add the disabled state design. At least now the basic template for how state changes are achieved is worked out.

An interesting and helpful Style property, BasedOn, allows application of merged Style resources to a target type. For example:

<Style x:Key="DefaultPillStyling"
       TargetType="{x:Type Button}">
  <Setter Property="..." Value="..." /> <!-- etc -->
</Style>
<Style x:Key="ButtonPillStyle"
       TargetType="Button"
       BasedOn="{StaticResource DefaultPillStyling}">
  <Setter Property="..." Value="..." /> <!-- etc -->
</Style>

The applies Style settings from both configurations, allowing some buttons to apply just the DefaultPillStyling, and others to apply that and more.

Monday 18-Sept-2023

Lots of studying and working with XAML templating. Blend helps out a bit in getting lots of configuration set on Controls, and even has a state management toolbar. Some takeaways:

Sunday 17-Sept-2023

Many of the items learned yesterday were implemented today in the File Sync Tool. The tool is getting close to ready, but a few tasks still need to be completed:

Some other takeaways using Caliburn.Micro and customizing buttons:

Saturday 16-Sept-2023

And I though CSS was challenging. Customizing screen elements and applying style to WPF Apps using XAML is a bit of a bear. Somem key takeaways:

This work will continue into Sunday.

Friday 15-Sept-2023

Working with .NET and C# the last few days, specifically my Coordinate Conversion Utility, I learned a few things:

Wednesday 13-Sept-2023

I've been reading up on a bunch of different topics, but the only one worth mentioning here is the Liskov Substitution Principle. Tim Corey of "IAmTimCorey" fame states "this is the L in SOLID". At a very high level, the principle states that substituting inherited types should not break the application. For example, inheritors should not make changes to an inherited class when using polymorphism. The way Tim Corey explains how to work around it is to extract Interfaces from the most parent class, and create an abstract base class that implements that interface, from which other classes can inherit. Those inheritors should then have Interfaces that describe the differing behavior (from the Base Class) to more strongly define their specific sub-types -- the "extra stuff". Also, functionality should require Interface Types (rather than concrete types) to ensure only those types that should use that functionality actually can. Doing all of this just ensures that all child classes are indeed "IS A" base class. A nice benefit of following the Liskov Substitution Principle carefully is the Compiler will catch coding errors at compile time, rather than runtime (harder to debug).

Key takeaways:

Ask Yourself:

In terms of derived types:

See Covariance and contravariance in generics at Microsoft Learn.

Related vocabulary:

Thursday 7-Sept-2023

The final big tests of the sync tool were yesterday and today, and after a good deal of troubleshooting and researching, the tool is now able to transfer data across a WiFi network between computers without errors. My lack of familiarity with the HTTP-based modules, especially Dot NET 6 and ASP.NET Core, made for a big challenge. The basic setup is a client computer wants to POST some data to another computer on the network, on a specific port. Besides the obvious requirement of "the server must be listening", there are several other requirements.

Here is a list of takeaways from ASP.NET and POSTing REST calls across a network:

Example Code Drilling into an InnerException:

public async Task<Tuple<bool, string>> PostStuff(MyModel model) {
  // some code...
  try
  {
    using (HttpResponseMessage response = await _apiHelper.ApiClient.PostAsync(requestUri, httpContent))
    {
      if (response.IsSuccessStatusCode)
      {
        result = true;
        message = "Succeeded.";
      }
    }
  }
  catch (ArgumentNullException ArgNullEx)
  {
    message = $"Argument Null Exception Stacktrace: {ArgNullEx.StackTrace} Message: {ArgNullEx.Message}";
    if (ArgNullEx.InnerException != null)
    {
      // tack-on any child message.
      message += $"\nInner Exception Message: {ArgNullEx.InnerException.Message}";
    }
  }
  // other Exception catch blocks here...
  return result;
}

Example Host Firewall Allowances:

Name,Group,Profile,Enabled,Action,Program,LocalAddr,RemoteAddr,Proto,LocalPort,RemotePort
filesyncapi.exe,public,yes,allow,{filepath},Any,Any,TCP,Any,Any
filesyncapi.exe,public,yes,allow,{filepath},Any,Any,UDP,Any,Any

Wednesday 6-Sept-2023

Attended a MSFT Reactor session on .NET MAUI Handlers and Native Controls. After looking at the MAUI repo and Microsoft Learn pages about MAUI, it is still in its infancy, but there is a lot of activity and documentation supporting development. One key drawback on developing MAUI apps is developing iOS native requires 'a networked Mac' (presumedly to run Mac Catalyst). I've missed some sessions in the series so I intend to catch up on those.

I tested using the Client-side sync tool while a live Winlink Express app was creating and receiving messages. The file accessing operations don't seem to interfere with each other. This was an important test and a good win! :boom:

Tuesday 5-Sept-2023

"When coding becomes difficult, it might be because the coder isn't following best practices." -Me

I've found several areas where I wasn't following good coding practice, and the code was becoming tough to read and too complex. After some refactoring, moving classes around and simplifying various methods by breaking them out into multiple functions, it became easier to read, edit, debug, and add-on to.

Monday 4-Sept-2023

Ran a few experiments with AREDN Mesh over the weekend into today:

I was beginning to believe Caliburn.Micro may never get updated to support Dot NET MAUI, then I ran into Ken Tucker's Blog. He includes instructions on how to setup Caliburn.Micro and use it in your MAUI workload. :smiley: Ken also has a repo named ClientNoSqlDB that might be interesting for my current synchronizing project, so I'll take a peek at that soon.

Friday 1-Sept-2023

Was tough to get a working solution to implementing a structured logging interface like Serilog. Code-wise it is fairly simple, but dependency-wise there are issues. Also, there are upgrade-related issues in Caliburn.Micro that a project upgrade to NET 6 will bring about. So for now I'm stuck with Dot NET 4 WPF project, unless I move away from Caliburn.Micro, or wait for v5.0.0 to be released (which there is no published date, just a 12-word roadmap).

Key takeaways:

The project is at a point where the primary features are working in a development environment. The next planned steps, roughly in order:

  1. Test the app in DEBUG mode outside of Visual Studio.
  2. Publish a Release version of the app for testing on multiple computers.
  3. Run the app, monitoring a Winlink Express folder structure, to verify timings and file handling will work properly (I should have done this a LONG time ago because I don't necessarily know how Winlink Express manages its file handles other than where the message files are stored).
  4. Clean-up the code and add xml comments to custom methods.
  5. Clean-up the UI and apply a theme that meets some (or all) Accessibility standards. Longer term I will apply specifications from W3C and A11y.

By the end of the day the Desktop and the Web Service are functioning as expected and are stable. I took a look at notes I'd been taking on paper and realized there is a lot more yet to do just to get to MVP. However, some sorting through all of these items has allowed my to prioritize them, and decide what really needs to be done, versus what can wait (or not be done at all if the end users don't need it). So I set up a Trello board to track everything so I can stay on top of it. There are plenty more ideas for this project, so a backlog column was added to capture my ideas, as well as those from end users, once they are engaged as I close-in on MVP.

Thursday 31-Aug-2023

Microsoft's WPF has an interesting feature: DispatcherUnhandledException class. Basically, in the startup App class 'App.xaml', an event handler can be bound to any raised DispatcherUnhandledException Type. The event handler (in code-behind file 'App.xaml.cs') is like any other handler in Dot NET: private void OnDispatcherUnhandledException(caller object, DispatcherUnahndledExceptionEventArgs e) {...} where error handling implementation is expected. After reviewing Application.DispatcherUnchandledExceptionEvent documentation, it is clear there are some requirements:

  1. The xaml parent class must inherit from the Application class.
  2. The handler must be written as described above.
  3. The original Exception must have occurred on the main UI Thread (Application-inheriting instance).

For Exception-type events that occur on threads with their own Dispatcher (or no Dispatcher at all):

  1. Handle the event locally, such as with a Try-Catch-Finally block.
  2. Dispatch the event to the main UI thread.
  3. Rethrow events on the main UI thread w/o handling them.

Caliburn.Micro has a virtual method OnUnhandledException(object, DispatcherUnhandledExceptionEventArgs) that can be overridden and used to call a custom handler. One way to handle this is to show a MessageBox with information for the user (if that makes sense to do). Another would be to log the event somewhere (especially if the user couldn't do anything about it anyway).

Wednesday 30-Aug-2023

While looking up best practices converting custom types, I ran into this ASP.NET Core Best Practices for DotNET 7. There are several items in the list that could apply to my current pet project, once it is out of MVP and growing.

Completed bug squashing and updating the README for the current version of the sync tool. One thing occurred to me: I'd forgotten how to build and deploy apps from Visual Studio.

Key takeaways:

Check out ASP.NET Core 6.0 Fundamentals for more details on Publishing an ASP.NET project.

My custom logging is a little messy, and probably too verbose. While it is true the logging can be turned on or off, the way I am going about it is not how it is done using Dot NET assemblies. So I took a look at Microsoft.Extensions.Configuration, Microsoft.Extensions.DependencyInjection (for review), Microsoft.Extensions.Hosting, and Serilog. Next step is to try and refactor the logging within the Projects so I have better control over what is logged and when. For example, while debugging and developing, lots of logging can be a good thing. However, a released product should avoid producing a ton of logs (be default).

Tuesday 29-Aug-2023

Back to work on the file sync tool:

As it stands now, the application is able to successfully:

The feature set is nearly complete, so the project is well on its way to MVP. The following work must still be completed:

Monday 28-Aug-2023

Completed a 2-node network at home using the following equipment:

For now all devices but the VLAN Switch are powered by 120v PoE injection. These will eventually by powered by a battery instead, via a buck-boost device, or a small inverter. A second 'site' will require its own power source(s), and as I get closer to goal #3, this will get addressed.

Back to coding!

Some key takeaways:

Weekend of Aug 27th and 28th

On Saturday I attended an AREDN Mesh workshop and learned how to load AREDN firmware into some cheap 2 GHz and 5 GHz routers and APs (AREDN stands for Amateur Radio Emergency Data Network, and is a non-profit organization of volunteer software developers). It has been a bit since I last had to do any serious networking, and I managed to get firmware loaded on two of the devices - a TPLink CPE-210 and a MikroTik hAP Lite. I had purchased three devices including a GL-iNet AR300M for use with AREDN, but have since decided that hte GL-AR300M is better utilized as an access-point/repeater with built-in firewall for use in hotels, coffee shops. It could be used as an AP for a local WiFi LAN for AREDN too, but many of the AREDN devices are setup as 2 GHz 'mesh' radios with 5 GHz 'WiFi' (LAN) radios, so the AR300 is banded for the MESH, rather than the end-device network.

My Goals Working With AREDN:

  1. Short-term: Learn about AREDN and become familiar with common setups and usages, including how to implement DHPC, DNS, Port Forwarding, and Tunneling as appropriate.
  2. Mid-term: Learn how to leverage it for services like chat, Winlink Express, and perhaps file sharing.
  3. Longer-term: Develop a set of steps to deploy a 2-site private mesh, where strike teams of 4 or fewer WiFi users at two sites (perhaps five or more miles apart) can relay messages more rapidly than usual ham RF links such as 1200/9600 baud packet on VHF/UHF. This will require some experimentation, and possibly so additional hardware purchases.

Tuesday 22-Aug-2023

What I learned today: When I start loading a class constructor with lots of logic...

public class DataProcessor {
  private SomeHelperClass someHelperClass = new SomeHelperClass();

  public DataProcessor(string[] someComplexData) {
    _logger = new Logger();
    foreach(var dataItem in someComplexData) {
      do {
        // process the data here
      }
    }
  }
}

...what I should really do is refactor the solution to include a helper class that will do the heavy lifting and employ Inversion of Control (IoC or Dependency Injection) so the class is always ready, either as a Singleton or as a Dynamically instantiated dependency:

using Caliburn.Micro; // for example
// more usings...
namespace MyNamespace {
  public class Bootstrapper : BootstrapperBase {
    private SimpleContainer _conatainer = new SimpleContainer();
    public Bootstrapper() {
      Initialize();
    }
    protected override void Configure() {
      _container.Instance(_container);
      _conatiner
        // various .Singleton<>() entries...
        .Singleton<IDataProcessorHelper, DataProcessorHelper>();
      // foreach to find ViewModels using Reflection, for example
    }
    // other Caliburn.Micro DI-related methods here
  }
}
public class DataProcessor {
  private IDataProcessorHelper _dataProcessorHelper;
  public DataProcessor(IDataProcessorHelper dataProcessorHelper) {
    _dataProcessorHelper = dataProcessorHelper;
  }
  public bool ProcessData(stringp[ someComplexData]) {
    do {
      // process the data here using _dataProcessorHelper methods
    }
  }
}

It is safer and cleaner to stictly initialize an object instance within a CTOR, and not introduce lots of processing. What if something goes wrong? Try-Catch won't help you within a Constructor (the instance won't get initialized properly). With DI, all requirements to instantiate an object are handled ahead of time, so the instance is ready to respond to Method calls.

See more at the Caliburn Micro home page.

Monday 21-Aug-2023

Revamped the Project layout in the file-sync-win Solution so that it is better arranged for building future features and will be easier to test and debug.

Completed a few exercises on using MVVM in WPF. Seems like Caliburn.Micro is a great way to go so I'll give that a spin. I'll want to reorganize the files (some more) to support Inversion of Control (Dependency Injection), but after some research it might make more sense to get Caliburn.Micro installed and functional first, then take on DI if it will still be helpful.

After some work refactoring and adding Caliburn.Micro, I have the main UI functioning again. Takeaways:

Sunday 20-Aug-2023

Struggled a bit with getting starting features up and running with this WPF app. Some notes:

However, I was able to implement some good practices without too much heartache:

TODO Items:

Saturday 19-Aug-2023

Completed a first-pass of a client-server solution that copies specific file data from a client (or at the server) into a MongoDB document store. The idea is to help solve the problem of copying 'bib data' from multiple Winlink Express workstations to a central "database server" workstation without having to manually sneaker-net or Telnet the files to the "server" computer. This exercise proved-out some design possibilities, some problems with my initial approach, and will help drive a better overall design for a possible future solution.

Began working on a possible WPF based solution for this file synchronizing utility. It is nice working with C# again, but I don't miss XAML. Why can't I just use CSS? :laughing:

Friday 18-Aug-2023

It's been a super busy week, followed by a couple days of travel mixed with some relaxation. Now it's back to work time.

Some Key Takeaways for the day:

Monday 7-Aug-2023

Attended a MSFT DotNET MAUI presentation: Databinding in MVVM. I've been away from C# for some time but recall working within an MVVM model to develop WPF applications. For DotNET MAUI it isn't too different, and there is now a toolkit developed by Microsoft to help implement the MVVM model. This was an informative introduction, and I look forward to working on a DotNET MAUI project in the future.

Thursday 3-Aug-2023

I have a new project idea, related to the Bigfoot Bib Report Form project, that will require some research and time to design. At the moment I believe Socket.IO to be a good candidate as the underlying infrastructure for the project:

Experimented with Watcher to utilize as a means to watch a file system for a specific file type. Once a file change is discovered, a separate module can be called to parse the file to capture the necessary data. This was a very early experiment, but there are a few takeaways:

These changes will take a bit of time to sink in to my grey matter.

Monday 24-July-2023

Attended a MSFT Reactor session about DotNET MAUI. Key takeaways:

Recall NextJS Project setup steps:

npx create-next-app@latest myProjectName --use-npm
set-location -Path myProjectName

Saturday 22-July-2023

Not much to write about due to other tasks interspersed with working on the BF Winlink Form, and planning around some of my personal goals for the next few months.

Friday 21-July-2023

Finished implementing the mock server basic functionality of:

Thursday 20-July-2023

Fiddled with my mock WLE server code trying to get it to read a specific file, edit a specific string within the file, and sending the entire file with changes back to the requesting client.

Key Takeaways:

Wednesday 19-July-2023

I've started writing custom scripts for Package.json in node-based projects. In today's case, I had to re-write a small section of an HTML file prior to the web-server loading it as a static page.

Key takeaways:

Tuesday 18-July-2023

I came up with an idea as to how to address the issue request 'copy most recent supplied entry' for the Bigfoot WL Form project. At first I thought I could get away with just using Local Storage and saving the data to a file, but I didn't quite implement it correctly. So I took another tact, trying to implement a forced save during Form Submit event, but I failed to block the default form action so the data would get lost instead of stored. I then realized that Local Storage will do the trick, however I need to block the default form action before setting the "last record" values into LS, then the form can close. The challenge will be setting the form items correctly into the multi-part form transfer that the Winlink Express 'server' will require. That's my goal for tomorrow.

Key takeaways:

Monday 17-July-2023

Completed the rest of the JS challenge started yesterday. Miro was still being sluggish but I completed the challenge anyway. Take aways:

Finished up research and writing about Mocha, Jest, and Chai. Key takeaways:

Made some progress working through a new Issue raised by a Bigfoot ham: Allow storing and incrementing the Message Number.

Sunday 16-July-2023

Worked through several JS challenges in CodeWars and completed one in the style of a whiteboard interview: URL Spaces.

I reserached several companies with interesting open positions, none of them were in industries (or locations) that were exciting to me.

Thursday 13-July-2023

Worked through Jest.JS documentation and took notes for future reference.

Wednesday 12-July-2023

I've been slowly working through Next.js getting started documentation. Some takeaways so far (what I think I'm learning):

Tuesday 11-July-2023

Sorted through a bunch of in-progress projects and those that are on the back-burner. I didn't remove any, but did some re-prioritization, and added a couple new ones. Then, while looking up how to package and publish code, I ran into Next.js documentation, which is something I'd wanted to look at for a while so I started a new project to learn how to use it. I'll get back to the build, bundle, package, and publish exercise later (if anything, this Next.js documentation has been helping understand the processes involved).

I also worked on some documentation for the Bigfoot Winlink form. I'll need to review the Readme and update instructions now that the form is in a good state. Mostly importantly, the instructions on how to share files between Windows and Android devices needs to be added. Some of that documentation took some time to look up and validate, but it will be really helpful for users.

Monday 10-July-2023

Updated my Portfolio WebApp with the Bigfoot Form project at version 1.0.6. There are some issues I need to resolve with the Portfolio WebApp when I get a chance:

One of my backlog items is to learn how to build, bundle, package, and publish a project. For this exercise I will use React as a starting point.

Sunday 9-July-2023

Continued working with Chai and learning how to integrated it into the JS-code-challenges repo and test the code challenge from yesterday. Some key takeaways:

On the Bigfoot Form front, enough time has passed since advertising changes without hearing of any problems that I went ahead and closed issues and merged-in fixes and enhancements. The first volunteer meeting is coming up on Monday, where I anticipate having a moment to talk about the form, how it is working, and provide general guidance on using Winlink for Bigfoot.

Saturday 8-July-2023

I completed a code challenge that required parsing through a string of alphanumerics and spaces. The idea was to reverse the case of the alpha characters such that Upper Case letters would become Lower Case, and vice versa. Non-alpha characters would not be affected. One rule was to keep the function pure, and to develop it as a prototype (in JavaScript) e.g. String.prototype.toAlternateCase(). Takeaways:

  1. Just because String.split(""); is effective does not mean it is the right way to go. This will force the code to process string items in an array regardless if they are alpha or not.
  2. Using a regex like String.match(/\d|\W/g) can be effective but it is not always necessary if it is a 'default case'.
  3. Using String.replace() would not work because that would mutate the input.
  4. Use String.at() to iterate through the characters of a string without having to deal with an array.
  5. Simply detecting if the String.at(idx) character is uppercase or lowercase is all that is necessary for Strings.
  6. Applying String.toUpperCase() (or lower) is an 'all are welcome' operation and will not fail if the character is not alpha.

Testing with Chai:

Thursday 6-July-2023

Here are some key takeaways from reading about Java Stream Collectors:

Overall I am feeling a bit more comfortable with Java Streams API. I will need to practice more to get a better feel for the syntax and how to use it effectively.

I've been reviewing the Chai Assertion Library the last few days:

In a future JS project I will try using Chai for assertions.

Wednesday 5-July-2023

Completed a code challenge in Java. Two things I'd forgotten about:

  1. Java Primitive Types cannot be assigned a null value. Jumping around from Java to JS to C# and back has probably contributed to this confusion.
  2. Array types in Java can be null. I actually remembered this but didn't think about it while designing the algorithm for a two-dimension Array. In multi-dimensional Arrays, the parent Array contains Arrays as items, so a null value represents a row that has no items.

Tuesday 4-July-2023

Did some self-study of JavaScript frameworks. Notes are linked from the Conted Index page.

Monday 3-July-2023

Cleaned up documentation references in this repo - there were a few floating documents with no links to them so they were difficult to find.

Updated Azure-Deploy YAML in LingoBingo API server repository (only on the azure-deploy branch). My notes on GitHub Actions: Build and Test Node.js App has details.

My Portfolio React SPA has several dependencies that have moderate vulnerabilities and/or are no longer supported (deprecated). I've removed a few of the dependencies that weren't needed, updated others to the latest version, and set a plan to replace the Vertical Timeline component sometime in the future.

Sunday 2-July-2023

Updated my Create-Markdown-TOC VSCode extension to version 0.2.1 with bug fixes and an enhancement (based on the bug fix). The Visual Studio Marketplace page has some metrics on downloads and page views that might be worth watching as I continue to develop the extension. The automatic update was seamless and I verified functionality on a few files locally.

Takeaways:

Thursday 29-June-2023

Learned something about CSS, by accident, while looking at a fun project at github.com/jdan/98.css:

/* just showing some styling possibilities */
hr {
  height: 0.5rem;
  width: 90%;
  text-decoration: none;
  border-top: 1px dashed rgb(0, 0, 0);
  border-bottom: 2px solid rgb(255, 0, 0);
  border-left: none;
  border-right: none;
}

Wednesday 28-June-2023

Last night I finished implementing some fixes to my create-markdown-toc VS Code Extension. The bug was related to how the extension handled unsupported characters in link fragments. The result of the bug was a linter warning that (in most cases) would be easy to fix by hand. Since the extension creates the entries that should be legitimate but aren't, it's a bug. The solution uses string.replaceAll(/regex/) to find a list of unwanted characters from the captured heading's "title text", and replace them with nothing (remove them). The result is a link fragment that is more likely to work as expected. I added unit tests to support the new code and am working on some manual-test scenarios to further test the code before publishing the update to the VS Code Marketplace.

GitHub Copilot has been helpful. I've learned how to prompt it to generate better suggestions. Microsoft Build had a session discussing how to leverage GitHub Copilot, and it turns out I was using some of those techniques already.

Tuesday 27-June-2023

Refined a bug description in project markdown-toc: This markdown file contains L2 headings that include a dash - character in the name. My code generates fragmented links for these headings. An Issue is already in the project and is capturing problem experiences so that I can generate a list of test cases to use when I get to fixing the bug.

I worked through a new code challenge and learned a few things, and then updated code and tests to a previous challenge due to lack of code coverage that I hadn't noticed before:

// fast fail if any zeroes are detected or if size of a row is not equal to 9
if (rowMap.size != 9 || rowMap.has(0)) {
  return false;
}

// later on...
if (thisCol.size < 9) {
  // not as precise as the previous if statement and is never true if the previous is true
  return false;
}

Monday 26-June-2023

Posted an update to LinkedIn about completion of my VS Code extension create-markdown-toc. I added a short description and a few in-action screen shots. As I complete other projects I look forward to doing the same.

Looking at an older team project - EZ-PC-Shopper:

Some code snippets I developed these last few days working on the Winlink Form project:

Media queries to control font size and element size:

@media screen and (width < 650px) {
  label,
  input,
  textarea,
  select,
  button {
    font-size: 0.7em;
  }
  input {
    margin: 0.2em 0.2em;
  }
  input[type='checkbox'] {
    width: 1em;
    height: 1em;
  }
  .formTitleHeader {
    font-size: 2em;
  }
  .msgHeaderTitle {
    font-size: 0.7em;
  }
  .addressInput {
    min-width: 70%;
  }
}

@media screen and (width >= 650px) {
  label,
  input,
  textarea,
  select,
  button {
    font-size: 1em;
  }
  input {
    margin: 0.3em 0.3em;
  }
  input[type='checkbox'] {
    width: 1.2em;
    height: 1.2em;
  }
  .formTitleHeader {
    font-size: 3em;
  }
  .msgHeaderTitle {
    font-size: 1.1em;
  }
  .addressInput {
    max-width: 55%;
  }
}

Centering elements without using flexbox or float:

.div-across-auto-align {
  width: 100%;
  margin: auto;
  text-align: center;
}

Read only text input field decoration:

.readOnlyText {
  color: rgb(84, 84, 84) !important;
  outline: none !important;
  cursor: default !important;
  opacity: unset !important;
}

Items that are hovered over change the cursor, opacity, and border style for visual feedback:

input {
  padding: 0.2em 0.2em;
  border-radius: 0.5rem;
}
textarea,
select {
  padding: 0.3em 0.3em;
  border: rgb(0, 0, 0) solid 0.15em;
  border-radius: 0.5rem;
}
input:hover,
textarea:hover,
select:hover {
  cursor: pointer;
  opacity: 0.8;
}

An active element (clicked or tabbed-in to) border style changes for visual feedback:

input {
  padding: 0.2em 0.2em;
  border-radius: 0.5rem;
}
textarea,
select {
  padding: 0.3em 0.3em;
  border: rgb(0, 0, 0) solid 0.15em;
  border-radius: 0.5rem;
}
input:focus,
textarea:focus,
select:focus {
  outline: rgb(255, 153, 0) solid 3px;
}

Simple local storage API usage:

// store Form element values into localStorage
function storeElementValueToLocalStorage() {
  var addressFormatted = document.getElementById('address');
  localStorage.setItem('addressKey', addressFormatted.value);
}
// load values from localStorage and populate elements in a Form
function loadValueFromLocalStorage() {
  const storedAddress = localStorage.getItem('addressKey');
  if (document.getElementById('address').value == '' && storedAddress != '') {
    document.getElementById('address').value = storedAddress;
  }
}

Use of JSON Stringify to store multiple values into a single element value:

// this is useful for storing values destined
// for localStorage or for saving to a file
function captureValuesToHiddenElement() {
  // call this function prior to saving data to a file
  const address = document.getElementById('address').value;
  const Location = document.getElementById('location').value;
  const message = document.getElementById('message').value;
  const formObject = JSON.stringify({
    address,
    location,
    message,
  });
  // when the saveToFile function is called it will save
  // the values stored in hiddenData element to a file
  document.getElementById('hiddenData').value = formObject;
}

There is plenty more work to do with this project, but that will wait until after some of the intended users have a chance to use the latest update and provide some feedback.

Sunday 25-June-2023

Continued efforts with the Winlink Form have paid off. The form now features:

One note about responsive design: I tried to keep all API usages compatible all the way back to Windows 7-era browsers, but have not tested outside of Chrome, Edge, and Firefox, so there is a possibility that Opera, Safari, or phone-based browsers won't see the benefits of these efforts. This is a low-risk situation because Winlink Express requires Windows 7 and newer, and most smart phones support Chrome or Firefox at a reasonable API level. I'm not sure about Opera or Safari, I guess I'll find out one way or another.

Major wins this week:

Bigfoot Bib Tracker Form Functional Diagram

Saturday 24-June-2023

Diagramming software is pretty fun, and very helpful. Looking at the functions listed in the Bigfoot Winlink Form, it is hard to trace the paths and where the paths split, and which functions return anything, or affect the UI in some way. The diagram documented the following key components:

I discovered several things while developing the diagram:

Friday 23-June-2023

Exploring use of FileReader, setting element values, and saving/loading data to/from localStorage.

I have some work to do to figure out how to get that last bullet point solved. Although it seems simple, the challenge is going to be how to solve it on the existing form without undesireable, unanticipated side effects. This could take a few days to solve completely, but I feel like I'm getting close to a solution.

Thursday 22-June-2023

Continued efforts cleaning up the Bigfoot Winlink form:

Working with the Home Sales Tracker Example app, in an attempt to get video and screen shots of it in operation, I ran into some bugs:

Wednesday 21-June-2023

Happy Summer Solstice!

In an effort to add more completed projects to my portfolio, I started working on upgrading Home Sales Tracker App (from 2019 - 2021) from DotNET Framework 4.7 to DotNET 6. Here are some takeaways:

  1. Use Visual Studio 2022, not VSCode (even with the VS Solutions Extension it is more complicated in VSCode).
  2. Ensure dependencies are installed after cloning (i.e. SQL Server).
  3. Ensure the correct Project is set as Startup and then do a Build on the Solution.
  4. Install DotNET Upgrade Assistant using the Extensions Manager is VS 2022.
  5. Diagram the Solution into a dependency tree to identify leaf Projects, and to find other dependancies and supporting files.
  6. Run the DotNET Upgrade Assistant on the leaf-node projects first, and then clean the build for that Project, then run Build on the Project. Solve any issues.
  7. Repeat step 6 for the remaining leaf project.
  8. Repeat step 6 for the remaining parent project(s) up to the last, most-common/root project.
  9. Update or add NuGet package Microsoft Extension Configuration to use appsettings.json, in place of App.config files.

There could be some errors along the way:

The following will cause an error when building a WPF project:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>
</Project>

The solution is to target DotNET 6 using -windows as a suffix:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0-windows</TargetFramework>
  </PropertyGroup>
</Project>

I made some other notes in dotnetconf-2022 with some added reference links.

Also GH Copilot Extension exists for VS 2022! Will have to investigate other Extensions as well.

Tuesday 20-June-2023

Updated my Portfolio project today and started to figure out how a few more code blocks work.

DevIcons in React - options:

It occurred to me that one of the issues with the Bigfoot Winlink Form is it is not obvious which element is currently selected, especially while 'tabbing around' the form. A solution could be to apply a 'box-shadow' to the element types that need to be highlighted when they have focus.

input:focus {
  background-color: rgba(200, 200, 200, 0.2);
  box-shadow: 2px 2px 10px rgba(16, 194, 45, 0.7), -2px -2px 10px rgba(16, 194, 45, 0.7);
}

Other input types can be targeted with this pseudo-class, including select:focus, text:focus, and textarea:focus. The downside is the solution is 'heavy handed' in that every single element targeted gets this background-color and box-shadow. Another approach is to leverage onfocus and onblur events on the specific elements themselves:

<input
  title="Send your responses to the survey."
  class="submitButton"
  enctype="multipart/form-data"
  id="submit"
  method="Post"
  name="submit"
  value="SUBMIT"
  type="submit"
  onfocus="style.boxShadow='2px 2px 10px rgba(16, 194, 45, 0.7), -2px -2px 10px rgba(16, 194, 45, 0.7)'"
  onblur="style.boxShadow='0px 0px 0px rgba(0, 0, 0, 0.0), 0px 0px 0px rgba(0, 0, 0, 0.0)'"
/>

Monday 19-June-2023

Webpage design learnings and takeaways:

Sunday 18-June-2023

Webpage design thoughts:

Friday 16-June-2023

VSCode API: The TextDocument interface lineAt() function defines 2 overloads:

The TextLine interface defines lineNumber (a Number primitive) but does not differentiate between what I would expect to be "Line Numbers" in a text document, and the zero-based numbering system for a structure like a Collection. So, when processing a TextDocument Type, be careful with handling line numbers to avoid unexpected results.

Thursday 15-June-2023

Took some time out this morning to help a fellow ham with some email-over-ham technology setup steps. He was close, and together we got the configuration squared away.

Wednesday 14-June-2023

Worked on building out tests to increase code coverage to the remaining two functions in my VS Code Extension.

Lots of effort put into preparing for various upcoming events, including an all volunteer meeting tonight that included a presentation I was pegged to deliver on the agenda.

Tuesday 13-June-2023

Completed a code challenge: Sum rows and columns from a 2D Array of Numbers. Key takeaways:

Watched a presentation about Azure Bicep:

Worked through some preparatory work to get my VS Code Extension published. While I could have just published it the way it is, I decided to continue working on the last few unit tests to get better code coverage. Some key takeaways:

Monday 12-June-2023

Was introduced to JSDoc this morning while listening to the Syntax Podcast. Historically I think I've done a pretty okay documenting my code. In some instances it hasn't happened until after the implementations (and maybe even testing) are completed. Turns out, my default mode of documenting seems to be compatible with JSDoc /** This function returns ~something~ */ so if/when I decide to use JSDoc it should be pretty simple getting going.

/**
 * Find the first occurrence of a second level heading in the document.
 * @returns Number The line number of the first 2nd Level Heading of the page.
 * @param {vscode.TextEditor} editor The active text editor.
 */
module.exports = function findFirstSecondLevelHeading(editor, topHeading) { ... }

Key Takeaways Using Jest:

Have to remember that Linux and Windows "slash" characters are different. For example:

Fun.

VS Code Extension development status:

There are several more steps to take before publishing. It is getting close!

Thursday 8-June-2023

Focused on learning VSCode Extensions. I have a working idea for an MVP and am currently working on unit tests, documentation, and meeting VSCode Extension standards. :tada: :smiley:

Tuesday 6-June-2023

Caught up on VSCode happenings with an episode of VSCode Day from earlier this year. Appended some notes from this session to the github-copilot from a few weeks ago.

Started reading up on VSCode Extensions, and worked on developing an idea.

Monday 5-June-2023

Completed a personal challenge: Update the Quicksort algorithm to accept any Number types, or other Types that implement Comparable<T>. Final code can be found in java-code-challenges, Quicksort.java.

Saturday 3-June-2023

Spent 4 hours this morning at a volunteer event in Kenmore, which was a good experience overall. Beautiful day for an outdoor activity!

Researched WPF Controls and connected aspects, looking to find a solution to the Issue discussed yesterday. Not sure if my solution will meet the Issue (because the description is a little ambiguous), but I'll see how I feel after attempting to address it, and decide from there what to do.

Friday 2-June-2023

Worked through a code challenge in JavaScript, sourced from CodeWars. Took about 2 hours to do everything except for actual code, and about an hour to implement code and unit tests, and perform debugging (majority of the debugging was of the unit tests, not the implemented code).

Took some time out to look at some MSFT open-source code (C#). It was interesting trying to piece together a large, multi-project solution I hadn't seen before. Drilling-down into a posted GitHub Issue in the project, I found the area that would need the fix, and started on a quest to re-learn the components that are necessary to adjust in order to address the Issue.

Thursday 1-June-2023

While working through Portfolio project tasks, I found the templated code used JavaScript 'var' to initialize a new variable. It was assigned within an if statement code block, and was later used in the contianing function, appearing to be referenced before being declared. In C# and Java, var is used to limit the typing necessary to instantiate something that is otherwise obviously a specific Type. For example var newNode = new MyLLNode<Integer>(some_value);. In JavaScript, var is used to create and assign a variable that is scoped to the containing method (or globally if not in a nested function). This feature is allowed due to var hoisting, which causes var declarations to be processed before other variables. The result is the variable is effectively assigned at the top of the function. MDN Var Statement. Next time I dive into that code I'll leverage this capability, and undo some of the code I added prior to understanding how to properly use the var statement.

Had a phone conversation with another software developer, Ken, about the C# language. Was great to meet him, geek out on programming languages, and share some empathy around the challenges of learning syntax, patterns, and frameworks.

Wednesday 31-May-2023

Learned a little about integrating Chat GPT into applications, and some of the issues with securing an LLM Prompt.

Was able to finish configuring a Raspberry Pi security camera for watching the yard. There is some tweaking to do but it is ready for deployment, later today. The problem with focus was due to the manually adjustable lens. Simply turning it clockwise or counter-clockwise (slowly) adjusts the focal length.

Started refactoring the Portfolio project to better handle skills icons and simplifying code. My first attempt was changing too many ui and data elements, which broke rendering completely.

Tuesday 30-May-2023

Lots of administrative stuff to do today, including volunteer-related emails, research, and preparations. The Ride Around Mt. Rainier in One Day (RAMROD) communcations team was looking for help so I signed up for that event, in the latter half of July.

Completed initial setup of a Raspberry Pi-based motion-sensing, streaming camera. It was a bit of a pain to set up, but I finally got it going. The video quality is quite low and appears to be completely out of focus. I'l have to do a bit more testing, with the camera set up to view items farther than just a few feet to confirm this is a known issue with some Pi Cams that set the focal distance to something less than infinite.

Monday 29-May-2023

My Portfolio project React App was using something in SCSS called 'transparentize'. It was used to adjust the opaqueness of the background color of icons. Although it did the job I decided to change it to RGBA instead. Transparentize accepted hex values for color, and RGBA uses integers 0-254 for each color channel, and a decimal representing alpha from 0 to 1. I had not used these styling techniques before and they worked well.

Next time I decide to use DevIcons or Iconify, I need to use Iconify's search tool to get me started. Iconify has DevIcon sets within its massive store of icons, and the search tools has code in the search results for implementing in HTML, React, etc.

Sunday 28-May-2023

Deployed LBJS API using a YAML file! Assigned the task to a specific branch (not main) so that deployments would be managed with specific PRs. One issue is there are no tests yet, and that should really be part of the pipeline operations.

Saturday 27-May-2023

Completed implementing an Express server with Jest tests and GitHub Action that builds, tests, and deploys the server to Azure App Service. Next step is to apply what I've learned to LingoBingo API server so that tests can be implemented and deployment will be automatic. :tada:

Friday 26-May-2023

Spent the day working on odds and ends.

Thursday 25-May-2023

Did some cleanup of my Bigfoot Bib Report Form repo, editing the README for clarity and to be up-to-date, removing an unused GH Action, updating the Packages to the latest version of HTML and TXT files, and deploying a preview site to Netlify of what an end user would see when launched within Winlink Express.

Completed the SQLBolt exercises to refresh my memory on using SQL Queries. Aside from all of the synax necessary to become proficient at CRUD, the exercises mentioned the order of operations within SQL Statements. In order they are:

  1. FROM and JOIN clauses execute, usually creating a temporary table for the remaining operations to work on.
  2. Where clause is executed, eliminating data that won't be included further into query execution.
  3. Group By clause organizes the current result set based on the expression.
  4. Having clause will execute if there was a Group By clause ahead of it, further reducing the dataset.
  5. Select causes the dataset to retain only those columns identified in its clause, including Aggregate Functions and the Distinct keyword.
  6. ORDER BY executes to further arrange data by columns, ascending or descending.
  7. LIMIT (and OFFSET if included) retain the final output elements of the dataset.
  8. The resulting view is returned.

Worked on a few issues with my Portfolio Website Project. Took a bit to warm-up to Bootstrap and in-line Styling. The major issue was alignment problems on the About page, and the minor issue was the About Me write-up. Both got attention and the webapp is now updated. Some things of note:

Wednesday 24-May-2023

Today is day 2 of Microsoft Build 2023. Key takeaways:

I started using GitHub Copilot today. Often enough I waste a good amount of time flailing around trying to produce just the right syntax, or looking up details on the internet to get to a sensible, effective implementation. I should instead be making better use of my coding time by minimizing time-to-learn and finishing managable tasks within a reasonable timeframe.

  1. There is a 30-day free trial, so why not?
  2. GitHub Copilot is like pair-programming (which I enjoy) although probably not as cool as working with a real human.
  3. I am not creating anything new. There is no IP in my code or apps. Everything I write more-or-less ends up on my publicly available GitHub anyway. And for those situations where my code needs to be private or ownership is involved, GH Copilot can be told to not use that code as part of its learning/context building feature.
  4. My goals are to learn and build my skillset, and to start producing applications and services that achieve things.

Seems like the best place to start is to resolve some existing issues in one of my exploratory code repos on my local laptop:

Tuesday 23-May-2023

Today is day 1 of Microsoft Build 2023. Key takeaways:

In between MSFT Build sessions, I worked on implementing AbstractSequentialList interface to a custom LinkedList class I recently created. Although the implementations aren't working yet, I learned a few things:

References for today:

Monday 22-May-2023

Long volunteer weekend in Portland was fun, supporting the Multiple Sclerosis Society's Walk MS event. Great people, great cause.

Java Scanner class review key takeaways:

Rummaging through Java Collections library I discovered a few handy things:

Using the List Interface Factory Method in a Constructor:

List<String> testLL = new LinkedList<>(List.of("alpha", "bravo", "charlie"));

As I experimented with Java based on inspiration from the above readings, I felt like I needed to review java collections and generics best practices. This led me back to some Java code examples I wrote while configuring VSCode for Java several weeks ago. Collections in Java include various types of Lists and Maps, and the supporting interfaces help drive functionality implementation and inherited capabilities. Turns out writing a custom LinkedList (or other collection type) class can be assisted by extending AbstractSequentialList and other interfaces from the Java Collections library. I spent a few hours refactoring existing code into a Collections-extended, custom LinkedList class.

Thursday 18-May-2023

VS Code's twitter account linked to a VSCode YouTube Channel event featuring Dan Shiffman (@shiffman) discussing p5js usage in VSCode. It was inspiring and lots of fun.

Wednesday 17-May-2023

Decided to create a DSA note taking page to track experiences and references so I can refer to those separately from the java-code-challenges or other repositories.

Tuesday 16-May-2023

It's concerning to start the day opening an existing (last-known good/functioning) java project in VSCode and it logs errors on imports stating source cannot be found. Opening the Gradle Extension and clicking "Reload All Gradle Projects" solves the problem. :tada:

Working through Quicksort one last time. I was still confused about how exactly the algorithm does what it does, and would get stuck with certain test cases failing due to duplicates in the array, or ending up not-sorted or endlessly sorting. For those cases that ended up not-sorted/endless, stepping through the code in debug mode showed that the algorithm would sort the array, but the stop conditions were not correct to keep it sorted and the algorithm would then un-sort the array, putting it into a state that further recursive calls would never be able to sort because there would be out-of-scope values that are out of order.

Monday 15-May-2023

Posh-Git:

Portfolio:

Code Challenge:

Wednesday 10-May-2023

Added a GH Repo for a small project I started working on back in November. Updated the old default branch to 'main' (surprisingly easy). Added GH Actions to build and test, and enforce PR and Status checks prior to merging to main.

Got a little off-track setting up my local for more work with CoordinateConversionUtility and changed-up the Posh-Git prompt:

PowerShell has its own prompt settings:

Tuesday 9-May-2023

JavaScript. So useful and at times so elusive. I completed a basic JS challenge within 45 minutes following the full CF rubrick, and the only hang-up was with validating JS built-in types. Key takeaways:

// multiline boolean return (simple example)
const bool1 = input1 % 2 === 0;
const bool2 = input2 % 2 === 0;
return bool1 !== boo2;
// single line boolean return from above example
return input1 % 2 !== input2 % 2;

Took a few side-trips:

Back to preparing Coordinate Conversion Utility for MPV demonstrating:

Monday 8-May-2023

Worked on some presentation materials for a volunteer meeting on Wednesday night. It's always a time sink but it forces me to organize my thoughts, and generate plans for the future of the organization, and for myself.

Worked through some reading and research on Java Streams API and functional interfaces.

Researched a potential employer (they don't appear to be hiring). Web-design consultancy in Seattle. Very small team, supports websites of at least one local event in my area. Turns out they use Wordpress site development, so my interest has waned somewhat. They have a good sales pitch describing who they are, what they do, and why. It was inspiring.

Sunday 7-May-2023

Worked on LingoBingo quite a bit, getting the code ready for cloud-hosted deployments. This is much more tricky than I anticipated:

It is pretty clear that one of my lacking skills is creative design in the UI. It's not that I don't want to be good at it. It could be argued that I am not that skilled at back-end development either, but the result isn't visual and so is not prone to immediate recognition of 'ugly' or 'not quite right'. Something for me to work on, and consider as I push forward in my developer journey.

Developing the back-end to be Azure AppService deploy and functional with Authorization and MongoDB CRUD took me about 4 months in all. Code was developed here and there as I learned new things and came up with new ideas. There were definitely times where no work was put into it. However IT IS NOW LIVE AT AN MVP LEVEL! Users can login (auto-register), create words and categories, and create gameboards that the React FE will consume and 'fetch' the correct set of words. :tada: There is more work to do though and the next step is to document what is done, demonstrate how it can be used, and debug it so it is stable and reliable. A little farther down the road additional features like Delete Word, Delete Gameboard, and Update (replace) Word will be implemented. :tada: :boom: :smiley:

Saturday 6-May-2023

After some analysis of LingoBingo front-end and back-end environment variables and local vs. cloud configurations, the causes of the AuthN and AuthZ failures are now identified and my goal for the next few days is to get an MVP of the full-stack solution up and running in Netlify + Azure. Not much else to report other than lots of updating environment variables, editing code, squashing bugs, and deploying to Netlify and Azure again and again. Getting close, not there yet though.

Friday 5-May-2023

There is a growing list of things that I want to do, and should do. These lists are forever getting larger despite the many things I do actually complete. The good news is part of the problem is there are a lot of things I want to learn about and explore. I need to remember that so long as I keep moving forward and achieve professional and personal goals, how big these lists are is less important than what I am doing overall.

Moved the LingoBingoJS FE & BE dev environment over to my Windows workstation. Took a little over an hour to get both FE and API Server up and running, connecting to a database, and authenticating via Auth0. This exercise (and helping Ryan get setup last weekend) informs me that I have a bit to learn about maintaining effective documentation during the development process.

Some key takeaways:

There are still plenty of issues to work through, but at least now I have a workable environment and can help move this last major portion of the environment forward.

Why did I wait so long to install MongoDB Compass? What was I waiting for? Compass is more capable than the Atlas website!

I started using VSCode.dev to write code in a web browser. While it is missing some functionality like Run-and-Debug and some Extensions support, it is practically the same as working in VSCode the application. Open the website, connect to a GitHub repo, create a new branch, write code, then use the Source Control widget to manage staging and commits. Simple, quick, and integrated. Good job MSFT and GitHub!

Watching Code Fellow students demo their 301 and 401 projects I learned a few things, and want to explore a few other things:

// within the body of the React module:
const cardImage = {
  width: '90%',
};

// and then within the render function:
<Card.Img style={cardIimage} src='' />;

// etc

Thursday 4-May-2023

Received some resume feedback. Will be using that to update my resume to be a little closer to stellar.

Worked on a few administrative tasks. Started building a presentation deck to review the commex completed last weekend. More to do, but it will be done in pieces.

Looking at my Portfolio webapp, it can use some help. I have run across at least one job posting that is asking for examples online, and this is a good way to aggregate the links to what I've accomplished. The Portfolio webapp is clearly missing a few projects, and some creative design elements. For projects, not a single Python project is listed, and the one DotNET project is pretty basic and does not highlight my experience with DotNET and automated testing. This prompted me to get a new project listed: Coordinate Converter. This was last updated 2 years ago using DotNET 5 (which is now out of support) so an upgrade was necessary. Also, the last time this project was edited I was using Visual Studio Community Edition. All of my development efforts have moved over to VS Code so there are some other updates that are needed.

Upgrading NET5 to NET6 Key Takeaways:

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
    <PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
    <PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
    <PackageReference Include="coverlet.collector" Version="3.1.2" />
  </ItemGroup>

In the future I want to:

While rewriting the readme, it became apparent there are more bugs in the code than I had anticipated. A few new Issues were added to the queue with these bugs, but I'm certain there are even more. The next time I pick up this project I need to build it and run it locally, fix any major issues, and produce a NET6 MVP. This will provide a 'golden path' for demonstration purposes and for grabbing screenshots of the Terminal app in use for the portfolio site. From there, additional fixes and enhancements can be planned and later implemented as necessary.

I bumped into a Microsoft Learn event that occurred in April: VS Code Day 2023. Silly name, however the content is focused on productivity using VSCode. There are definitely things I could learn about VSCode to help me out, so this is in the queue, too.

Wednesday 3-May-2023

Interesting email regarding a job opportunity not far from home. After some research, I submitted a resume. The research was helpful, but the company is private, so information is (relatively) limited, and I don't subscribe to information-gathering services to draw from. I am interested to learn more about the opportunity because the description was a bit lacking, however I look forward to asking about the role and its responsibilities if the opportunity arises.

I've moved back over to my Windows development machine (nothing is wrong with the Linux environment). I discovered my NPM installation is a little behind, so it took me a bit to get it up to speed.

Upgrading NPM on Windows Key Takeaway:

I recall reading about GitAttributes having some overriding effect on local git configurations. Bigfoot Bib Report is a Windows-targeted project that I partially developed in a Linux environment, later to discover an issue with LF vs CRLF handling. Previously this was handled by setting up a CircleCI pipeline to re-write the text file with CRLF symbols in place of LF. That worked. Going forward, I wanted to see if GitAttributes would solve this problem going forward without using a pipeline. GitHub Docs has a nice little write-up.

Git Attributes and LF vs CRLF Key Takeaways:

Initial testing indicates this will work. I look forward to feedback from the other contributors and users once they get this latest version (probably late July and early August).

Tuesday 2-May-2023

Second iteration working through Quicksort was close but did not complete passing all of the tests. After some additional research I realize my mind was stuck on thinking of partitioning the array as an equal, symmetric operation. It doesn't have to be that way. For this challenge it might be better for me to think about solving the sorting problem by filling the ends of the array first. In other words instead of just picking the first index with a value that needs to be in a different position, find the index with the value that is most likely to be put at one end of the array. This requires sweeping the array several times, however after the first few sweeps the largest elements should be near the ends, and any elements still of the 'wrong side' of the array can then be managed within a sub-array (partition) without worrying that the out-of-order item will get 'cut off' from the rest of the array (and therefore never find the index where it belongs).

Monday 1-May-2023

Worked through another iteration of Quicksort. Some corner-cases still failing (actually, corner-cases are good now its the golden path that won't pass). Seems like a large enough value at the end of the input array won't get moved far enough to the left. Will debug again on another day.

At some point I need to start figuring out how to use anonymous method and lambdas in Java. I have no problem using lambdas in Java when I see documentation showing usage, but it has yet to materialize without assistance.

Sunday 30-Apr-2023

Continued working on Quicksort algorithm in between other projects. So far this second attempt seems close, although it feels like cases where inputs have duplicate values might fail completely. Once I finish off the core logic, refactoring code to the new implementation plan will begin, in tandem with regular unit test executions to guide the refactoring process.

Assisted Ryan getting his local environment working for LingoBingo. The tricky parts were:

  1. Refactoring Auth0 configuration for a new deployment is a little tricky and requires a super-keen focus on details to get the Auth0 Application configuration and the project environment variables correctly set.
  2. My code was not well documented so there was a bit of stepping-through that was necessary to find where it needed to be updated.
  3. It had been just long enough since working in the code that a bit of re-discovery was necessary to get myself up-to-speed enought to be able to help at all.

Over all it was great to work through the issues in a remote pair programming session that results in a working environment!

Friday 28-Apr-2023

Returned to designing a Quicksort algorithm and implementing tests and code in Java. It was close, but failed on 2 fronts:

  1. The code could not pass 2 of the tests that other sorting algorithms can pass.
  2. The code does not match a quicksort algorithm example (see Wikipedia).

The plan is to return to this challenge in a day or two with a tiny bit more research, and a fresh perspective on solving the problem.

Wednesday 26-Apr-2023

Lots of emails with questions about the volunteer exercise coming up on Saturday have been distracting me. Despite this, here are some takeaways from today:

Tuesday 25-Apr-2023

Much of the weekend was spent at volunteer events. On Monday the 24th I configured Netlify to deploy a test build branch based on my updates over the last several weeks, incorporating Auth0 and API calls. It works, however there is a problem and I suspect it is a timing issue when an API call is made but the page renders without a valid response.

CodeWars has been acquired and has had a bit of a redesign, including a restart of their email campaigns that I hadn't seen for several months. The latest email had an interesting code question: How to verify a Sudoku puzzle has been solved. I started fiddling with possible solutions in between other tasks.

Completed two JavaScript code challenges and posted them to js-code-challenges. Added GHActions to run tests prior to merging, updated README notes, and added code commentary to analyze code in Big-O notation.

The antenna swap activity was successful and the repeater seems to be functioning properly, although it hasn't been tested to determine if signal quality (or coverage) has improved at all. At least the site has an actual 'repeater antenna' that has been used in that purpose before, so I have hope that it will perform well for many years to come.

Friday 21-Apr-2023

My day was a little blown up with final prepping for several upcoming volunteer activities. However, I completed some interview preparatory tasks, got back into Microsoft Learn training paths, and also supported Code Fellows students by attending and interacting in their mid-term and final presentations.

Thursday 20-Apr-2023

Microsoft Reactor has been ramping up their informational and educational sessions. Three that are interesting to me are all happening today.

Tuesday 18-Apr-2023

It's that time again: Update the resume.

While researching job openings I noticed quite a few that are looking for SQL Query skills. While I have worked with SQL relational system before, and am currently working with Mongo DB, I felt like the question "write a T-SQL statement that would return a list of book titles, sorted by author" would be met with a lot of "uhh" noises from me, so I added a task to review SQL Statements to refresh my memory.

Did some refactoring and debugging on LBJS front-end:

Monday 17-Apr-2023

Did some Git cleanup on this article. I occasionally delete older branches and found a missed branch that was never merged-in to main, with some comments from August 2022, so I got it merged in. There are a bunch of administrative catch-up items I need to complete this morning, then do some preparatory work for 4 upcoming volunteer events that will require completing and publishing plans and notes from previous meetings, as well as preparing hardware for in-the-field operations over this coming weekend.

I updated java-code-challenges with some refactorings of code and tests that I did a few weeks ago:

There is some more work to do with the code to "clean it up", but it is in a much better place now and it can be loaded, code can be edited, and tests developed and executed in VSCode now! :bang:

Lots of work with React and Express today, working through implementations for LBJS. Key takeaways:

React does this thing in development where useEffect() executes twice - once to test the integrity and setup of the Component, and again to actually execute it. react dev documentation walks through why this is and how to work around it. There are still edge cases where it will not fix a problem and presents some options for resolution:

I also read through a section of Baeldung's Java Streams and took some notes in my Java Streams Reading Notes.

Finally, there were a few interesting job opportunities posted recently that I need to research and circle-back to.

Friday, Saturday, Sunday, April 14 through 16, 2023

Lots going on ending last week:

I still need to test published deployment using 'deployed settings' for both SPA and API Server.

Saturday and Sunday were spent working through implementing a componentized and state-managed design to the front-end:

Thursday 13-Apr-2023

Lots of effort was put into volunteer projects yesteray and today. Now I'm back to the program.

CodeWars: I hadn't done one of these challenges for quite a while so I decided to do a technical design practice and follow up with actual code. Apparently this was a good idea because:

Key takeaways:

const array1 = [];
console.log('array1 size is', array1.length);
array1.push(10);
console.log('array1 size is', array1.length);
array1.push(20);
console.log('array1 size is', array1.length);
// altering items in an array can be done with replacement
array1.push('40'); // a String
console.log('array1 contents', array1);
array1[4] = Number.parseInt(array1[4], 10); // parse String to an int of specified radix
console.log('array1 is now', array1);
// js arrays can contain different data types
array1.push('a');
console.log('array1 size is', array1.length);
console.log('array1 index 3', array1[3]);
console.log('array1 contents', array1);
// shift removes element at index 0 from an array and returns it
let index0 = array1.shift();
console.log('removed item', index0, 'from front of array', array1);
let alpha = array1.shift();
console.log('removed item', alpha, 'from front of array', array1);
// unshift adds elements to beginning of an array
alpha = array1.pop();
console.log('array1 is now', array1);
let fourty = array1.pop();
console.log('array1 is now', array1);
array1.unshift(alpha, fourty);
console.log('array1 is now', array1);
// Number.parseInt() is helpful but might provide unexpected results
const number = 'letter';
const letter = Number.parseInt(number, 10);
console.log('string', letter, 'is now Number', letter);

Wednesday 12-Apr-2023

Interesting discussion with a person at the dentist office today about the tech industry, layoffs yet lots of openings, how fast the software world moves, and building portfolios.

Tuesday 11-Apr-2023

Did a bunch of studying and redesign planning in Express js for my custom API server. Some key takeaways:

Monday 10-Apr-2023

Back to Auth0 challenges from a week ago:

My plan going forward:

Whelp, that wasn't really the problem but that's okay. Since using the canned SPA (React) and API (node, express) code does not get the data the API needs, a different route will be taken tomorrow:

  1. Read Auth0 Scopes and Claims
  2. Implement the OID request with user-consent.
  3. Have the SPA request tokens.
  4. Decode the token and grab the needed claims.

For the rest of tonight I am working through a small code challenge: Find the 'middle value element' in an array of elements, and return its index.

Sunday 9-Apr-2023

This morning was dedicated to doing some catch-up work due to my heavy focus on code and environment setup last week.

Completed the task of documenting how to use VSCode for Java projects. It is very sparse comments that covers:

The best resource for this is Java Project Management for VSCode at code.visualstudio.com.

Spent some time looking through Baeldung Java 8 Streams, in the hopes I will exercise my previous learnings, build on that knowledge, and expand my Java skill set.

Saturday 8-Apr-2023

Focused on implementing "Remove Node" and "Remove Edge" functionality on the java-code-challenges repo's Graph class. When I originally built this class and came to the point of having to remove Vertices or an Edge, I didn't have a clear path to a solution, and the ideas I had at the time were inefficient and difficult. With a little dry-erase modeling and design work, I discovered the problem is fairly simple (although there is probably a more time-effeicient way to do them).

Removing an Edge in a Directed Graph:

  1. Find the Vertex that has the Edge to be removed.
  2. Call the Vertex's Remove Edge function, passing in an argument of the neighboring Vertex.
  3. The Remove Edge function find the Vertex's Edge that has the Neighbor Vertex reference and deletes it from the collection.

Removing a Vertex in a Directed Graph:

  1. The Graph class finds the Vertex to be deleted and creates a reference to it.
  2. The Graph then traverses the Adjacency List and calls each Vertex's Remove Edge function, passing in the Vertex Reference to be deleted. This could be done asynchronously.
  3. Once the traversal completes (all Vertices remove their Edge references to the referece Vertex), the Graph Class tells the Adjacency List to remove the Vertex to be deleted.

Looks like moving to VSCode to do Java development and testing is not too tough, and the Extensions have enough smarts to use configuration-style project setup, or file-hierarchy style project setup, as well as integrate Gradle or Maven.

Friday 7-Apr-2023

Spent the morning configuring my main workstation Windows installation for development work. VSCode and Git and various support files were already installed, and some configurations were good. Git needed to be updated to support CRLF in a Windows AND Unix friendly way. Some takeaways:

I still need to confirm my Windows workstation can play nice with:

Learning to get comfortable with Linux has been a journey that I've enjoyed and am sure will help me in the future. For now, I want to expand my ability to develop in both Linux and Windows environments. This agility could come in helpful for future employment, as well as when I am home and away from my primary Linux workstation.

Cloning to a Windows machine from a Git Repo that contains files with unsupported file name characters or filenames that are too long, will cause a Clone problem. Good news is Git provides a helpful message:

error: invalid path 'license.'
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'get restore --source=HEAD :/'

Installing WSL seems like a good solution for this. The inconventient result is a reboot is required to complete the installation and configuration. Additional takeaways:

This worked, but took much longer than expected because its not everday that I work with ssl certificates and a credential manager. For my future reference, some key takeaways about adding SSL Credentials to Git:

  1. Generate new keys with ssl-keygen.
  2. Add the generated public key to your GitHub profile's SSH Keys.
  3. Install Git Credential Manager or the latest git-for-windows to get the manager installed locally (rather than use the cache).
  4. Set the credential helper Git configuration to manager-core (or manager which might be deprecated).
  5. Test the SSH Key setup by using ssh -T git@github.com per instructions from GitHub Docs.

Also: If credential manager is already setup in a host Windows machine with WSL 2.0 installed, the WLS OS VM can access the existing CredMan installation and use that as its own configuration.

Thursday 6-Apr-2023

Spent more time tweaking VSCode for Java development, and working with the Testing and Debugging tools (for Java) in VSCode. I was able to import an existing project with a large file hierarchy, edit files, run tests (passing), and do the usual git operations.

The Bucket Sort experimentation took several more hours of my day. I was exploring the performance implications of various changes to the algorithm, and trying to understand the algorithmic complexity through the modular method calls. At some point in the future I want to design Bucket Sort again, from the ground up using a TDD approach.

Wednesday 5-Apr-2023

More on getting tests set up for Java in VSCode:

{
  "java.project.sourcePaths": ["src"],
  "java.project.outputPath": "bin",
  "java.project.referencedLibraries": ["lib/**/*.jar"]
}

Testing Java in VSCode has more detailed information.

At first I selected JUnit Jupiter and it wasn't clear if fully supported (turns out it is fine).

Some takeaways while working with solution designing, Java coding, and Java debugging:

About generating random numbers in Java:

Tuesday 4-Apr-2023

Took care of some administrative and volunteer stuff.

Worked through some code challenges:

Developing Java in VSCode is a matter of installing supporting tools:

Monday 3-Apr-2023

Long day of battling Auth0:

So much for Monday, hello Tuesday please be more productive! :smiley:

Sunday 2-Apr-2023

I took a look into using GitHub Actions to enfore code style. Because Prettier is pretty great, and is now included with VSCode it is becoming fairly ubiquitous. GH Marketplace has a prettier-action that would do the trick. I'm not sure I feel comfortable with it adding a Commit to a Push or Merge. However, it has a dry run parameter which will fail the Action if Prettier has to make changes. The remaining challenge then is to ensure the settings in the GH Action match the actual desired codestyle and the VSCode user profile Prettier settings are in-sync. And isn't that the problem to begin with? With some experimentation I got it to work and will use it as a (potentially ongoing) learning experiment on my Portfolio project. Key takeaways:

Saturday 1-Apr-2023

Finished up a version of Merge Sort that I can be happy with. Some takeaways:

The final Merge function turned out like this example code:

public void merge(int start, int midPoint, int end, int[] inputArr) {
    int leftIDX = start;
    int rightIDX = midPoint;
    int tempIDX = start;
    int[] tempArray = new int[inputArr.length];

    while (leftIDX < midPoint && rightIDX <= end) {
        if (inputArr[leftIDX] <= inputArr[rightIDX]) {
            tempArray[tempIDX] = inputArr[leftIDX];
            leftIDX++;
        } else {
            tempArray[tempIDX] = inputArr[rightIDX];
            rightIDX++;
        }
        tempIDX++;
    }

    for (int fillIDX=leftIDX; fillIDX < midPoint; fillIDX++) {
        tempArray[tempIDX] = inputArr[fillIDX];
        tempIDX++;
    }
    for (int fillIDX=rightIDX; fillIDX <= end; fillIDX++) {
        tempArray[tempIDX] = inputArr[fillIDX];
        tempIDX++;
    }
    // the following built-in array copying utility was added by the IDE
    // my code was a for loop from start to end, tempArray to inputArr
    if (end + 1 - start >= 0) System.arraycopy(tempArray, start, inputArr, start, end + 1 - start);
}

Friday 31-Mar-2023

Worked through a Merge Sort algorithm challenge. Started last night, whiteboarding the basic idea behind the solution. Came back to it today to do a full technical interview style solution. It took about 3 hours total including writing actual code and the golden path test. While the code is not fully vetted, this is arguably the best I've been able to implement a Merge Sort algorithm without looking at a reference to get through it. Key takeaways:

// find "left" sub-array and "right" sub-arry of an input array
public void partition(int startIdx, int endIdx, int[] fullArray) {
  // if endIdx is 6 then mid = 3
  // if endIdx is 7 then mid = 4
  int mid = endIdx % 2 == 0 ? endIdx / 2 : (endIdx + 1) / 2;
  // assigning startLeft for clarity
  int startLeft = startIdx;
  // assigning endLeft to be last IDX of "left" sub-array
  int endLeft = mid - 1;
  // assigning startRight to be mid aka first IDX of "right" sub-array
  int startRight = mid;
  // assigining endRight for clarity
  int endRight = endIdx;
  // call another function to process "left" and "right" sub-arrays
  var result = processLeft(startLeft, endLeft, fullArray);
}
// avoid adjusting the incrementing indices within nested loops
// instead just have the loops do the work for you
public void merge(int startLeft, int endRight, int[] fullArray) {
  for (int leftIdx = startLeft; leftIdx < endRight; leftIdx++) {
    // by forcing the inner loop to start 1 index greater than outer loop index
    // the inner loop auto-adjusts and never gets overlapped by the outer loop
    for (int rightIdx = leftIdx + 1; rightIdx <= endRight; rightIdx++) {
      // compare values at array leftIdx and rightIdx and call a shift function
      // to move higher-value item at array rightIdx to the leftIdx location
    }
  }
}

Thursday 30-Mar-2023

Took care of some administrative stuff this morning, and cleaned up a couple notes files from previous events.

Reviewed Graph data structures and a custom method I developed (by hand) that find accumulated weight between two vertices. Also updated TODO lists with completed tasks.

While reviewing job postings I found one on LinkedIn that turned out to be click-bait. That makes job hunting that much less fun, oh well.

I was out for a bit, and when I came back I reviewed "Zip Linked Lists" challenge and made some minor changes. This is tight, well designed code. There is room for improvement in the tests themselves, but adding To String overrides allows visualizing the test inputs and outputs for confirmation that the zipper code is doing what is promised.

Wednesday 29-Mar-2023

Reviewed Promises again. Maybe this time it'll stick. :smiley: Just for the record, in recent weeks I have been using Promises correctly, and have also been implementing async-await whenever possible due to its simplicity. It is also worth noting that a Top-level Await in JS Modules is not available and newer browser support is pretty good (see MDN).

Tuesday 28-Mar-2023

Attended a MSFT Reactor "Monitoring Azure Resources" event. Hoping this will provide some basics on adding monitoring to my AppService deployments. Somehow, I've missed a regular MSFT Reactor newsletter offering with more info about virtual and in-person events, until today.

Bumped into an interesting way to avoid compile-time warnings of Unchecked cast statements in Java. See Java Exceptions and Scanner for details. I also cleaned up that exceptions and scanner content for readability.

Completed a code challenge for Java to practice using File IO and NIO: Build a console application that will return the count of characters within a provided text file. This took me about 3 hours to complete from design, through implement, test, refine, and document. I updated java-code-challenges with the results of this exercise.

Monday 27-Mar-2023

Researching SWE openings recently I've noticed more Java Kafka positions. This is the first I've heard of Kafka so I took a peek. It is a framework for processing and presenting 'big data' for your applications or services, in Java. It is open source, based on Java 8+, and abstracts away the complexities of big data so your app can adapt to the Kafka inputs, and not worry about processing large amounts of data. Sounds interesting! I've added a task to take a peek at Kafka.

Reviewing Insertion Sort and Selection Sort, two key takeaways on the basics of these 2 algorithms:

Sunday 26-Mar-2023

Spent several hours trying to debug an Auth0 problem:

Completed some administrative and wrap-up work left over from last week.

Saturday 25-Mar-2023

Completed integrating Auth0 into a dev branch of LBJS. Key takeaways:

Started working on API calls using authorization:

Friday 24-Mar-2023

Continued working on authorized section of LBJS. Key takeaways:

Thursday 23-Mar-2023

Working with LBJS attempting to get a page of forms designed for this next version. My initial idea was to use Bootstrap Accordions and Forms, and of course Accordions gave me trouble. Key takeaways:

Wednesday 22-Mar-2023

The JavaSE Tutorials on Basic IO are quite long, and I'm nearly done studying them. Hopefully I'll have a better grasp on what I'm doing next time I need to work with Files, Scanning, and Streams in general.

Reviewed Hash Tables data structure and methods. Did pretty well, and could probably be conversant about the topic. Coding one without help might be mostly successful - not quite there yet.

Tuesday 21-Mar-2023

Researching algorithmic complexity, it is good to remember:

Completed Insertion Sort code challenge. This was difficult. Key takeaways:

Monday 20-Mar-2023

Job hunting has revealed many more advanced position openings in the last week or so. Also, several interesting positions are looking for AWS experience that I would need to brush up on. I have a few backlogged projects I'd like to work on that would support using AWS tools, so I am inclined to consider how to reorganize my task log to make room for that.

Working through a code challenge to sort an Integer array I realize my sort algorithm knowledge is lacking. I kept trying to implement a merge-sort algorithm but couldn't quite get it working so I fell back to a simpler, very inefficient, selection sort-like algorithm. After coding and testing this, I will take some time out to study and analyze other algorithms.

Sunday 19-Mar-2023

Working through the Java SE documentation on Streams. Code Fellows curriculum covered this, but I need this added context and detail to get a better handle and to know when and how to use them:

Ryan submitted some comments on PRs and merged a few in to Main. One issue was an inefficient check performed at every Game Session load (whether starting, during a game, or playing again) that was O(n) in time and space. I wasn't sure I could solve the problem, but after some studying and trying things out, I found an O(1) time and O(n) space solution that should do the trick. This also eliminated an additional useEffect() hook, further consolidating code into an existing hook with similar dependancies. :medal_sports:

Saturday 18-Mar-2023

Completed a code challenge adding one Binary Tree to another. It was completely incidental that I ran into this challenge, and it just happened that designing a solution worked well in my current workload -- better than some other tasks would have. Key takeaways:

I added to my network a little bit, but I still need to update my resume.

Reviewed an Azure Friday episode Developing Azure Functions using v2 Programming Model for Python. This breaks down to decorated functions that Azure Functions Service recognizes and deploys accordingly, and there is a local (virtualized) dev environment for rapid ramp-up.

Completed my weekly retrospective, stored elsewhere. I know what I need to work on, I just need to keep moving forward and keep my head up along the way.

Friday 17-Mar-2023

Prettier was integrated into VSCode recently, which is great! There are some things to know:

Review React Documentation on JSX.

Thursday 16-Mar-2023

While researching open positions with a C# / Scala team in US-East, I uncovered a bit of an interesting rabbit hole, discovering different views about investing, decision-making, and meritocracy. I don't believe the company/team would be a good match for me, but I came away from the research with a few notes and slightly changed view of the world...an unexpected takeaway.

Reviewed java code challenge: Binary Trees and decided to merge-in the PR as-is. There will always be more to do, but not right now.

Completed some administrative tasks, and discovered I should rework my social media follows a little bit, and also try to squeeze in some official podcast time so I am more regularly introduced to on-going tech topics.

LBJS on Netlify work takeaways:

Create React App documents on deploying to Netlify.

Wednesday 15-Mar-2023

It's practically Thursday and I'm just now writing about my day.

I completed some interview prep and job hunting tasks. There were a couple of interesting openings - one required relocation (would pay but I'm not interested in moving right now) and another was not a well formed job opportunity posting, just failing to describe the job or who the hiring manager was looking for. I did pick up some good insight into what a few teams were looking for in a candidate, even if the experience or other aspects did not match well for me.

Self tested on some data structures and algorithms, and completed a code challenge: Whiteboarded a complete solution in 45 minutes with analysis, test approach, step through and code, and then validated the code in Java with tests. Along the way discovered something called a TreeSet: A Java utility class that provides sorted data. I didn't research it completely, and am assuming it is a Binary Search Tree. This was useful for ordering a large number of inputs to get the largest value (last sorted item) without knowing what the values were, so a unit test using large random value inputs could be used to test my code.

Back to LBJS:

Tuesday 14-Mar-2023

Happy Pi Day!

This morning I continued development on the Binary Tree class, completing implementation of the remove() function, verified tests passing, and performed some general code cleanup. There are a few more things I want to get done with this code challenge, but it will wait for another day.

I found a few software job postings online today that were worthy of some time to research.

I also reviewed my previous java code challenge work on Graphs. There are some issues with the Readme content, and perhaps sometime I will address that. For now it stays as-is. However, I came away with some thoughts about using HashTables and Sets to store unique values for later lookup (Graph, Traversals with Visited Collections, etc):

Started researching Java Streams and making notes here.

Monday 13-Mar-2023

Put some time into designing Binary Trees, continuing from yesterday, and also started coding tests and implementing from designs. Key takeaways:

About Binary Tree Nodes vs their (possibly) containing Classes:

I plan to add the ability to find the Height and Width of the Tree, as well as implement recursive depth-first traversal, as well as a generalized breadth-first traversal function. At that point, this challenge should be done, effectively replacing the older binary tree implementation.

Sunday 12-Mar-2023

Completed some administrative tasks including end-of-week retro. Since I have missed completing my retros on Fridays, I'm going to reset the goal to Saturdays instead. Seems to make sense anyways because I track weeks Sunday through Saturday.

Whiteboarded some Binary Tree structures and traversals, but somehow am getting stuck on depth-first. I'll need to work on that tomorrow (I know it, just need to work it out again which is good practice). This is in preparation to replace my Binary Tree implementation in my java-code-challenges repo.

Saturday 11-Mar-2023

This morning was a little disrupted with a vehicle repair situation, followed by a drive to Puyallup for a ham convention and electronics show. I met up with a few hams I have volunteered with in the past and we caught up a little. It was good to get out and be social.

At home I designed a set of functions using Java, on a Singly Linked List to do various things:

I still need to do my end-of-week tasks, but that will have to wait until Sunday.

Friday 10-Mar-2023

Completed a code challenge on a real dry-erase board with pseudocode and step-through (excluding BigO analysis and tests).

Attended a Code Fellows Code301 Final Presentation session. The Code301 curriculum has been updated with React Hooks and WebSockets. I am a little envious about this, but I have already started to use React Hooks, and can always add Sockets as a topic I want to explore in the future.

The MS Graph project is not very exciting to me. I thought it would be, but I find myself not getting excited about interacting with MS Graph, and feel like I am putting more into it than I am getting back, so for now I'm going to set it aside. There are a few more days left so I might go back to it, meanwhile there are tasks I am passionate about, so I will pursue those.

I completed some LBJS activities, and with some research and experimentation came away with these tidbits:

Later, I set up my SurfacePro 7 VSCode with Java development Extensions and it is working well for dev and simple debugging. I will need to learn how to set up unit tests as well as find build output (JAR) files, but that will come in time. Using this setup I coded (in Java) the code challenge from earlier today (a singly linked list) and starting building out additional functionality:

Thursday 9-Mar-2023

Lots to do today. For starters, attend an MS Reactor presentation on TS: Deploying React+TS App with Azure Static WebApps. Next, some volunteer administrivia finalizing a capabilities diagram and sending a few follow-up emails from last nights meeting. Then, to finish up the morning, complete some job research and preparatory tasks. This afternoon I'll get back to MS Graph development, and try to sneak in a technical challenge or two. Friday is usually a busy morning, and Saturday I'll be at another event for a large portion of the day, so today is probably the last 'full day' to get some impactful things accomplished.

I'm realizing that I can be organized and yet still experience some chaos of my own doing and from outside inputs, without concluding I lack structure.

Wednesday 8-Mar-2023

Holy wowzers it took me 2 hours of fighting with DotNET ConfigurationManager extensions to figure out how to get environment variables into a console app. Good news is I DID IT. Key takeaways:

Took some time out from the MS Graph project and studied some OOP and C# lessons from a few years back. It is interesting to see the anonymous functions, Delegates, and other keyword implementations after studying JavaScript and Java for the last year and 6 months (respectively). I can't believe I had such a hard time with data structures and algorithms in Java, given that I had already be training those concepts in 2021. Anyway, it was good to go over some of this and I'll count that at code challenge studying for the day.

Back to MSGraph: I was having an issue where authentication was failing in a weird way. The message indicated that the wrong tenant was selected for authentication. It took a bit to figure out which portion of my setup was bad, but the only thing remaining was to verify my app was properly registered (was the ClientID correct?). I remember creating an Application and setting a ClientID, but perhaps that was deleted after my first (very rough) attempt to develop this hacky solution. Once I went back in and registered the an and set the ClientId, the code would run without hanging or throwing, and data was actually returned.

Tuesday 7-Mar-2023

Spent a good amount of time reviewing code already written for LBJS API server and finding some places where things could be improved, and updated the uuid generation to use base64url encoding instead of hex. I was originally going to implement Secure Cookies but I'm going to table that effort for now, and put a work item in my backlog for focusing on later. For now I need to spend more time in front of MS Graph and C# so I can submit something for the hack-together event.

On Monday, before diving deep into the API Server, I did some research on a few companies. Nothing terribly exciting has come up yet but it is interesting to see lots of job expectations, company values, and ways companies interact with the internet.

This evening, my MS Graph project could no longer get past authentication. The problem might be related to my changing the app.config file (per docs) but I'm not sure. Will look into it tomorrow morning.

Sunday 5-Mar-2023

Continued working on LBJS API Server, reviewing the implemented paths and refining the code, runing manual tests to validate functionality and crash avoidance. Utilized whiteboarding to work out logic fix-ups and refactorings for some functions. There is still work to do here but it is better. Began researching SecureCookies, which seem simple enough, just need to figure out the proper syntax to get the secure key working. Current thinking is to use a secret salt and just go with that. One concern is dealing with these massively long UUIDs - it might be good to use URLEncoded or some other conversion or digest method to keep the IDs from becoming too long for the frameworks to handle them (introducing unexpected results and matching or authorization bugs).

Saturday 4-Mar-2023

Did some job search work and updated lots of administrative items and documentation. I also completed a week-end retro for this week. These are helpful in setting a pace and expectations going forward.

Whiteboarded some new appoaches to existing API Server functions. Turns out there were some issues with some routes and also the default error handler. One route issue was checking for situations that would never occur because the cookie handler middleware would have caught it, leading to cleaner code. Takeaways:

There are 7 more tasks to complete before I will feel like the API server is in a good-to-go state.

Friday 3-Mar-2023

Some developments this morning:

Completed the Java Generics exercises, and experimenting with the code and tests I produced.

I updated the MS Graph code a little bit. There is much more to do and learn. The main hang-up right now is figuring out how to handle the result type from a successful, filtered request. It is not obvious to me.

Thursday 2-Mar-2023

Attended another seminar on Microsoft Graph API and SDK, and signed up for the hack-a-thon challenge at MS Hack Together. Initially I considered a Java-based Android app for my submission, but the DotNET SDK is a requirement for entry, so I'll stick with that. It took some time to get used to how the Graph Explorer works, including permissions allowances to various endpoints. While using the tool I set up some ideas for project features I could implement, and wrote a Console App in C# with DotNET SDK 7. Key Takeaways:

Wednesday 1-Mar-2023

Attended a seminar on Microsoft Graph API and SDK for DotNET. Microsoft 365 is building features and functionality on top of Azure services and the DotNET platform. Microsoft Graph allows querying for "me" data, meaning the API endpoint root is "me" and after authorization, the REST methods allow calling for calendar, email, task, and other data. MS Reactor will be holding more sessions about Microsoft Graph in the coming days and weeks.

Reviewed Java Generics on Oracle's Java Documentation. It went into much more detail than I had expected. It made sense although it was slow going at times. In the past I ran into issues with Generics and saw some warning messages that I didn't understand, now they make sense. For starters, the Raw Types message: This means the code risks operating without type safety, and Object is used as the base Type, allowing Boxing and Unboxing to occur, and unchecked Casts, which can negatively impact performance, or allow Runtime Errors.

Some other key takeaways:

Tuesday 28-Feb-2023

It's snowing again.

Worked on researching interesting job openings, and exercised my brain with some q-and-a practice early this morning. It's a good wake-up exercise once I get some food and a cup of coffee in me. :coffee: :smiley:

Snow stopped falling, everything is drying out now.

Took at a look at some job openings, more research is needed.

Decided to take a peek at the Portfolio webapp project from April last year. There were many issues, partly due to deprecated and vulnerable versions of modules, and partly due to various CSS and content problems. I took some time out to fix all of that and deployed a working version to Netlify. I added work items of things to fix and update to make this portfolio webapp a bit more appealing and useful.

Monday 27-Feb-2023

Continued working with Graph data structure and completed the challenge: Write a function for a directed, complete graph, that finds a total value of a path between two vertices. Key takeaways:

Sunday 26-Feb-2023

Revisited updating dependencies of a React-JS webapp. Every so often vulnerabilities are found in node-js modules that probably should be cleaned up. Good news is, there are bug-bounties and free-lancers that find these vulnerabilities, so they get fixed in the OSS world pretty rapidly. Now the problem is for the implementers (dependecy dependers?) to update the node modules and redploy apps to avoid these attach vectors, for the sake of their own deployment, and their users.

Key takeaways:

Plenty of bouncing around today, between the Graph code challenge problem solving design efforts, and catching-up on LBJS PRs and enqueued work.

LBJS: We are very close to a point where we can launch V1 front-end and utilize the deployed API server to get existing gameboards if needed. We have means to authorize for adding words and creating gameboards all on the backend, so custom requests can be made. There are just a few bugs and a couple loose ends to resolve on the front end before pushing the latest to Netlify and basically having V1 ready-to-go for players.

I realized that instead of manually editing package.json and package-lock.json files I can use npm to manipulate dependencies safely. There are a few situations where manual editing is still required, but a lot of the complexity is gone now that I've worked out and refined a step-by-step.

Promises made a return, related to an Axios call in a useEffect on a React site. Some takeaways:

See conted index for an entry about Promises.

Ryan got back to me about some updates I supplied to him earlier in the day. He raised a good question about a PR that I submitted, so I went in and fixed it. I need to watch for obvious code-line omissions, kinda like 'copy-pasta' problems.

Saturday 25-Feb-2023

Worked on a few administrative and interview prep tasks, and watched an Azure Friday episode about billing: Monitoring and Reporting. This was timely since I recently started getting charges for a couple of AppServices (dimes and quarters worth, so at least it is small).

Working through a tougher Java challenge: How to get the weight between multiple vertices. Key takeaways:

I'll take a look at this again tomorrow, and I'll use a Stack rather than recursion to solve it. This way I'll have full control over the exit from the search pattern.

Friday 24-Feb-2023

Thursday was spent designing, testing, fiddling, redesigning, coding, and testing Graph class. The key takeaways are:

Friday morning I made the mistake of trying to change Themes to get something closer to VS Code's Night Owl custom Theme. There is one, but it is NOT the same. Also, I don't understand how changing themes in IntelliJ can possibly be fun. Couldn't they have just added a one-stop-shop to import, use, change, and edit UI Themes?

I continued with more redesigning and test-driven development with the Graph Class. Key Takeaways:

Wednesday 22-Feb-2023

Back to code challenges:

Some takeaways from working on code challenges:

Worked through interview preparation tasks. I need to review some documentation from back in June and July '22 to refine my preparatory tasks, resume, and etc.

The live stream about Windows Subsystem for Linux was canceled.

Tuesday 21-Feb-2023

Back to the drawing board to figure out the logic necessary to bulk-load words into a DB via an API. I was practically dreaming about this problem last night. Whiteboarding the problem took about an hour, but the resulting code works better than any of Monday's attempts. The final hangup is managing status codes and any result message. Gotta love it when the code works as expected, but the hang up is just error handling and final portion of the WRRC.

I generally find HTML Forms to be fairly easy to work with, with some referencing MDN for details and some syntax. Using PUG to display a form that will accept an array of strings was a little challenging. The key takeaways:

Methods of cleansing and massaging a long input string into an array:

Reviewed Graph Data Structures:

Monday 20-Feb-2023

Approached LBJS bulk-load words via an API. There are some limitations (like only authenticated users can do this) and requirements that must be met (at least 24 words, and the database should not be polluted with duplicate words for a single owner) that results in some design and slightly more complex implementation details. First idea was okay and leveraged Promises nicely, but the logic did not work out - duplicate words were allowed. Second and third attempts were better but still some logic failures were allowing duplicates. I shouldn't have let 3 attempts go by before re-designing. Will work on this tomorrow.

I knocked out several interview preparation tasks and took some time out to reorganize and re-prioritize work items.

Friday 17-Feb-2023

Knocked out a few more LBJS tasks including fixing code vulnerabilities in dependent node modules. Determining the correct set of steps to find and remove the vulnerable code was a challenge. This exercise led to some side-track investigations into a few things:

Ryan approved and merged-in a few PRs so I updated the Trello board.

Vercel has a getting started with Next.js onling training session that I should explore some day.

End of week retro:

Thursday 16-Feb-2023

Most of my time earlier this week has been spent on volunteer and around-the-house tasks. I will be presenting how to use "Email over ham radio" to a class of 12 hams on Saturday the 18th, and I think my presentation and plan is ready to go.

Completed an LBJS PR to componentize a pair of nested functions within a React Class component. After initial discovery and fiddling with the code I started to thing the effort was not going to be worth it. I took a break and thought about it, came back to it and implemented a slighly different solution that started working well. After a few short refactorings while testing, the webapp was working without errors. Key takeaways:

Watched a presentation on Linux on Azure. It wasn't too informative but I already have some experience with Azure services, so some of it was review. It was interesting to learn:

Knocked out an example 'favicon' file for LBJS. Was a good exercise in using creativity, Paint.net for image editing, documentation, and code management using git.

Thursday 9-Feb-2023

Completed a java code challenge, this time using a Queue data structure. Although I was unable to complete requirements of the technical interview, the diagram had good basic logic and required few edits to make it a good resource for writing pseudocode and actual Java code. Once I wrote Java code, about 4 lines of code needed to be removed, and there was only one small bug in the code that was quick to fix. All the tests, even the empty cases and those containing zeroes passed right away. One other positive takeaway is: I implemented a Queue class and Queue Node specifically for this solution and only needed to peek at a working solution once before the Queue implementation was fully functional (Peek, Enqueue, Dequeue, IsEmpty, and getSize/Count)!

Wednesday 8-Feb-2023

Took some time researching Azure and Linux. Microsoft Learn has resources and training materials that I started in on. Hopefully this will help me take the next steps, which is continuous integration, and eventually continuous delivery. See notes added to linux references.

Monday 6-Feb-2023

This morning I realized there was a problem with a test for the latest java code challenge so I fixed the test, which uncovered another bug in the latest revision of the code. I spend some time redesinging the code (to avoid writing really long and tedious garbage code) and came up with a solution. Some key takeaways:

There are other data structures I will try to get a good sorting algorithm working for this code challenge.

I also spent some time working on LBJS front-end. When a user is given a link to the gameboard by the presenter, the website should load the appropriate words and randomize them so the bingoboard is ready for the user to play. Lacking an appropriate gameboard ID in the URI link, the gameboard should still load a canned set of words. Last week I wrote a possible solution and included a 'then-able' Axios call, but I didn't quite implement it correctly. Key takeaways using Then-able Axios:

Sunday 5-Feb-2023

On Friday I attempted to impelment the code I created during a 45-minute code challenge and it became clear there were many issues. So today I retried the same code challenge and it moved along pretty well. I utilize a different data structure and traversing it was a bit easier. The 45-minute timer expired before I was able to walk through the code visually, but there was code on the board, and it had been stepped through using the design diagram I sketched up. What was lacking was stepping through the code using the example input collection values.

Saturday 4-Feb-2023

The code challenge yesterday has one pretty bad bug that makes it a failing solution, and there were a few idiomatic and syntactical issues, docking a few points. Given I haven't written Java in a while, this is not a total surprise. Plan is to re-try this challenge soon and do a better job of defining the problem before building an algorithm, and then walking-through the algorithm (debug it!) before writing the code.

Worked with Ryan, sorting out Auth0 authentication configuration and use of JSON Web Tokens and Keys.

Friday 3-Feb-2023

Slowly I am getting back to my weekly schedule. There have been enough interruptions the last few months that I have fallen behind on things like technical interview practice and other preparatory tasks. I am so fortunate I have the time and ability to put in this effort.

Completed a technical interview question that required code in order to 'complete' it. Initial rubric scoring of my solution indicates a likely pass, however I will need to review the idiomatic and syntactical correctness of the code (later today). One error I made was in code analysis:

After watching a presentation on algorithms and data structures, it occurred to me that during technical interviewing I often times get caught up in values. The presentation used colors as Linked List Nodes, rather than numbers or characters/strings. While it is true that values are important in an algorithm, it is more important early on to determine how to traverse a data structure. Walking the structure is necessary for the algorithm to process the values within it. Once a data structure and traversing algorithm are selected, plug-in the numbers while performing a walk-through to verify the planned implementation.

Some advice shared by David:

Thursday 2-Feb-2023

Made some experiments with LBJS React using Axios to acquire a payload from our custom API server.

Also took some time to execute the implemented routes on the Azure-deployed API Server and everything is working so far.

Wednesday 1-Feb-2023

Attended MSFT Reactor session "Building Your First Typescript Project" and made notes in my Cont-Ed folder for reference. Key takeaways:

While working on what looked like a good fit for a Turnary Operator (which avoids writing yet another set of if-then-else codeblocks). While fiddling with the right Turnary Operator statement, I explored some alternatives and discovered that node.js will accept the Logical AND operator && followed by a Logical OR operator ||:

function getCode(arr) {
  return (arr.length > 1 && 200) || 404;
}

console.log('statusCode from [1,2,3]:', getCode([1, 2, 3]));
// output: statusCode from [1,2,3]: 200

console.log('statusCode from []:', getCode([]));
// output: statusCode from []: 404

MDN covers this in their JavaScript Reference documentation on Operators so there is no real surprise here but it was fun to stumble upon it while working on a real project. Fairly easy to read and less typing than if-else conditionals. Pretty neat! :sunglasses:

Tuesday 31-Jan-2023

Practiced whiteboarding while developing a route on the LBJS API Server: Problem statement, inputs and outputs, step-through definition (but no depictions/drawings), and javascript code (but no pseudocode). Took about 45 minutes to complete whiteboarding, perhaps 5 minutes to implement the code with only minor adjustments, and another 5-10 minutes of debugging and the code is functional! There are probably a few more bugs to work out, but only one major bug-fix was required to get the happy-path working as intended. :boom:

Implemented cache and Promises on one of the routes. All of this practice is paying off and implementations like these are getting easier, and are completed more quickly than before. I still need to add tests to the functions for sanity sake, and there are plenty of refactorings needed on most of the other routes... those things will be done in time.

The LBJS-Back API AppService has been redeployed with the latest PR code and it appears to be functioning! It can successfully return a JSON collection of words, and all of the existing routes are protected by default. Tomorrow I will do more testing using authorized users while watching the Streaming Log to validate API paths are doing the right things and Node.js is not falling over in Azure.

Monday 30-Jan-2023

Spent a good deal of time battling Express Middleware and Error Handling again. I somehow allow myself to ignore the rules of these concepts, run into errors, and wonder why implementations are failing. Important aspects:

Sunday 29-Jan-2023

Chatted with Ryan to get up to speed with LBJS and we are both pretty busy lately. Overviewed the WRRC, current dev state of API Server to-be-deployed, and using Auth0 in a React (SPA). Will deploy a sample SPA that works with my Auth0 acct so Ryan can test and dev on his local using the working sample code.

Thursday 26-Jan-2023

This morning I attended a Microsoft Reactor live stream introducing TypeScript. I have some experience with TS as a test engineer but haven't tried developing with it yet. I'm not in a big rush to learn it, and this session gave me a pretty good idea about how to get started so I can start exploring when I'm ready.

Most of the rest of this week through Satruday was busy with other administrative and volunteer-orientated tasks.

Wednesday 25-Jan-2023

Key takeaways for Wednesday:

Tuesday 24-Jan-2023

Key takeaways for the day:

Monday 23-Jan-2023

Worked on the API Server a bit. Got caught-up in Promises and complexities of asynchronous server-side code. Will address this tomorrow.

Scheduled a meeting with Ryan to discuss LingoBingo for this comming weekend.

Sunday 22-Jan-2023

Was out of town last week and didn't do any coding or writing. Instead, worked on other tasks in between skiing sessions and other activities.

Friday 13-Jan-2023

Busy week. Lots of dev Weds and Thurs that didn't get logged here, that's okay here's a summary:

Going forward I won't have much time for implementing and securing routes, verifying username/password authN and authZ, and adding caching. Before the end of the month I hope to have the API server in such a state that the front-end can call an open route and get a valid response, and soon after that get authorized requests working as intended. Additional social login types will have to wait in the backlog.

Some other takeaways about deploying a Node.js project to Azure AppService:

For the Nth time in a few months, I've found myself getting a little confused around Promises. At least it's a new year. :smiley: Perhaps part of the confusion is I am mingling promises with Express middleware and custom error handling? In some instances the headers are getting rewritten (after already sent) and in others the system crashes instead of catching an error (despite being in a catch block). Some research followed by refactoring will be necessary to get this going properly.

Tuesday 10-Jan-2023

Started working on what will be the production API server for the LingoBingo project. Basic API paths hierarchy is laid out, schemas are added, database connection is working, and some core functional modules are implemented. Next steps:

  1. Implement authorization validation.
  2. Implement cookies to maintain application sessions.
  3. Test a live Azure deployment can access MongoDB Atlas.
  4. Implement additional API routes ones at a time.
  5. Implement caching and other features.

Security will be maintained through Authorization Validation checks and use of Write- and Delete-capable modules only on specified paths with input and processing guardrails.

Saturday 7-Jan-2023

Technical Datastructures Review, areas where I need to brush-up on:

Completed some interview preparatory tasks, and an end of week retrospective.

Completed writing up a summary of Firebase Authentication: Setup and Implementation. I still need to go back and do it again from scratch so that I exercise what I know, and learn what I don't.

Wrote-up notes on an Azure Friday episode about Azure support for Java Development. Microsoft released their own OpenJDK of Java 17 (LTS). It might be based on Adoptium.

Writing up some notes on error handling in ExpressJS. I left-off about 1/3 the way through the API documentation while implementing the basics on a few cached routes.

Other Key Takeaways:

Friday 6-Jan-2023

Fiddled with PowerShell 7.x for a minute (2 hours). Now I remember one of the driving forces to find another language to learn and to get a better understanding of object-oriented principles. PowerShell has its place none-the-less.

Took some time to implement caching on the (private) getting-started API server:

A good portion of the rest of my day was spent preparing and emailing items in my volunteer capacity. It is set in stone (pretty much) that I will be running a training session, demonstrating basic Winlink startup and usage. Within a couple hours of the email announcement going out, the 'registration survey' already had 1 response, and I know there will be at least 2 more, maybe as many as a dozen!

Goals for Saturday:

Wednesday 4-Jan-2023

For the first time in over a month I went for a run on Tuesday morning and I overdid it. So I ran again this morning and it was much easier so back to work!

Working on the Auth0 front-end:back-end authentication project:

Now the front-end is able to access unprotected routes without an Authorization header, and CAN access PROTECTED routes WITH an Authorization header and a valid Token:

UseEffect is easy to get wrong, here are things I learned getting it wrong, then debugging and getting it right:

Monday 2-Jan-2023

Happy new year!

Entering retro notes daily is a little overkill for my purposes, so I'm going to try a weekly branch => push cadence instead.

Deployed an example API server with canned authentication and data (no DB backend) to Azure App Service:

Going back to the React + Auth0 + Express example deployment:

Tomorrow I will get back to this and:

Friday 30-Dec-2022 and Saturday 31-Dec-2022

Express Learnings:

Thursday 29-Dec-2022

A markdown surprise: H1 Headings can be made using equals signs. It will render the same as # Heading1.

Heading1
===

Demonstrated Firebase Auth and Auth0 capabilities to Ryan, for LingoBingo. We are both pretty confident that we can make Auth0 work with React FE and ExpressJS API Server, so we plan to start moving forward with server setup and deployment, and developing needed React pages.

Some more takeaways:

Wednesday 28-Dec-2022

Random comments and discoveries:

I had a good lunch break with my friend Dave in Snohomish. It was great to catch up with him and to talk techie stuff over tacos and coca-cola.

Tuesday 27-Dec-2022

Christmas week is over and it's time to get back to business:

Some key takeaways:

Friday 23-Dec-2022

Started working through integration of Firebase Auth into an ExpressJS server.

Attended a partner power hour presentation by Roger R, about Graphs, demoing a simple navigation app. Well done!

Wednesday 21-Dec2022

Goals for today:

Takeaways:

Tuesday 20-Dec-2022

I ran into a problem with getting the user context back from Firebase...rather, I knew the user was registered (and logged on) but somehow my code was missing the ability to update the state properly so that the site would show the user was logged in and allow logout. After trying some things I ran across some web resources about using Firebase and decided to explore them. Because my React App was manually configured, the WebPack and ReactScripts versions are in a buggy state that blocks using dotenv 'process' properly. This is a super-bad situation and probably means the site could have other broken issues I might not want to have to fix, so I'm starting over using the standard Create React App method. argh

Monday 19-Dec-2022

While working through an Advent of Code challenge, I found a need to develop a collection of custom Class instances.

Working through Firebase Authentication again:

Will keep moving forward tomorrow, after a good night's rest.

Sunday 18-Dec-2022

Interspersed: Various administrative tasks that need to be completed, outside of coding.

Implementing Firebase Authentication required resetting to my Linux dev environment. I wasn't too interested in using NPX to set up my new React project for this purpose, so I did it by hand following (most of the) advice of vish448's Gist on GitHub. Vish448's method included installing and configuring WebPack and Babel (neither of which are well understood by me just yet) so I spent some time working through issues:

Quite accidentally, I ran across what could be a helpful article next time I approach Auth0 + React (soon!):

React State and Forms:

Saturday 17-Dec-2022

Was ill last week and did not add notes here. Instead, I worked through several Advent of Code challenges and have completed the first 4 days' challenges.

Some takeaways re: Advent of Code solutions using javascript:

Lingo Bingo:

Saturday 10-Dec-2022 and Sunday 11-Dec-2022

Saturday:

Sunday:

-[ ] Review Firebase authentication and determine if this is a viable solution for a current project. -[ ] Update Miro with new design thought and approaches to the back-end API server.

Friday 9-Dec-2022

Completed some job hunting and interviewing tasks this morning.

Against my better judgement I took on part 2 of Advent of Code 2022 Day 1 challenge. I retro'd the outcomes elsewhere but in essence:

Completed end-of-week retro (elsewhere). While it was a good, productive week, there are areas where I can improve, so I will continue taking time and effort to better plan and execute my projects and time.

Thursday 8-Dec-2022

Fixed-up most of the CRUD methods in the exploratory API Server to ensure consistent output and status code returns. Still need to refactor OUT the req, res, and next from the gameboard functions module.

Had to do a git reset --soft <commit> due to my running git commit -m 'message' after an incidental git add . when I meant to git add <file>. Still not the ideal solution, but for this project the git history and messages aren't super critical.

I discovered that adding non-async calls to another module, from within an async function can really cause timing havoc. The best solution is probably to move to promises over async/await.

Mongoose provides for model validation within the schema, so I added that.

Completing implementation of 'deleted' (boolean) and 'updated' (dateTime) field updates was not too bad. The biggest hurdle was learning how to create a valid timestamp in javascript: const dateNow = new Date(Date.now());. I modularized that so it can be called JIT from any other function that needs it.

I'm not too thrilled with Pug. While it is nice as a quick-and-dirty html templating engine, doing anything too fancy with it is just too tedious. Also, the documentation mentions 'native' handling of arrays, which is true, but then they use examples that are awful (using hard-coded values) AND what is meant by 'native' is an Array can be passed-in to the rendered Pug file, and it will just list it horizontally within a 'p' element without any additional effort on the developer's part. It is probably the case that the desired output needs to be processed prior to passing it in to the rendered Pug file? Not sure I care much about it right now -- if I wanted to do something truly good for the user, I'd just create a React App and be done with it.

Code Fellows hosted a "Code 401 Instructor Panel" as they have done every so often in the past. It is always enlightening, and usually uplifting. Today one of the instructors reminded the audience that honing expertise takes 10,000 hours, so keep hacking through the tough times and learning will happen along the way. This is a good reminder for me to consider where I was a year ago versus today, and 10k hrs is still a ways away, so I should not be expecting 'expert level code' by any means at this point. In other words: Keep at it, but take it easy on yourself.

The exploratory API server now has cookies fully implemented to use as an authorization tool for the various paths. Next goal is to get cache working on get calls.

Good places to start:

Wednesday 7-Dec-2022

Skipping an authentication provider service for now, working with cookies takeaways:

It was becoming more and more clear that I needed to implement middleware and Express Routes, so I started working in that direction. The goals are:

Enabling cookies was definitely a good idea. Validating cookies is a bit more difficult. Refactoring the code lead to some typos that consumed lots of time, but I can 'login' and 'logout' using just cookies. Next steps:

Some things I learned:

Goals for Tomorrow:

Tuesday 6-Dec-2022

Auth0 struggles stole most of my day. There were a few other interruptions too, and that didn't help. Key takeaways:

Monday 5-Dec-2022

Cookie exploration was interesting. I had forgotten a lot of what I'd been exposed to 20 years ago in college. The challenge then was learning how to use the cookie-parser middleware function. High level takeaways:

The basic plan going forward will be to use Cookies only in very specific places in LingoBingo:

Sunday 4-Dec-2022

Met with Ryan, discussed the exploratory API server, set some work items, and moved forward from there. He now has access to the exploratory API server to review the code and explore it's configuration and operation. I have a few new work items that will take some time to knock out.

The afternoon activity (not dev related) took up a good amount more time than I expected. Good progress was made but I was pretty much done for the day after that. Goals for today now pushed forward into the week.

Saturday 3-Dec-2022

USMNT is out of the FIFA World Cup, oh well.

Did some more work on API Server experimentation. Some key takeaways:

Update multiple documents across model namespaces in the same DB:

  1. Validate the inputs to the function that will perform this trick. Return an appropriate http status code and exit if validation fails.
  2. Execute Model.findOne({}).exec() for each input and store each result into a variable.
  3. At every findOne step for every variable, test if null. Return an appropriate http status code and exit if validation fails.
  4. Use the captured findOne result objects to update the Fields as required.
  5. Use myModel.save() to store the least impactful document first (e.g. a child array or ancillary meta data item). If that fails, return an appropriate http status code and exit.
  6. Continue the previous step until all updated Models have been saved successfully, then return the appropriate http code and any status message in Body or JSON.

I wasn't following these steps very carefully when developing a function that updated 2 documents with one API call, and it was tough to determine what the problems were when things weren't going as expected.

Commonly Used HTTP Status Codes:

  1. Bad input? User error so return HTTP 400.
  2. User not authenticated or doesn't have correct authorization? Return HTTP 401.
  3. Cannot find the DB items associated with the validated user inputs? Return HTTP 404.
  4. Cannot create a new instance? Probably a programmatic error so return HTTP 500.
  5. Everything executed without throwing, data is 'in hand' and/or the state is verifiably 'good' (expected)? Return HTTP 200 along with any expected return data/message.
  6. Everything executed without throwing and an object was added to the DB? Return HTTP 201.

Some more database lessons:

Findings about Server-side Cache:

Goals for Tomorrow:

Meeting with Ryan:

Friday 2-Dec-2022

Discovered MSFT Learning has beginner's videos about Java! Hosted by Brian Benz (@bbenz) and Mark Heckler (@mkheck) at Microsoft Learn - Java for Beginners.

Watched an episode of Azure Friday and took some notes. Not sure I completely understand what is going on here. Perhaps it would be worth looking in to and maybe applying to Lingo Bingo.

Completed some end-of-week tasks focused on accomplishments and improvements going forward.

In a CodeFellows channel, a member mentioned Advent of Code 2022, an 'advent calendar' of code challenges. I had put on my task list to take on a code challenge, technical-interview style, so I used that as fodder to do so. I failed the design portion miserably, but after opening a repl.it to work through the issues I realized my approach was not taking advantage of javascript's capabilities.

Some key takeaways:

Thursday 1-Dec-2022

These notes span both Weds and Thursday.

Explored Auth0's "APIs" feature. This could be helpful for enabling Auth0 to authorize access to parts of an SPA or Node app. For now I've backed-out of the settings and am moving on to other things.

For now, the authentication requirements are removed from my exploratory API server so I can concentrate on updating the schema models and get those working with the existing routes, web templates, and processing functions.

Some REST and CRUD takeaways from today's experiences:

Mongoose/MongoDB:

IDs versus Hash Codes versus UUIDs:

General Coding and Design:

Interesting reference:

REST API Tutorial website breaks the REST verbs down into easily digestable chunks.

These are now done:

Tuesday 29-Nov-2022

Worked through Ryan's latest PR and approved and merged it.

Continued API Server design efforts:

Completed goals:

The sign-in/out functionality is implemented but the Presenter User Stories paths haven't been fully implemented in the UI or in the routes. That will be a work in progress for a few more days.

Started adding models and middleware to the exploratory API Server:

Monday 28-Nov-2022

Did some looking for apps that would create an animated gif, hopefully really small in file size, of the LingoBingo website. I settled on ScreenToGif because it is pretty simple and straightforward. It is a Windows app though, and it wasn't able to make small enough files to be hosted in our GH repo. There are some options for how to host an animated gif and link to it that I will have to explore. Turns out the project is built in CSharp and is open source (perhaps something to look further in to, in the future).

Authentiation - Auth0:

Sunday 27-Nov-2022

Goals:

-[X] Re-watch WDS episode, uninterrupted. -[X] Review LingoBingo Trello and work on at least 1 card. -[ ] Implement caching on the API server demo. -[ ] Implement a sign-in and sign-out functionality to the API server demo.

Middleware:

Saturday 26-Nov-2022

Reviewed Azure Friday Episode: Azure Kubernetes VSCode Extension introduction. This short feature quickly overviewed creating, deploying, updating, monitoring, and managing a Node.js instance in an AKS (Azure Kubernetes Service) service.

Worked with Ryan here and there on the hamburger menu PR. Lots of progress made after a bunch of discussion. Somehow my local git got out of sync with the PR despite carefully pulling from the correct remote and PR branch. A quick clone to a new folder, git pull from remote PR branch, npm i, and npm start, and the code on my local was fixed. This is the 2nd time this has happened to me. I'll have to figure out how this keeps happening because it is causing interruptions in the dev and test processes.

I reviewed a Web Dev Simplified episode on quickly building an Express + Mongo API server. There are multiple good nuggets of information in there:

I'll need to watch it again and take better notes. There were too many interruptions to capture all there was to get.

Friday 25-Nov-2022

Ryan and I met for several hours to go over design and architecture details of our next planned version. We refined some of the work items in Trello and moved lots of stuff into TODO. There is more architecture to get sorted out though:

Had pretty good success developing API server path(s) and using Pug for forms-based interaction with the API server, interfacing the Mongo DB:

Wednesday 23-Nov-2022

Some things to consider when planning API Server development for LingoBingo:

Lots of learning new things today. Also, reminders of lessons from previous experiences. I'm not writing fabulous code out of the gate, but I'm pushing boundaries and getting further along building an API Server using my own resources. If I would have been asked "what is 'middleware' in ExpressJS" last week, I wouldn't have had much for an answer. Today this is different and I feel like this is something I can intelligently discuss with others now.

Tuesday 22-Nov-2022

LingoBingo setup stuff:

Somehow I couldn't recall how to do object destructuring so I looked it up on MDN. Simple: { param1, param2, param3 } = inputObject

Monday 21-Nov-2022

Back to Express, this time revisiting Forms, Jade, and Auth0. Will work on integrating with a database a little later.

Pug takeaways:

I posted an answer to a StackOverflow question that seemed to lack good answers, and it felt good to work through the problem, find a solution based on the original poster's code, and provide a structured, descriptive solution with a simple, tested code example. Hopefully it helps somebody. I had forgotten about being a StackOverflow member - probably because answers to questions are so common, and rarely is much additional information helpful (i.e. others that have answered have done a really good job). To update my profile, I added a slightly modified introductory statement, and inclduded a profile pic.

As I get ideas and find a few extra minutes, I will update Miro (and Trello) with LingoBingo JS features for v.next.

Express CRUD with Mongo Atlas takeaways (so far):

Sunday 20-Nov-2022

Continuing using express with postgresql from LogRocket blog. I was stuck on querying a single user by ID:

Some other takeaways from the ExpressJS + PostgreSQL exercise:

LingoBingo MVP is live! Currently it is hosted on Netlify using built-in "ITU Phonetics" wordlist. We plan to set up the back end for the next version, and it will take some time to flesh out all the details.

Saturday 19-Nov-2022

While getting the computers set up for today, I ran across some older C# project files, mostly during and soon after Bellevue College classes a few years ago. So many exercises and some clever solutions to problems are hidden in there! I recall having difficulties dealing with Chars and Strings (conversions, slicing and splicing, and regex operations) during Code Fellows. This was very frustrating because I felt like I had solved those problems before, but I couldn't recall how to do it. Takeaways:

I'm realizing that using the same Express server to explore and develop multiple features is getting a little complicated, so this weekend the goal is to create new Express servers for each single or limited number of features. This will force me to review the setup and install and implementatin processes, which should be good exercise.

Started working through a Log Rocket blog post using express with postgresql in a separate Express instance to quickly connect to a relational DB instance. It has been a while since I've done this so some of it is a little awkward. Hopefully this experience will help me when LingoBingo moves into post-MVP development.

Friday 18-Nov-2022

Reviewed current status of LingoBingo with Ryan. We have just a couple more work items to resolve and we are going to call MVP achieved! We will have more development sessions this weekend, most likely Sunday.

There were a few other tasks I had to complete today for my volunteer work. This slowed my progress with everythingn dev related, but at least those tasks are sorted out and I can move on.

While exploring Cookies in ExpressJS, I ran across a scenario that I haven't considered before: Using Pug/Jade templates to design a submittable Form. This led to an older blog post on 456Bereastreet.com that talks about including labels on forms for the sake of accessibility. Some key takeaways:

Continuing on, I found that there were intracacies of Pug and ExpressJS's Request and Response API's that I either don't have a good grasp of, or have otherwise forgotten how to use effectively, so I will need to review some of my prior work and de-clutter my learning environment to make better progress.

Thursday 17-Nov-2022

This week has been very busy. Unfortunately not all of it was busy in the ways I wanted it to be.

Worked with Ryan intermittently to get these last few PR's reviewed and merged in, and locate other last-minute changes necessary to meet MVP. We will meet on Friday to discuss the state of things and next steps.

I spent some time updating my profile on LinkedIn, adding links and some descriptions of current projects, revamping my intro, and creating a tagline. I still need to rework the resume a little bit. As the LingoBingo project comes to be useable, I'll have to promote that a bit more.

Today I spent a couple hours with Kevin L to look at purchasing equipment for the volunteer team's operations. We had good conversation and find a lot of agreement on the approach to interoperating between the agency and the volunteer team. Most of the budgeted items for this year were purchased. There may be networking opportunitites here in the future.

Also today I worked through some interview preparation tasks including refining responses to behavioral questions, considering what I want in a 'dream job' team and organization, and thinking up important questions I want answered as part of the interviewing process. These activities are helping me gain confidence in my ability to have a relaxed, productive conversation where I can put myself in a good light, and also determine if the prospective employer is one I want to work for.

ExpressJS has been displaying a warning whenever I launch the server. The message is "using form_post for response_mode may cause issues for you logging in over http...". In a development server, without a self-signed certificate, http is the way to go. Production servers would (of course) use a signed cert and leverage https. Since the example server I'm working on leverages Auth0, they have steps for running https in development, which should resolve the warning by implementing a reverse proxy (they recommend caddy). When running expressjs behind a proxy, 'trust proxy' must be configured, otherwise expressjs will register the incorrect 'client ip'. See Express Behind Proxies documentation for details.

Tuesday 15-Nov-2022

Spent lots of time working through LingoBingo PRs on my own and with Ryan. This was the focus for today.

Monday 14-Nov-2022

Much of my day was spent working on volunteer work items, to clear the way for trainings, meetings, and exercises in 2023.

Completed a code challenge, whiteboard session only. It took 70 minutes to complete all facets:

Sunday 13-Nov-2022

Completed Graph write-up, implementation, and full suite of unit tests. There are a few minor lingering items that I could revisit in the future as a means to jog my memory on this data structure and the algorithms used to traverse it.

Sorry Friday, it wasn't your day.

The Lingo Bingo project continues to move forward, and we are marching ever closer to MVP launch!

Saturday 12-Nov-2022

Met with Ryan on Lingo Bingo project and made lots of progress reviewing the Trello board:

Reviewed an Azure Friday video on using Mongo and Cosmo DB via a local, virtualized developer instance of the services. Very cool!

Thursday and Friday 10 and 11-Nov-2022

Thursday:

Friday:

Meeting with Ryan about project Lingo Bingo has been rescheduled for Saturday 12-Nov.

GitHub Codespaces Sounds Interesting!

CSS Animations can be tricky:

Wednesday 9-Nov-2022

More DotNET Conference 2022 video viewings and note taking.

SVG and Playwright were mentioned.

Completed some tasks for LingoBingo and prepped a test deployment of the latest changes to Netlify. Many of the tweaks I am encountering seem much easier to approach and deal with than in the past. :smiley: Progress! :fire:

Lastly, I spent some time tweaking the Screen Party animations:

Tuesday 8-Nov-2022

DotNET Conference 2022 starts today. Notes will be stored elsewhere.

Between interesting DotNET Conference sessions I worked on java-code-challenges, implementing a Graph class and requisite unit tests.

Monday 7-Nov-2022

Took some time out to respond to some interview questions before tackling Cheerio. It took much of the day to learn how to use Cheerio once I got an Express server running (which was key, really). Since I have been focusing on Express recently, I also reviewed the following packages since it was convenient to do so:

The one part of deploying Express that I didn't pay much attention to (but I should in the future) is using NPX vs NPM INIT and building by hand. The NPX initializer builds-out a deprecated templating library (Jade) and includes Express Router and lots of setup and sample files. This isn't a bad thing. In most cases though I think it would be good for me to build the server by hand and get more out of the experience.

Sunday 6-Nov-2022

Reviewing Express.js today:

Worked with Ryan on LingoBingo updates, PRs, code reviews... via GitHub, Email, and Slack. We are getting very close! He resolved several bugs and is moving things forward nicely.

While exploring Express.js and Auth0, I discovered Auth0 provides profile information for free. It's not a lot of info and really only includes the user name, locale, email, and an access grant token that is only used in the current authentication session. However, my exploratory Express server didn't have a way to display the data in a user friendly way.

Express.js and server-side HTML Key Takeaways:

Express.js Social ID Providers and Developer Keys:

Saturday 5-Nov-2022

Survived the windstorm and power outages last night and this morning. Back to it!

Attended a webinar by a Code Fellows alumni and ex-instructor re: CSS. Was well worth the time, and he was very good at walking and talking through what he was doing and why.

Walked through the steps necessary to deploy React Apps to Netlify and Azure App Services. Netlify is pretty easy just on its own, and deploying to Azure App Service is made super simple using the Azure Extension for VSCode. 9/10 do recommend! For LingoBingo we will plan to deploy "production" front end to Netlify, and back end features (API, DB, Authentication and Authorization, etc) to Azure.

Friday 4-Nov-2022

The local MongoDB installation needed to be removed from my main dev workstation, so that is now done. There were some Linux updates ready to install so I knocked those out too. After some additional research about Netlify vs. Azure App Service Web App. Before I do any more research, I need to deploy the LingoBingo website as-is to each and document the experience.

Next was to review Hash Tables. I keep forgetting about a few important Fields and Methods:

Pattern and Matcher classes:

Here's the suggested development pattern from Oracle Docs on Java:

Pattern pattern = Pattern.compile("\sword\s");
Matcher matcher = Pattern.matcher(Input_String);
boolean result = matcher.matches();

Thursday 3-Nov-2022

Finished off the Rotate 3x3 Matrix code challenge from yesterday. Added a feature where it would rotate other sizes including non-equal sized rows and columns, so long as the input matrix x and y are 3 or longer.

Walked through some documentation about deploying a server-side Node.js app to Azure. Documentation is pretty good and there is now a VS Code Extension (several actually) for Azure. It's worth noting that full Linux-based, Express.js server applications are supported, and MongoDB can be part of the Web App solution, too. This could work well for Lingo Bingo.

MongoDB (local installation) was not playing nice so troubleshooting and reinstallation consumed a bit of my time. It's funny that although Mongo Org has lots of great documentation, they are pushing pretty hard for users to just use Mongo Atlas...which is what I'm going to do for most projects going forward. I guess PostgreSQL will be the local DB platform for me? Maybe MySQL? We'll see.

Wednesday 2-Nov-2022

Took some time out to attend a Microsoft Reactor presentation on Rust (of all things). Key takeaways:

I'm not at a point where learning a new language is a productive endeavour. It is good to take the pulse of the dev world.

Back to deployment options for Lingo Bingo:

I found a blog article that talks about using Netlify Serverless Functions to talk to a MongoDB Atlas cluster, rather than rely on a back-end API: Netlify Serverless Functions with Mongo DB. It wasn't terribly good, but I understand the jist of how it works, and the numerous gotchas and limitations. Not sure this is what we are looking for.

After some additional research on deploying our React Site and a possible API Server w/ DB Access, I changed gears and completed a 40 minute Code Challenge - rotate 3x3 matrix by 90 degrees. This went fairly well, although the final code had a major bug it in. Analyzing the solution, documenting take aways, writing unit tests, and implementing (and bug squashing) the code was a good exercise. I have updated the 'java-code-challenges' repository with commits from this effort.

Tuesday 1-Nov-2022

Hard to believe it is November already. I took time out yesterday and today to brain-dump everything I thought I knew about Stacks, Queues, Linked Lists, Hash Tables, Graphs, Trees, and sorting algorithms. Sorting Algorithms is different in that recently not much time has been spent studying them. Given my experience with the other data structures and algorithms, I feel like it is a good time to take on a merge-sort algorithm and just see how far I can get on my own.

Key Takeaways - Problem Solving:

Key Takeaways - Java Coding:

Monday 31-Oct-2022

Saturday featured a communications exercise through early afternoon, and then family time for the rest of the day.

Sunday was a down-time day. I managed some documentation related to Saturday's post-exercise debriefing discussion, but largely it was an opportunity to decompress from a busy several weeks.

Today I had a late start and decided to work on yaml skills. My java-code-challenges repository in GitHub is a good candidate to explore yaml files and will benefit me in assuring builds build and tests are passing before merging into main. I've looked at YAML before and it had confused me (still does). Today I was able to make progress and defined 2 files: One for on push and another for on PR.

YAML key takeaways:

Resources:

Friday 28-Oct-2022

Attended a PPH Session today with a guy from Microsoft talking about his journey of 40 years in the tech industry, from C++ to Xamarin and C#, to Cloud Advocacy. Good session, enthusiastic guest, enlightening takeaways, and overall enjoyable. Turns out he has had a similar experience to mine, in having to leave a job due to a bad manager.

Spent some time reviewing Cheerio and the more I look at it, the more I wonder if this is something I want to get involved with. I will give it some more time, to see what it can do. Also, having some experience with it should help me gain the context necessary to help solve that (8 year old!) Issue they have sitting there.

Took some time out to sketch a REST and CRUD design for Lingo Bingo. This came to me relatively quickly including n-to-m relationships. We now have a draft outline of custom API server features, interactions with an external authentication service, a database service, and users based on authorization types.

Revisited ExpressJS to jumpstart my memory on how this all works. It's nice that it is such a small, simple thing, but there are a lot of libraries that can be bolted-on that make it (highly extensible and capable) difficult. :smiley: Key takeaways so far:

Last thing to note: Working server side is making me smile a lot. I am excited to move to this server-side portion of the project!

Thursday 27-Oct-2022

Today I spent most of the day working through some older assignments in the data structures and algorithms repo. Key takeaways:

I am celebrating my successess in updating these months-old projects. :fire: :firecracker: :fireworks: :grin:

Wednesday 26-Oct-2022

Sometimes challenges are designed in a way that the candidate is very likely to fail. It doesn't matter if the wording is imprecise, wrong, or otherwise misleading. The idea behind code challenges is to determine:

Here's an example of how to frustrate your candidate and see how they deal with it:

At any rate, it was fun to solve the challenge a few different ways. There are at least 2 other ways to solve the challenge but I am not going to pursue those today. I am glad I have the brain dumps, code, tests, and analysis to review in the future as I see fit.

Tuesday 25-Oct-2022

If I had an extra couple hours yesterday I would have completed implementing a CSS theme-selecting feature to Lingo Bingo earlier. This is exciting! I accomplished CSS magic with little help and lots of exploration and logically working through the problem on my own:

The idea to use a CSS Class selector came from css-tricks.com.

I reviewed my latest code challenge attempt and there are problems with the pseudocode and the slightly altered actual Java code:

  1. Character class is a single String character, but is stored as an integer. So when casting a char of an integer (lets say 23) to an int, the value of the char is returned instead of the character as an int. Instead of casting the Character class to an Integer, I should first cast Character to a String, and then to an Integer.
  2. Creating temp variables should be done with a purpose, meaning they need to be used sometime later, and probably destroyed. This needs to get corrected to be sure that temporarily stored value is used.

Monday 24-Oct-2022

We've been looking to find a font or three to use for the Lingo Bingo project. Some resources were added to the Trello board so I read the article about Roboto and took a peek at FontJoy to find some reasonable pairings. Will have to revisit this in the future with the goal of making a decision.

While researching hosting options for Lingo Bingo I found Azure to be a pretty capable. Looking at Heroku and Azure, it is clear that deploying a database server/service, storing the data, and dealing with transaction or request limits is much more expensive (and complex) than deploying a web app, desktop virtual machine, or some other services. Azure does have one benefit of having a pretty cheap SQL Server deployment tier that will consume some credits every month, but the capabilities of MS SQL are all there. It is possible that mutliple services will be used for example: Front-end webapp on Netlify and a back-end API with MongoDB in Azure.

More research is needed to review a few other hosting services to see what we might use, and what we should get ready for. RedHat OpenShift is so market-eeze that I can't tell what it might cost to use it, much less exactly what I'd use it for. Netlify is a known quantity, and as a front-end hosting platform it will only provide a part of the solution. Heroku has something called 'build packs' that support React, but are completely unknown (to me at this point). Heroku also has Add-Ons that will enable MongoDB access and other features, but my experience with those is they are supplied at a cost (although a minimal PostGresQL was available for Java-based deployments and was free, that doesn't help us in MERN-stack world).

I took some time out to look at Expressjs, since I haven't used it at all since May. It will take a minute to get back up to speed and I already have several other things to work on so I created a card to come back to exploring Expressjs in the near future, to support upcoming Lingo Bingo develoment tasks.

Sunday 23-Oct-2022

Dedicated a good portion of today working on Lingo Bingo. Ryan addressed the issue with the React-hooks which is great because I couldn't quite get it done. Instead, most of the day was spent working through theming issues. I still don't quite have what I want. At least there is a colorful, and styled website now that we can work with and is less... sterile.

Tomorrow I need to look at hosting options. Ryan had some feedback earlier today and I want to participate in the information gathering and decision making process. Looking forward to that.

Saturday 22-Oct-2022

Re-attempted a technical interview challenge see previous attempt notes below. I managed to complete all of the technical aspects of the challenge and came up with a sensible solution, but it took me 2.5 hours to do. A vast majority of that time was breaking down the problem in such a way that I could visualize a solution, as well as vocally and visually walk through solving the problem, before I could write pseudocode and actual Java code.

Key takeaways:

Turned my attention to LingoBingo for a bit to work out some theming issue. I don't quite have my head wrapped around this yet, but I feel like it is close.

Friday 21-Oct-2022

Took some time out to do a technical interview practice challenge. Key takeaways:

Completed 2 behavioral questions. There are just a few more that I need to write out responses to, then I can start a serious review and better prepare for interviewing.

Attended a presentation session on web accessibility. I was aware there are standards out there providing guidance to make sites, services, products, and software accessible, but I wasn't aware just how far along those resources have come. Check out the W3C for details about the WCAG (Web Content Accessibility Guidelines) at all stages during the software development process. Doing so will bring the site/service/product closer to compliance, but the main point is to design for inclusivity.

Saw presentations by Javascript Full Stack developers and they were using a package called inquirer. It is a command-line interface for Node.js. They were using it to administratively update database entries, and manage services running on their backend infrastructures. This could be useful in future Node and Express projects! Turns out the class was instructed to do their projects without any graphical user interface at all, and use AWS Services for CRUD, authentication and authorization, and build custom API servers to manage their data calls. They all did really well!

Went through the java-code-challenges repository to review properties, methods, traversals, and algorithmic complexities. There were a couple of errors, some points that needed refinement, and some reference links that needed to be updated, so I did that. Having that repository with all of the documentation included seems to be a good idea as I am able to easily review the information and refresh it in my mind. This actually raises my interest in coding, so it might be good to do these reviews earlier in the day so I can take advantage of that coding desire.

Thursday 20-Oct-2022

Continued research using React Hooks. Much of the documentation introduces the concept of Context and 'useContext' all in the same file. That's fine except those examples fail to demonstrate leveraging a defined context across files in a React hierarchy.

Key Takeaways:

Checkout this post on react usecontext hook by 'rw;eruch' aka Robin Wieruch.

Once I had spent a few hours with 'useContext' hook to get the hang of it, I took some time to work through some more CSS issues. Turns out there are areas where CSS and Bootstrap styling could be refined to make the GameBoard display more appealing. Right now it is a little weird in how the Tiles are sized and shaped, but the benefit of the CSS layout and using Bootstrap is the site is responsive to both desktop-sized and phone-sized screens.

I attended the Bellingham Codes Software Forum, where plenty of good discussion around building websites using React and javascript, among other things. Afterwards, I had more good discussion with Ryan, another attendee, about navigating becoming a software developer.

Some takeaways from the Software Forum discussions:

Wednesday 19-Oct-2022

Researching Theming in React has tough. There are several articles that are very out-of-date, using older React techniques, are too vague for new developers, or the backing "see my github repo for the code" doesn't actually exist.

What I did learn is using React Hooks is a thing, and it could be helpful in creating themes for a React website. I started documenting some react hook takeaways for reference.

React Hooks uses concepts that are pretty familiar, now that I am gaining a basic understanding of the design patterns of Hooks:

About 'Array.prototype.reduce()':

// from mdn.org Array.prototype.reduce() documentation
const array1 - [1, 2, 3, 4];
const initialValue = 0;
const sumWithInitial = array1.reduce(
  (previousValue, currentValue) => previousValue + currentValue, initialValue
);

Step Through:

Tuesday 18-Oct-2022

Finished CSS cleanup from yesterday and built upon that by submitting a new PR to the Lingo Bingo project. Some display bugs were solved and general rules like avoiding in-line CSS and using classes or Bootstrap were implemented. The project is looking better!

Next step is to finish working on devloping a theme for the color scheme. For now the effort might be overkill, but in the long run it will simplify implementing alternate themes, and perhaps user-configurable ones. Not an official feature right now but will be good experience to have.

Monday 17-Oct-2022

Took a little bit of a break over the weekend. Some development and exploration was done, but not at the level of the previous month.

Put some effort into learning CSS Variable usage:

I'm thinking there is probably a more robust way to implement this to simplify applying a theme to an entire webapp. Looking more into this subject, I started to see some style issues in the Lingo Bingo project, so I worked on fixing those. Some key takeaways recorded on Sunday September 3rd.

I also watched a video where a guy developed a javascript version of the Minesweeper game. It only took him 55 minutes (of video time) to get the core elements of the game working, including a UI. He jumped back and forth between whiteboarding and coding, so it was interesting and inspirational!

Friday 14-Oct-2022

Attempted a code challenge "convert integers into roman numerals". This was very difficult and I ended with a partial algorithm and will need to attempt it again.

Attended a seminar on DevOps and AWS. Was very interesting and help re-kindle my interest in working with AWS, like in the Java 401 class.

Key takeaways:

Tailwind CSS was mentioned again with lots of positive feedback and kudos. I have that on my list of things to investigate.

Ryan and I updated some Lingo Bingo code and some PR's were merged in. So I moved forward with the "screen party" feature implementation. So far the integration of planned code into the gameboard was not too difficult. There is more work to do in the next few days to make it more awesome!

As of right now, I have a streak of a solid month of contributing code to GitHub. Some of that is due to my endless typing in this retrospective markdown, however there are definitely some significant code updates and project completions:

I took a look at a few blog articles about theming, and it is pretty invovled. It might be worth the time to look for a package that will manage theming and end-user-selectable theming. Until then, a baseline theme using CSS will be implemented, and I will consider what to do about theming longer term.

Thursday 13-Oct-2022

Monitored MS Ignite sessions again today. Notes are stored at MSIgnite 2022 Notes.

MSFT has done a lot of work to enable remote development, and IT management of remote development resources, via the Azure cloud. Although it is very Visual Studio-centric, they did demostrate Maui features (cross-platform build, hot-reload, and an android emulator).

I completed a React-Tac-Toe challenge: Highlight Winning Tiles. I updated the blargh article where the challenges are listed. Takeaways:

Wednesday 12-Oct-2022

Watching Microsoft Ignite 2022 this morning, looking forward to hear what is next from Microsoft.

GitHub Universe is set for November 9th and 10th 2022.

Git tid-bit:

git commit -c {id} allows updating a commit message for a commit with id.

What is an OKR? Objective and Key Result. OKRs enable setting and communicatingn goals and milestones.

During the break in MS Ignite sessions I worked on LingoBingojs. I updated information on a PR so that my partner could make some tweaks and the PR could be incorporated to main. We're getting pretty close to first MVP!

Quite by accident I bumped into cheeriojs/cheerio, an open source project that scrapes web pages and returns a tight, scaled-down DOM. ikatyang's emoji cheat sheet utilizes cheerio to create the list. Turns out there is a 'good first issue' item in the Cheeriojs repository, so I forked it for future inspection. This could be a good next opportunity to contribute to the OSS world.

Back to MS Ignite, David Fowler and Damian Edwards shared some interesting ASP.Net 6 and DotNET 7 preview code and features. In the past, these sessions have been difficult to track, but with Code Fellows training in full-stack web development, the terminology and features they discussed were consumable and interesting. :fireworks:

Tuesday 11-Oct-2022

Another poster added a link to Jake Archibald's blog page that discusses CORS in historic detail. It's also pretty humorous. Key takeaways are stored in cors-review. Key takeaways for right here:

Monday 10-Oct-2022

Seems like using this.setState((prevStat) => {}) will alter the developer's approach to updating State under certain circumstances. For example, if a collection of items is already a property of State, and another property changes based on that collection, then updating the second property will not be possible in a single setState call.

Some resources to review:

Turns out the work around is to just call this.setState({ item: {value based on otherStateItem ,}}) and it will work. My gut sense tells me that there are probably better ways to manage state than this, but I don't have concrete evidence to support it.

Many tests I wrote for the project were using lots of .forEach() statements and creating lots of arrays to store JSON data. Ryan suggested moving to a more object-oriented approach so I refactored the Jest files. While doing that I realized he could have meant doing something a little different, so I posted what I did and asked him for feedback. In any case, I learned:

Using '.find()' makes the code a litte bit longer horizontally, but from a readabilty perspective it is pretty good, and it hides the ugly iteration detail.

Sunday 9-Oct-2022

Reviewed some of Ryan's code for the LingoBingo project. He's working on a play again button, so I reviewed the code, pulled in his changes and ran them, and sent him some feedback. That functionality will definitely be needed but it's not fully baked yet.

On Friday I experienced some anxiety figuring out why some of my Jest Tests were failing, and others would appear to hang. There are key takeaways for Friday that cover most of the items but there was one remaining question: Do Jest Tests run in parallel? Behavior of npm test output and the errors I was seeing suggested that was the case, and today I verified it with some internet searching. According to www.oreilly.com and GitHub Facebook Jest issue 5818. A read through provided some detail on how Jest operates.

Key takeaway on Jest parallelism:

Assume Jest will run your tests in parallel. It might not, but unexpected side-effects will happen when assuming otherwise.

After integrating my calculation components into the Lingo Bingo React project, it became clear that one of them needed to carry more weight, and provide better output, so I refactored it. This meant that the Jest tests had to be updated. This work is incomplete as of the end of tonight, so I'll pick it up tomorrow. Takeaways?

Saturday 8-Oct-2022

Today I worked through writing the basics of a Graph Data Structure, and the traversal algorithms. I found an interesting slide deck for a computer science class at the UW CSE 417: Algorithms and Computational Complexity that was helpful. It had an interesting quote from Walter Ruzzo, Professor of Computer Science & Engineering and Adjunct Professor at the University of Washington.

"Never write an argument you are not convinced in because this may damage your brain." [Ruzzo]

Some key takeaways:

Friday 7-Oct-2022

There are a couple of presentations I want to attend early this afternoon.

First was refactoring: How and why. In essence, code smells will appear for many reasons, and it is important to try and refactor code to remove the code smells, making it more easily readable, less prone to bugs, and better performing.

Started working through Lingo Bingo logic to determine when a Bingo has been attained. This will be in a dev branch and can get refactored and reworked as necessary.

Key Takeaways:

Thursday 6-Oct-2022

Bitmap Transformer Project: It took a bit longer than I thought it would, but I completed this project today! While writing up method descriptions I realized many methods were too busy, and some basic checks were not being done at all, or not very well. Also, while writing unit tests I realized there was some logical processing flow that didn't make sense, so some refactoring had to be done.

Key Takeaways:

  1. I should have worked through the bitmap support problem I ran into rather than just moving to PNG. Not a big deal, but it does raise a question about the name of the app.
  2. The Main entry point is a static method. That means instantiation is not required for entry. Other methods that App needs might need to be non-static, so take that into consideration when building a console app.
  3. In hindsight it would have been better to do more design planning for this project, and the general flow would have been better. For example, a better naming scheme for methods, and the order the methods needed to be called, and when the app would exit, would have been better designed.
  4. Exception handling was, exceptional, in the busy sort of sense. If I was to do this again I would try to track exception handling paths better so they were easier to track and manage during dev and test cycles.
  5. Building the app to run in IntelliJ IDEA is different than producing Artifacts (JAR files and etc) for executing in a shell or terminal environment.
  6. Gradle is a different beast. It is easy to forget the requirements to get initialize, build, test, and run a project properly. Review notes in bitmap-transformer and other places to get through these challenges.
  7. Working with graphics is complex. Lots of math can be involved, and the existing Libraries in Java are not documented to my liking. At least docs existed and it was good that I found some example usages online and leveraged that code, then refactored it to apply to this project.
  8. A good hands-on test is to re-use the same file over-and-over when reading and writing files. Running Bitmap Transformer JAR against a bitmap file multiple times would fail after 1-2 transformations. Not sure why, and don't plan to persue it at this time, but this is something that could happen on other projects where file Create, Read, and Update operations are performed.
  9. REGEX can be a beast! I know this, but it got me again in this project. I have to step very carefully through the capture requirements and filtering in/out specific character and groups of characters in strings. It is easy to make a REGEX that is too complex for the problem at hand. Use REGEX101 and throw all known pass and fail garbage at it so it is clear what my defined REGEX string might actually do in a Pattern Matcher.

Behavioral questions: I addressed two of these today. One was a revisit, the other was one I hadn't responded to before.

Working through some Java concepts in ReplIt, I discovered that replit isn't really a great place to sandbox Java code. It seems to be unaware of basic Java libraries like Pattern and Matcher classes. So instead I spent a little time fiddling with JS arrow functions.

Key Takeaways about Arrow Functions:

An example of what I threw together can be found on ReplIt.

Wednesday 5-Oct-2022

At this point I've deployed a new React website a few times. If from here-on-out I continue doing React Web Dev, I'm sure it wouldn't be an issue to know how to deploy a new React site, or add React to an existing one. However, right now I have many different tasks on my self-assigned plate, from web dev, to Java dev, to software design, project management, and algorithm studies. This makes it difficult to be an expert in any one area, and I recognize the power of knowing React and web development so it is important to have some key takeaways to look back on.

React Deployment Key Takeaways:

The Syntax podcast mentioned CORS and CORS-related issues, so I took some notes. This lead to writing a new article about CORS so I could easily reference it later. This could help helpful on future web projects such as LingoBingo and other project ideas I have.

My attempt at a 40-minute technical interview challenge ended with timer expired before I could finish writing java code. Completing the code, then writing about testing approach, and of course Big-O were necessary to ensure points capture. Later, this item will be added to the Java Code Challenges repository (just like the others) and must be re-attempted at a later date.

Since I had a little time before lunch, I responded to a few sample behavioral questions. These are slowly getting easier to respond to. I feel like they are less burdensome, and more like an opportunity to share my story of who I am and what I can do for a potential employer.

Back to CSS Animations:

To experiment with CSS Animations, I created a ReplIt called React Css Animations.

Before the day ended implemented the technical interview challenge in my Java Code Challenges repo. My pseudocode solution really wasn't all bad, but it was lacking some simple bad-input checks. I still have a question about whether in a Kary Tree if checking across a "holey children array" could produce a Null Pointer Exception. I don't believe it would. That is something I'll have to explore some other time. The final solution, with a Kary Tree anyway, is all completed, unit tested, analyzed, documented, and checked-in now. Code implementation was pretty fast and very few lines, so I must have done something right. :smiley:

Tuesday 4-Oct-2022

Back to the bitmap transformer project! Had I taken time to look into BufferedImage class back when I first did this assignment, I probably would have been able to complete it, or at least get one transform done (instead of none). Key takeaways:

If I ever want to show some regex skills, I'll need to become more familiar with Pattern and Matcher classes in Java.

Multi-use:

String inputParam = "I contain letters and spaces.";
String regex = "[a-zA-Z]";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(inputParam);
boolean result = matcher.matches();

Single-use:

boolean result = Pattern.matches(regex, inputParam);

Note: The Oracle Java docs have a special set of REGEX rules that are slightly different than what I've seen elsewhere (e.g. regex101).

Responded to a behavioral interview question. This was in interesting one because it is basically asking what gets me exciting about software development. The basic answer is: solving problems, and watching unit tests pass, proving the problem is solved. There is more of course, but that is in the details of the answer I drew up and will refine.

Final set of takeaways:

Last couple TODOs for the bitmap-transform project were completed on October 6th:

While I was checking in to a couple of ham radio nets, I decided to take a peek at the NWS API. Key takeaways:

I added some comments to my "Practice Boards" in Miro, as well as some added Cards and details to Trello for future projects based on using NWS API.

That will be it for this very productive day!

Monday 3-Oct-2022

Updated the Trello and Whiteboard documentation for the LingoBingo project with ideas sparked from yesterday's conversation, and whatever occurred to me overnight.

In one of the forums I follow, a user is asking if folks are interested in learning about Streams...which is on my list of things to do, so that could be a nice additional resource!

Back to LingoBingo, I added a 'session' component that is used to get data and prep it for a gameboard to consume. The gameboard handles the display and click event and no longer has to manage importing the word data. This fixes a problem where clicking on the gameboard would reload all words.

We are going to have to figure out how to manage "Host" users vs. "Player" users. There is no decision on this just yet. A couple of ideas on how we could approach it:

  1. Implement registration, authentication and authorization, and a profile page.
  2. Create a Host landing page to just frame-in Host-only operations like importing a word list, assigning a category, and generating a link to play the selected category in a game.

Key takeaway: Trust myself a little more when it comes to solving problems related to React State.

Code Challenges: I discovered that my solution to "Is Anagram" challenge was not quite right. Turns out the input was to be 2 strings and the comparison is whether they are anagrams of each other. I might take on the challenge of fixing that in the near future.

I attacked another React Challenge: Add a toggle button that lets you sort the moves in either ascending or descending order. See entries from about 2 weeks ago for the full list and images of results.

Key takeaways:

On to Java Code Challenges! Reviewing the isAnagram solution, it turns out I solved the palindrome problem instead of the anagram one. Granted, a palindrome is an anagram, there are a bunch of use cases that won't get solved by the isAnagram method I created. So I completed an update to the java code challenges repository that addresses that problem. There are now two classes - one for the Palindrome problem, another for the Anagram problem.

Takeaways:

Also, when thinking about using Hash Table, recall that it:

That's it for today.

Sunday 2-Oct-2022

Met with my project cohort and reviewed the Trello board work items, updating and closing a few of them. There is a lingering issue of the full-page refresh when State is updated. Normally that wouldn't be a problem except the refresh causes the words to randomize again, which is a bug. We think that changing the location where the wordlist is imported and randomized will fix the problem, so I'll work on that and see what I can come up with. Ideas:

  1. Move the state to the level above the Gameboard. This makes sense from a few feature perspectives.
  2. Store the organized words into state and recall them once they are there, rather than from the randomizer.

Saturday 1-Oct-2022

I spent some time figuring out how to install, configure, and utilize Jest. It's not that difficult really. Some key takeaways:

Jest supports:

I set up Jest on the Lingo Bingo project and submitted a PR with a couple of test files pointing to the purely functional modules. From here on out, it would be good to get unit tests written to any new PFM's, or any updates to existing ones.

Friday 30-Sept-2022

This morning I attempted another technical interview question and could not get code on the board before 40 minutes was up. I believe the overall design is close, but there is definitely a problem with the iterators and indexing. Using a Stack seems like a great idea though.

Key takeaways:

  1. Remember that the Stack data structure has a Peek() method and an isEmpty() method. Be sure to consider their use and how they can help solve the problem at hand.
  2. When I'm struggling to deal with "cutting an array in half" and "iterating through the result(s)", just start drawing out an odd-count array and an even-count array and work the problem until it is solved. Do not just skip over it because it will bite later on.
  3. Developing a Stack's Pop() and Push() methods requires careful operation, depending on how many items (if any) are already in the Stack. Push: More than One? Only one? None? Pop: None? One? More than One? ...in those orders.
  4. When a method needs to raise an exception that means: specify the exception in the method declaration using the throws keyword.
  5. Before implementing generics, just use Object. Yes, un/boxing and various Casting calls will be necessary, but this will allow developing the solution rapidly, without getting hung up with Generics.
  6. When thinking about unit tests, especially with data structures that have linked Nodes, remember that an empty structure, a structure with a single item, and structures with few or many items may have slightly different behaviors, and those "boundaries" should be tested and are not really optional.
  7. Java's Char class does have Character.toLowerCase(char) but it is a little different than String string = character.toString() followed by string.toLowerCase(Locale.ROOT). This might be worth reviewing a few times to get the hang of.
  8. Dividing an integer by 2 may cause a rounding error. I need to refamiliarize myself with what happens: Does it round UP or DOWN? (to be continued...)
  9. It is okay to pseudocode lots of placeholder variables that in real code won't be necessary (and might even be confusing), so try not to worry about that while tackling a technical interview question.

This afternoon was a presentation by a Code Fellows alum and previously an instructor. She discussed the importance of, and how to work with, ambiguity.

Key Takeaways:

Ask questions to:

Well, that's time for today. Many other tasks stood-by while I got this sorted out, however these challenges are forcing me to break-down problems into very small parts, and think through solving each step in a sensible way. Back at it tomorrow!

Thursday 29-Sept-2022

I started today completing some housekeeping tasks - literally - so no technical work or exercises were completed this morning. At least the house and yard are a tidied up a bit.

Back to the Java Code Challenge: Browser Navigation History. I completed designing, implementing, and testing enhanced versions of Go, Forward, and Back methods. Confusing elements:

  1. Using a linked-list, it is most effecient to insert a new node at Head, so moving 'forward' through history move toward head.
  2. Moving foward through history means decrementing an index or traversing previous Node references (counter-intuitive).
  3. Chrome's Forward and Back buttons have a different "view" of the Browser history than Chrome://history! Figuring out which to follow (and why) caused me to develop 2 solutions to the code challenge.

In retrospect:

There are a bunch of tasks now in my Trello board, one of them I haven't touched for several weeks: Java Project 'bitmap-transformer'. I'll take a peek at it and try to knock out something small before the day gets away from me.

First things first: Can I build it? No, not with gradlew...and a few adjustments.

It took a while but I started to figure out how the ImageBuffer class works, and the RGB / ARGB properties are handled internally. So I refactored and added to the existing code. Good news is it doesn't crash, and the arguments input to the App are accepted. Next step is to debug and find out why the output file is not written to disk. After that, find out if the image is changed at all, and if not, why not.

But that will wait until tomorrow.

Wednesday 28-Sept-2022

There are never enough hours in a day:

Of course this is nothing new.

This morning I knocked out a couple behavioral questions. One of them was asking what I aim to accomplish in my first 30, 60, and 90 days on a new team. Generally speaking there are things I can talk about. Without knowing anything about a company or team or code base, the answers are going to be fairly unrealitice -- although the general concepts around what is important as a new dev on a team should be well orientated. This speaks to actively reseraching companies I am interested in. Soon I will need to return to doing this as I am increasingly excited about my next big thing and look forward to getting underway!

As for the Browser Navigation History challenge in my Java-Code-Challenges repo, I decided to approach implementation from a test driven development perspective. Although I already have the algorithm written, the code is not. As I write the code I want to be able to run the tests and modify the code to make the tests pass. I made a good amount of progress and discovered that there are a couple ways to implement solutions to this challenge. Once I was done writing and testing the algorithm I designed in Miro, I started planning an "enhanced" version of the methods that would solve the problem, matching the behavior of "Chrome History" a little more closely. It will take me into tomorrow to finish designing, implementing, and testing that code.

Tuesday 27-Sept-2022

First stop was to pick-up where I left off with CSS Animations. I have a video from Web Dev Simplified to watch, some more experimentation in the sandbox Reactjs site to do, and some emojis and/or thumbnail images to make.

I completed a couple behavioral questions and am starting to think I need to re-think how I respond to these so that when the time comes, I have realistic answers to use with tie-ins to who and how I am.

Code challenge: Haven't quite got there yet!

CSS Animations: I updated my current exploratory ReactJS project and things are working with images and emojis. So far so good! Repl-it has a React template now, so I refactored the code into that environment and it works, so I'm doing something right.

I spent a little extra time exploring Hashtables to wrap my brain around the expectations of these technical interview questions. I'm pretty sure I have the technical aspects of these data structures. The issue is probably two things:

  1. Understanding when to use them.
  2. Boiling them down to a simplified explanation, without going into the weeds.

The impetus for that second point come from reading my README file about Hashtables and the Repeated Word challenge, and one of my takeaways from yesters: Don't waste time implementing those 'already implemented' structures and instead use an existing language library. Given the 1st point above, I should be able to talk my way through what I would be using, why, and how.

So I attempted a new 40 minute code challenge and time expired before I could complete writing Java code. I did manage to write out the problem domain, review inputs and outputs, depict the problem and step through it for 1 test case, write an Algorithm, supply information on my test approach, and perform Big-O analysis on the Algorithm. I'll do further analysis at a later time and code up the correct solution in my Java Code Challenges repository soon.

Since today is coming to a close, I updated my Trello board and noticed I was missing a few things. So I added key tasks and aspirational activities that were already on my mind and one of them (Bitmap Transformer project) that wasn't listed at all. This way I can better track my todos, and 'imdones'.

Monday 26-Sept-2022

Today I started out working on a technical interview challenge question. This time the question was to make a function that accepted a String as input, and returned true if all the characters in the input string were unique. This time I was unable to complete all of the Code Fellows grading rubric items within 40 minutes, but that's ok. I was on the right track, implementing a method that uses a hashtable. Had I not spent so much time writing out the hashtable functionality during design time, I probably would have completed coding and a step through. Commonly, I pick the wrong level of detail (usually too much) for situations like these, and that is what happened this time. Another issue was I couldn't remember how Java's String methods were used to a) replace characters, and b) split a String into a character array. After the time was up, I opened up a new brach on my java-code-challenges repo and built-up the solution starting with my whiteboard notes, and going from there. Within about 2 hours I had a working solution, fully documented, with a full suite of unit tests.

Takeaways:

A detailed readme with code analysis and links to the code and unit tests can be found in the java-code-challenges repo.

Next up was behavioral questions practice. This really didn't take very long and I probably should have done 1 or 2 more, but there was an event coming up.

The event was an Ops-301 final presentation. The students did really well, and it was interesting to see how they were solving problems like securing a network and wifi connectivity using VPNs, a capture portal, and AAA at the perimeter.

Following that, I returned to CSS Animations. The goal is to learn how to make an animated "celebration" happen on a web page under certain conditions. I'm going to need several things:

  1. Knowledge of and experience with @keyframes and animation properties in CSS.
  2. Some emojis and/or small thumbnail images or drawings representing fun party stuff (party poppers, streamers, cake slices, lollipops, etc) that will be animated on-screen.
  3. A design for how this will be implemented in the LingoBingo project.

I made a little progress by deploying a new ReactJS website to use as the experimentation sandbox. More to do tomorrow.

Sunday 25-Sept-2022

In my collaborative project 'LingoBingo js', there is a need to design an animation that happens when a user gets a Bingo. This is going to be a design challenge for me, since that is not my forte'. So to warm-up to the idea, I opened up cssbattle.dev, battle number 2, item 17. The image is somewhat complex:

Key takeaways:

Next I completed CSS Battle 2 Challenge 18 "Matrix", earning 600 pts for a 100% match... but it took 834 characters to do it. It makes me wonder:

My initial idea was to use Divs with the ::before and ::after pseudo elements again, but I was concerned that I couldn't leverage property inheritance that way (may I can and I don't know it?).

I stuck with Divs and used a class hierarchy to identify the 2 colored shapes, each column, and each row. I then applied position: absolute, transform: translateX(), and margin-top (for Y translation) to position every div specifically.

To Dos:

  1. Investigate how to iterate using CSS.
  2. Investigate if it is possible to apply property inheritance in pseudo-elements.

One more challenge before I quit: Battle 3, 19 Cube. This was really tough!

Key Takeaways:

I'm still not entirely sure I know the size of the center diamond shape, so it is extremely difficult to get the positioning right!

Nevertheless, I did complete it with a 99.9% match, 598 character score! That's pretty good considering how little I have used rotate and skewx/skewy properties.

Saturday 24-Sept-2022

For the last several weeks I have wanted to work on my desk a bit. There are USB and audio extensions that were just hanging around on and about the desktop and it was... messy. So I took apart the dual-monitor mounting system, added the USB + Audio line housing to the foot of the mount, and put the system back together. While I was behind the desk I added a second power stick to shore-up power cables to the monitors and a few other things, and cleaned-up the USB, audio, and D-port cabling so everything is nice and tidy now. My Uplift desk is so good.

I attended a seminar by Mica Goebig, where she discussed confidence issues, as well as managing fear and self-doubt. Her business is geared towards women, poc, etc. Her advice in this session was easily transportable to just about anybody. My takeaways to boosting my confidence are:

This afternoon I put some time into the Lingo Bingo JS. Although development has slowed, I am completing tasks one-by-one, successfully, and things are coming together. Some things that went well:

Some things that need improvement:

Friday 23-Sept-2022

Back to React! Some key takeaways when developing a site that requires some initial processing to display a page:

On another topic, some of my Code Fellows student-friends are at their 401-level finals week. I won't be able to see it live but I'm looking forward to seeing a video of what they did!

Thursday 22-Sept-2022

Worked on React again. Had some difficulty figuring out how to pull-in data, process it, and then set it into state. When setting State the Component reloads, causing timing issues. I should have been concentrating on passing functions as props anyway (that was more the goal), and handling the input data properly to begin with. In a future revision of this project, there will be a back-end API server that will manage gathering the correct data, processing it, and returning a data set that can then be set into State.

Code Fellows held a Code 401 Instructor's Forum this afternoon. These are always fun, and are chock full of reminders about what the classes have to offer (and what I learned taking Java 401!). Also, the banter between the instructors is pretty good. Someone usually has a good tid-bit about the industry, new hot frameworks, or tips around contracting or freelancing.

Speaking of which: I'm interesting in learning a little bit about Tailwind C S S. This has been added to my list of things I want to learn more about.

Lastly, I worked through a couple behavioral questions this morning. It is getting easier to write these. I need to remember to speak these responses out loud so I get used to hearing the question asked, and hearing myself respond. During several of the Code Fellows class sessions, it was pointed out that having ready-to-go responses to many behavioral questions is good preparation for interviewing. The practice helps to releive anxiety, and makes for a more natural, relaxed, and focus response.

No code challenges nor technical interview practice sessions were done this week, and it isn't likely I will get to them before this weekend. The plan is to get back to knocking out 1 of everything every day as much as is possible. Keeping a busy schedule with productive, impactful tasks will help me in the in the long run.

Wednesday 21-Sept-2022

React challenges, continued!

I completed the challenge of making the currently selected move text bold (see the checklist below for a screen snip). The code was fairly easy, but it requires an understanding of the backing State and data, and also an ability to leverage boolean logic to select and apply CSS to an element.

<button
  onClick={() => this.jumpTo(move)}
  className={this.state.stepNumber === move ? 'selectedBold' : ''}
>
  {desc}
</button>
.selectedBold {
  font-weight: 700;
}

The next challenge proved to be much more difficult, but I finally figured it out. The Board component had a hard-coded render statement that explicitly set the row element and each "tile" element, and the challenge was to convert that into a pair of loops that would generate the tiles on the fly, instead. Scroll down to see the challenges and the solutions.

In summary:

  renderSquare(i) {
    return (
      <Square
        value={this.props.squares[i]}
        onClick={() => this.props.onClick(i)}
        key={i}
      />
    );
  }

  setRows() {
    const rows = [];
    for (let rowId=0; rowId<3; rowId++){
      rows.push(
        <div className="board-row" key={rowId}>{this.setTiles(rowId)}</div>
      )
    }
    return rows;
  }

Tuesday 20-Sept-2022

Reviewing React facts and usage this morning, here are some key takeaways:

Arrow Function used for an onClick event: onClick={() => this.setState({value: 'X'})}

Passing a function via props:

// in the parent class
handleClick(i) {
  const squares = this.state.squares.slice();
  if (calculateWinner(squares) || squares[i]) {
    return;
  }
}

// in the parent class render statement
<MyComponent
  onClick={() => this.handleClick(i)}
/>

// inside MyComponent
<Button
  onClick={props.onClick}
  >Click me</Button>

React-Tac-Toe

Here is a neat little React js tutorial, and at the end some code challenges are posed. I started working through these because I was feeling like I was a little too rusty with React to make effective progress on the Enigma Bay project.

Sort button added to game output > Sort button clicked sorts descending history

Highlight three squares that caused the win


Monday 19-Sept-2022

Put some effort into the javascript project today. Some key takeaways follow.

React:

  1. Use React Function Components as much as possible, unless a Component absolutely needs to maintain its own State, then it should be a Class Component.
  2. React Function Components are just javascript functions, so adding a parameter to the function allows the function to utilize it as input.
  3. Avoid chaining the input parameter(s) within the Functional Component code blocks... they are read-only.
  4. React Function Components are simple, and must contain a return statement.
  5. React Class Components must extend React.Component and have a render function with a return statement.
  6. When defining props (in a functional component for example), remember to set the PropTypes at the end of the Component to avoid type mis-match errors. See the example code below.
// import statements
import PropTypes from 'prop-types';

export default function MyFunction(props) {
  return <div className={props.styleclass}>{props.message}</div>;
}
MyFunction.propTypes = {
  styleclass: PropTypes.string,
  message: PropTypes.string,
};

React State and Lifecycle, react-js documents

Components and Props, react-js documents

Type checking with PropTypes, react-js documents

Bootstrap:

  1. Bootstrap and react-bootstrap have built-in color themes.
  2. Color themes can be applied to bootstrap components fairly easily, like with the Warning, or by using the SASS Theming system on just about any element.
  3. It is possible to use your own colors and backgrounds on Bootstrap components, just as you normally would using CSS and your own elements.

Color customizations and theme system, from getbootstrap.com

CSS:

  1. Remember display: flex ? Then remember to also set 'height', 'align-items', and 'justify-content' in the parent container to make your life easy arranging content in the child box.
  2. Be careful with class naming schemes and multiple CSS files. Class names can clash and produce unexpected rendering. Remember, importing multiple CSS files ends up creating one large CSS file under the covers.
  3. Enable CSS variables to do stuff like create a single CSS file with all the theme-based color designations (see example below).
:root {
  /* selects all elements */
  --primary-main-color: #12ae55;
  --secondary-main-color: #0055ff;
  --shadow-color: #112233;
}

To use these variable colors just call them using the 'var(--named-variable)'.

element {
  color: var(--primary-main-color);
}

Using variables in css from MDN web docs

Friday 16-Sept-2022 thru Sunday 18-Sept-2022

Wow did this week go by quickly, I can't believe it's friday already! Earlier this week I tackled another Java Code Challenge. It actually tackled me, so I had to do some research and due-dilligence to figure it out. Essentially the problem was I did not identify the correct data structure, or rather I picked the correct data structure but for the wrong reason and so I couldn't determine how to utilize it within the time limit.

The challenge is basically this: You are given a book's worth of text, and you must write a function that processes that String input to return the most commonly encountered word (the first one if there are many).

For example: Input <= "The quick brown fox jumped over the lazy grey cat."; Output => "the".

There are probably 2 or 3 really wrong ways to solve this problem that are inefficient, difficult to code, and probably hard to test. The correct solution involves using a hashtable. Where I got stuck was determining exactly how the hashtable could help me get the right answer. I wrote a custom hashtable with a custom Linked List as Buckets to help solve this problem, but had to sleep on it to come to a legical, working solution.

So this experience spills-over into Saturday and Sunday, delaying work on other things I really wanted to do, but this is important if I ever want to be an effective software developer.

Key takeaways:

  1. When a code challenge requires String input, a whole host of questions should be asked of the interviewer to try and hone-in on a viable solution (and buy some time for the creative problem-solving juices to flow). For example: Does case-sensitivity matter? How about punctuation - is there a difference between 'cat' and 'cat!'? What about whitespace and null or empty string characters, should they be ignored or are they somehow important to the output? Answers to these questions (and more) will help bring to light the amount of additional processing the algorithm might need to do to the input.
  2. Code challenges that state an input will be a String, or a Collection, might have some requirement to process those inputs. Remember to consider a String input could become an array of items in your algorithm, in order to better deal with the input.
  3. A code challenge that asks for a comparison, inclusion or exclusion (uniqueness), should immediately become a condidate for Types like Hashtable or Set. These types were developed to find and properly manage unique items.

More takeaways, about hashtables in general:

  1. Buckets are each comprised of a LinkedList, which will be initialized and isEmpty() == true upon hashtable instantiation.
  2. LinkedLists might be generic, or could be predefined to hold specific values or types. In any case, that needs to be abstracted away, so that LinkedList Nodes are simply part of the operation of a LinkedList, and callers do not need to try to utilize Nodes directly, only the functionality the LinkedList exposes (Add, Contains, Find, Remove, AddBefore, etc).
  3. Even with a large sized backing array, the hashing function could still result in a duplicate Key index. A good hashtable algorithm will abstract that situation and do the right thing to the right item. In the case of an Add, the Bucket will insert a Node; In the case of Find or Get, the Bucket will return the correct item from the LinkedList, whether there are 1 or multiple Nodes in the list.
  4. Remember that hashtables won't answer the question as to how many items have been de-duplicated, but they can be used to find out, given a stream of inquiries and by interrogating the results from hashtable.has(item) results.

Administrative Stuff:

I added an entry to the Linux learnings documentation - how to keep MAN output in the terminal scrollback. While I was in there I cleaned up a bunch of text formatting that was just terrible. Not a great use of time I suppose, but it was a nice change of gear from code challenge solving, code planning and writing, and brain-dumping during and after.

Wednesday 14-Sept-2022

Multiple other tasks consumed quite a bit of my day, and I managed to do some studying for interviewing, as well as knock out a code challenge session.

The code challenge was to find the most common word "in a book". The input would be a String containing lots of words, punctuation, and spaces. This detailed analysis was lacking in my 40-minute time-limited exercise, which slowed my progress. It was pretty clear that I needed to use some sort of Collection that would help me determine duplicate items, but I didn't quite get the right selection. If I had walked through the data structure and how it is traversed, I would have discovered helpful facts that I could have used in designing a solving algorithm.

When approaching code challenges, I need to remember to:

Tuesday 13-Sept-2022

Continuing with the Java code challenges, I completed working on the core functionality of the Tree libraries. The K-Ary Tree was challening enough, and once I figured out to just stick with making "a tree of nodes" rather than a specific tree Class things got a lot easier.

I bumped into an interesting reference for using Java Generics at codejava.net called 18 Java Collections and Generics Best Practices. Although many points did not apply to what I was working on a the time, it looks like there is plenty to study and work toward understanding in the future:

  1. Choosing the right collections.
  2. Use interface types when declaring collections.
  3. Use generic type and diamond operator.
  4. Specifying initial capacity of collection.
  5. Prefer isEmpty() over size().
  6. Return an empty collection instead of null.
  7. Use the Enhanced For Loop or a While statement instead of classic For Loop.
  8. Using a lambda expression? Try to use a forEach().
  9. Override equals() and hashCode() propertly.
  10. Correctly implement Comparable interface.
  11. Using utility classes Arrays and Collections.
  12. Using Stream API on Collections.
  13. Prefer concurrent Collections over synchronized wrappers.
  14. Using 3rd party Collections libraries.
  15. Eliminate unchecked warnings.
  16. Favor generic Types.
  17. Favor generic Methods.
  18. Use bounded wildcards to increase API flexibility.

Check out the site for details.

I've already implemented a few of these, and am working toward using generic Types more often and handling unchecked warnings (rather than ignoring or avoiding them).

I could use more practice with generic methods and lambda expressions with forEach(), but I'm pretty regularly using the diamond operator and Enhanced For and While iterating structures.

The Stream API is still a dark art and I just need to gain some experience with it and I should be able to grok it.

When developing in C-sharp, I tend to implement Equals() and HashCode() overrides, but in Java I have not been doing so (and I could stand to do so for the exercise).

As I learn more about these best practices and start implementing them, I'm sure I have more notes and comments to make here and elsewhere.

Recursive Functions

While working through the Binary Search Tree Node class, I realized there was still a challenge ahead with recursive functions if I wanted to use them. Because recursive functions pop-off the Call Stack automatically when they exit, any of their data also disappears, never to be seen again. Passing data between recursive calls is possible, but tricky. But I wanted to be able to return an in-order list of values within a BST, so I had to figure this out.

Key takeaways:

Working code:

public class MyNodeClass {
  // fields
  private List<Integer> values;

  // methods getLeft(), getRight(), and .getValue()

  private boolean inOrderTraversal(MyNodeClass root) {
      if (root.getLeft() != null) {
          inOrderTraversal(root.getLeft());
      }

      // process root node here
      this.values.add(root.getValue());

      if (root.getRight() != null) {
          inOrderTraversal(root.getRight());
      }

      return true;
  }

  public String callingFunction(MyNodeClass root) {
    this.values = new ArrayList<>();
    StringBuilder result = new StringBuilder(); // for example
    MyNodeClass tempNode = this; // critical to enabling access to this.values

    if (this.inOrderTraversal(tempNode)) {
      // process the results within this.values
    }
    return result;
  }
}

Not really that difficult nor complex... just took a while to wrap my brain around the problem enough to work a viable solution.

Monday 12-Sept-2022

Now that I'm back from my volunteer event, I have some work to do. It's time to revisit K-ary Trees and Binary Search Trees. Coding these up and writing unit tests for these might take a minute, but I'm looking forward to reviewing these data structures and finding key takaway points for future use.

Java Generics

I've battled with these before and I did so again today. For future reference, I need to remember the following to help guide me to a solution, faster:

  1. Utilize an interface if you have to. This will set up a constraining rule that limits (or enforces) the types are actually supported within the class or class member.
  2. Remember to separate type template placeholders for reference types, versus reference type's value(s) they might be holding.
  3. Start with a completely non-generic class so it is easy to tell where the template placeholder types should go.
  4. When certain methods do not easily support being generisized, consider moving the functionality closer to the expected/intended type(s), perhaps up the inheritance chain or via a new class that supports inheritance and/or inherits from another, similar class.

Data Structures

Often times I struggle with taking instructions a little too literally. This causes me to try again and again to get code to work where it really shouldn't (see [Java Generics, above]{#java-generics}) or is above my skill level to complete in an efficient way. It will help me to remember that when writing code becomes difficult or I keep re-writing code and coming to a dead end, there are better ways to approach and resolve the problem:

  1. Stop. Take a break and think about the problem that needs to be solved, logically.
  2. Write out the problem domain and ask some questions about it to better describe the problem to solve, and perhaps uncover some ways to solve it.
  3. Break out a diagramming or drawing app (or an actual dry-erase board) and try solving it through diagrams and simplified steps.

My experiences at Code Fellows taught me the importance of breaking down a problem into the smallest possible bits, and working through each individual component carefully. This should help keep me from "coding in circles" and instead, finding a solution that I can then write tests for and start coding, and move forward.

Trees

Up until today I have been thinking of Trees as a separate class or structure than Tree Nodes. This has caused some issues:

  1. When challenged with a problem that includes a Tree data structure, I tend to worry about the complexity of development multiple classes to solve the problem, and the limited time-space to write algorithms and code, this slows me down.
  2. When implementing a generic data structure, separating Tree from the Node causes complexities with the Generics (see Java Generics, above). Developing a Tree Node as its own class with all the necessary functionality helps to overcome setting type placeholders and allows managing Node Data (values) without all the code gymnastics.

It is probably better for me if I think of Trees as a Node that might/not have child nodes. Any Tree Node should have the functionality necessary to get/set its value, one or more children, and know how to traverse, and be generic for all types that it could store.

Friday 9-Sept-2022

Today I have a volunteer event scheduled that will keep me busy through Sunday. Before that, I coded the Code Challenge and wrote a test for it and it passes! There are probably a few other tests to write to ensure the code is functional in all the expected ways including failure cases, while will be developed over time. For now, I'm calling the code challenge exercise a success, and can safely say that I passed the challenge per the rubric scoring system.

Thursday 8-Sep-2022

Met with Ryan to go over our project, update the Trello cards, and plan next steps. Made good progress completing several MVP cards, created a few new ones, and updated existing ones. There are a few cards that seemed a little lacking in detail so we added to them when we could, otherwise left a comment reminding us that more definition would be necessary to do work.

Following the meeting I completed the tasks at hand and then got back to work building my Java Code Challenge Libraries, starting with Trees and Queues. They needed to be built from the ground up following the curriculum, which I found to be much easier to do this time around (versus when learning them in classes, earlier). I guess the pressure of everything including homework and new material every day, multiplied by lack of sleep and limited time, fried my brain a bit!

Once I built-out a Binary Tree with Pre-Order, In-Order, and Post-Order traversal methods, I then had to build-out a Queue class so that I could implement a breadth-first traversal method. This required implementing generics as well. All the while I was writing and running unit tests to ensure the code I wrote was working and when it wasn't, I would know quickly and could pin-point the problem and fix it.

I am to the point where I am ready to write the Code Challenge code that I planned-out on the whiteboard, but it is too late to get involved with that right now. When I get a little time I'll get back to it and find out just how well (or not!) I did in the mock interview!

Wednesday 7-Sep-2022

I don't know where the time goes! Actually, plenty of it is spent doing research, learning about aspects of coding, taking care of things around my home and neighborhood, and volunteering in my community. Most recent community volunteer event was Tuesday where the ham radio emcomm team worked on a local repeater system to try and improved its coverage of the service area. No towers were climbed, and progress was made.

Things I've been working on include:

Today and on Monday I spent a few hours doing interview preparation activities, mostly working with behavioral questions, but also looking at some software developer openings around the area. There was a post on a bulletin board I frequent about a remote job opening that could be interesting. The OP works for the company and stated the entry requirements might look very high, but the hiring managers are likely to accept more junior developers for the role. Some of the entry requirements include C#, Azure, SQL, Git, and Selenium -- all of which are things I have experience with. I have some research to do.

Today I completed a technical interview challenge. The expectation was to build a function that accepts to binary trees, counts tree nodes that have no children, compares the two counts, and return true if both counts are the same, false if not. In 40 minutes I was able to build a plausible algorithm, write the code (Java this time!), define my testing approach and tools, and analyze the solution using Big-O notation. The only part I was missing was a step-through of my solution using the identified inputs and outputs, which cost a few points in total. Even without verifying my Java code for syntactical and idiomatically correct, my self-analysis shows I would likely pass a Code Fellows technical interview. I'll write the Java code anyway to get the practice and confirm my assumption though.

Completing that code challenge in Java prompted me to review how Tree data structures are arranged, how to traverse them, and how to and analyze them. Doing this work begged for a new repository so I created one from scratch, and intend to build-out the repo with various code challenges including basic data structures (for reuse) such as Trees, Stacks, Graphs, and so on.

All of this aught to keep me quite busy for the forseeable future! :zany_face:

Sunday 3-Sep-2022

Friday was busy with lots of tasks in lots of areas, including software. Most of the software-side of things was researching React-js design and techniques including planning, routing, and nav bars. Plenty of time was spent fiddling with CSS and react-bootstrap. The Enigma Bay team is making progress on the site layout based on wireframes and selected color palette, and I have a little work to do fixing up an alignment problem in a Component. Some things I should keep in mind when buiding a responsive site using CSS and Bootstrap:

.parent {
  height: 100%;
  display: flex;
  align-items: center; // horizontal centering
  justify-content: center; // vertical centering
  padding: 0.25rem; // your choice
}
<div class="parent">{text}</div>

For responsive design, and allowing viewability on varying sized browser windows, try using 'vw', 'em', and 'rem' (relative em) units. Be aware that font styles and browser-zoom levels might cause unexpected results. There is a lot to this, and many resources exist that dive deeper into how to get responsive design working well.

After battling with Bootstrap for a little longer, I was reminded how difficult styling websites can be when mixing it with CSS, because Bootstrap implements margin, padding, and box-sizing automatically, which makes some CSS styling ineffective. I keep going back and forth between "stick with pure CSS!" and "stick with just using Bootstrap" and there is never a winning decision, it is always a draw. At least for the purposes of the current project, the time spent fiddling with style is just practice time anyway, and much of the styling wil be revamped completely as the project moves forward.

Thursday 1-Sep-2022

This morning I worked on a LeetCode challenge, medium level, in javascript. The goal was to implement a function that takes two non-empty linked lists with data type Integer (Number), and sum the values across lists. Remember elementary school math, summing large numbers like 714 and 237? Like that but with singly-linked nodes, and (of course) the numbers are in reverse-order, which makes carrying-over values a little more difficult. I'm about 75% done and will get back to it in a bit.

Meanwhile, EnigmaBay had a meeting to discuss moving the project forward. We chatted about color schemes, icons, CSS, Bootstrap, and SASS, React Router, and the React Component hierarchy we want to implement. Very productive! We start developing the layout and basic design of the website today.

ESLint with React was reporting some errors and warnings that were unexpected. After reinstalling eslinter and learning there is a plug-in specifically for React, I installed that too. Two elements needed to be udpated in the eslintrc.json file:

  1. "extends" element needed to be updated to a collection that included both "eslint:recommended" and "plugin:react/recommended"
  2. "parserOptions" element needed "sourceType": "module" added

Now linting seems to be working as expected.

Wednesday 31-Aug-2022

It has been a busy start to the week. Not all of my activities have been code-related, unfortunately. Several tasks related to volunteer activities came up and I decided to concentrate efforts there to try and meet some deadlines in the coming weeks.

At any rate, I took time this morning to respond to a few interview questions and practiced speaking them aloud in an effort to gain my confidence and organize my thoughts, preparing for when the interviewing starts.

This morning I completed a technical interview challenge: Sum Odd Values in a Binary Tree. Ending (self) score was 34/40 (32 is passing). I was able to depict the problem domain, inputs and expected output, testing approach and basic test cases, write an algorithm and analyze it in Big O notation, as well as write pretty-close-to-working javascript code (minus a few syntactical errors).

To check my work (because testing ones self is dubious) opened a replit to validate my code. Note that I had to create classes to meet the requirements of the challenge:

It was time consuming to write all of this out, but exercising my mind to get to the correct solution is important. I find myself questioning the code I write before, during, and after I write it (before testing it). Perhaps its the test engineer in me.

The next challenge was from CodeWars using javascript. In 40 minutes I completed whiteboarding Kata "Testing 1-2-3" and got very close to a solution. Below are some retrospective commments:

  1. Array.prototype.length is a property, not a function/method.
  2. Indexing into an array is zero-based so do not change the beginning iterator in a for loop unless you really really need to.
  3. Next time consider using Array.prototype.map( (element, idx)=> { return ... }); and increment idx value within the string concatenation (or template literal).
  4. Concatenating strings in javascript using template literal requires ${} placeholders and back ticks (e.g. code fencing characters).
// template literals
let var1 = 1;
let var2 = 2;
let var3 = var1 + var2;
let myString = `${var1} plus ${var2} equals ${var3}`;

Considering my internal anxiety coding with javascript, not all that bad really.

Saturday 27-Aug-2022

Reactjs oh-my!

I'm glad I started fiddling with React, javascript, and CSS these last few days. Today's adventure was trying to get a React site looking okay and passing props around. Looking back at issues and resolutions:

When importing a collection of data using a json file:

  1. Be sure it is directly in the 'src' folder. A sub-folder or some other part of the React project folder hierarchy will not work.
  2. Ensure the json collection is a collection starting with '[' and ending with ']', and also be sure to make all collection items objects using braces, separated by commas.
  3. File contents do not need to be loaded into state in order to use them. They can be passed as props e.g. <GameBoard wordlist={words} />

When using React-Bootstrap, be sure to:

  1. Install it: npm install react-bootstrap bootstrap
  2. Import it in the root file: import 'bootstrap/dist/css/bootstrap.min.css';
  3. Import the specific Bootstrap Component(s) you want to use on the Component you want to use it in import { Container, Row, Col } from 'react-bootstrap';

Track Keys and Values when passing a collection as props:

  1. Review React Keys
  2. The Parent Component should specify the key attribute inside the array (inside a Map function).
  3. The Child Component that uses the passed-in props does not need to reference props.key, only props.value (whatever value is).

Lastly, whenever it is not clear whether data is being passed around or what it looks like in-flight, use console.log and check it out at run time.

Friday 26-Aug-2022

After finishing some tasks around the house, I jumped right in to a 40 minute technical interview challenge. This one was summing odd numbers in a binary tree. It tests the interviewee's understanding on binary trees, including traversal and Node data structures. Whiteboarding these challenges in Miro (and similar apps) is quite difficult because there is an additional interface layer between me and the depiction I'm attempting to draw and layout. When working on a real, in-person, dry-erase board, it is much easier to erase, correct, and draw-out the brainstorming and ideation. Granted, one benefit of Miro (and similar) is duplication of complex drawings is super fast!

It took the full 40 minutes but I earned a passing score because I pretty much nailed every section in the rubrik except for code and Big-O. The failures there were not writing any Big-O evaluation at all, and my javascript code was only 85% complete before the time expired.

To solve this challenge I used Breadth-first Traversal using a Queue, rather than Depth-first using a recursive function because it is more difficult to store Recursive function values/outputs than it is to collect and store data within a while structure.

Code Fellows hosted a Big-O algorithm analysis webinar with guest speaker and alumn Isaiah Burkes. He reviewed why we do code analysis, how it is done using Big-O notiation, and gave a few rules of thumb to help remember algorithm analysis:

The last bulletpoint is referencing algorithms that take multiple input parameters. Each parameter has an impact of the algorithm run time and could significantly add to the run time.

After this I started in on the LingoBingo-js project, working in a dev branch to initialize a React singe-page webapp. The goal is to sort out how to build-out Components so they fit into the existing wireframe design intentions. I plan to do more work through the weekend, and the plan is to pick-up collaborative work early next week.

Thursday 25-Aug-2022

As happens on most days when I leave my Linux box powered-on overnight, a Printer Added popup appears in the notification area on the desktop. This hasn't been a problem, but my curiosity about it got me researching. It's pretty simple: The CUPS service is restarted at about midnight daily in order to 'roll the log file'. There is a bug filled with Cannonical with discussion, and the basic result is there is not a problem per se, and it can be worked around.

I realized, after reviewing yesterday's technical interview problem js solution, that I failed to nullify a node within the pop() method. While this is not a problem per se, it is best practice to nullify objects so the memory is freed. For managed code the object will get garbage collected when all references to it are removed. The larger the code base, the more important this design practice becomes in terms of memory efficiency, so is a good habit to get into now.

// updated pop() method code
  pop() {
    // returns the TOP node or item (LIFO) from the stack
    if (this.isEmpty) {
      return "Stack is empty";
    }
    let tempNode = this.top;
    this.top = tempNode.next;
    this.nodeCount = this.nodeCount - 1;
    this.isEmpty = this.nodeCount < 1;
    tempNode.next = null; // orphan tempNode from the Stack for cleanliness' sake
    return tempNode.data;
  }

My Stack's isEmpty() method is relying on a hidden nodeCount property to compute a boolean return when called. Looking at a best practice pseudo code example, I could instead just check to see if 'head' is null, and so long as I manage the 'head' node reference properly, isEmpty() should always return correctly and without throwing.

// updated isEmpty() method code
class Stack {
  constructor() {
    this.top = null;
    // this.nodeCount = 0; // this is no longer necessary
    // this.isEmpty = true;
  }
  isEmpty() {
    return this.top === null;
  }
  // this.nodeCount operations removed from any methods that have it
  // this.isEmpty interrogations are replaced with this.isEmpty()
  // any code where this.isEmpty is calculated should instead point to this.isEmpty()

Earlier this morning I read an update from SalesForce about Heroku free products pricing changes. Yep, that's right, those free Dynos and Postgres instances you've been using for all these year might become charged services. Check out Heroku's Blog Article Heroku's Next Chapter for information from Bob Wise, GM and EVP at SalesForce. Thankfully, no immediate action is needed, but sometime in October I'll need to revisit my Heroku instances and figure out what will be going away and what will stay.

Back to code! I failed another technical interview challenge (couldn't complete in 40 minutes, and was doing it wrong anyway) so I attempted to solve it without a time limit on my physical dry-erase board, and then punished myself :wink: by writing out the code in javascript.

I started with a Node class, similar to a linked list Node, but this will be used in a Queue class.

class Node {
  constructor(data) {
    this.value = data;
    this.next = null;
  }
}

Then built the Queue class with count, front, and back properties, and functions isEmpty, getCount, peek, enqueue, and dequeue.

class Queue {
  constructor() {
    this.count = 0;
    this.front = null;
    this.back = null;
  }
  isEmpty() {
    return this.front === null;
  }
  getCount() {
    return this.count;
  }
  peek() {
    if (this.front === null) {
      return null;
    } else {
      return this.front.value;
    }
  }
  enqueue(data) {
    let newNode = new Node(data);
    // case 1: no nodes in queue
    if (this.front === null && this.front === this.back) {
      this.front = newNode;
      this.back = this.front;
      this.count = 1;
      return;
    }
    // case 2: 1 node in queue
    if (this.front !== null && this.front === this.back) {
      this.back = newNode;
      this.front.next = this.back;
      this.count++;
      return;
    }
    // case 3: more than 1 node in queue
    this.back.next = newNode;
    this.back = newNode;
    this.count++;
  }
  dequeue() {
    if (this.isEmpty()) {
      return null;
    }
    let temp = this.front;
    this.front = this.front.next;
    temp.next = null;
    this.count--;
    return temp.value;
  }
}

Next up is the duck-duck-goose function code. Code Fellows utilized arrow functions for their datastructures and algorithms training assignments, so I followed suit.

The important part of the code starts with the Queue instantiation and loading from the input array. From there the main processing code is pretty short and sweet, but entails two iterating structures, which is not always the most efficient algorithm in BigO.

The worst-case BigO of Time for duckDuckGoose() is probably O(n * k). Thankfully, the Queue datastructure has a O(1) in time and O(1) in space for all of its operations so total time through each iteration is fairly fast and lean.

BigO in space for duckDuckGoose() is more like O(n) because the entire input array is stuffed into the Queue O(1) storage at a time for every item in the array.

const duckDuckGoose = (arr, k) => {
  // test for null and empty cases here
  if (!Array.isArray(arr) || !Number.isInteger(k)) {
    return null;
  }
  if (arr.length < 1 || k === 0) {
    return null;
  }
  if (arr.length === 1) {
    return arr[0];
  }
  if (k === 1) {
    return arr.at(-1);
  }
  // end null empty test returns
  if (k < 0) {
    k = Math.abs(k);
  }

  let myQueue = new Queue();
  // enqueue the array!
  for (let idx = 0; idx < arr.length; idx++) {
    myQueue.enqueue(arr[idx]);
  }

  // main processing
  while (myQueue.getCount() > 1) {
    for (let jdx = 1; jdx < k; jdx++) {
      myQueue.enqueue(myQueue.dequeue());
    }
    myQueue.dequeue(); // this should be the kth item
  }

  // return result
  return myQueue.dequeue();
};

It's not always necessary to code all of the edge case tests (depends on your interviewer I guess), but I decided to do it to exercise my software test engineer skills.

Next I wrote some exercises starting with the example case, and added a bunch of edge case inputs and a few larger input cases. Below is the base example case:

let result = duckDuckGoose(['a', 'b', 'c', 'd', 'e'], 3);
console.log('result a-e, 3: ', result);

In the end the challenge isn't really that hard, in fact it was easier to write it using a Queue (including coding the queue in full) than it was to try and solve it will various types of for and while loops.

Wednesday 24-Aug-2022

While updating my notes organization yesterday, I also added some emojis that did not work at first. Some investigating revealed that I didn't have the correct plug-ins selected. Some references that lead me to the correct solution:

GitHub Docs on Publishing GH Pages using Actions

GitHub Docs on Using Jekyll with GH Pages

Jeykyll's GH README defining the jemoji plugin.

Jekyll Docs on Plugins

Sounds like Jekyll-themed GH Pages can be locally tested, which might require some Ruby knowledge - I didn't look too deeply into this as there are more important things for me to research and practice right now.

Technical Interviewing exercise: I attempted to complete a Stack-related technical interview question but could not complete the discussion and solution design within 40 minutes. This is not uncommon for me. So I took an additional 40 mins or so to try and create a Stack using Node just to see if I could do it using replit.com, and I could! Following is the code I wrote:

'use strict';

// node class constructor
class Node {
  constructor(value) {
    this.data = value;
    this.next = null;
  }
}

// stack class constructor
class Stack {
  constructor() {
    this.top = null;
    this.nodeCount = 0;
    this.isEmpty = true;
  }
  push(value) {
    // node or item is added FILO to this stack and returns nothing
    let newNode = new Node(value);
    if (!this.isEmpty) {
      newNode.next = this.top;
    }
    this.top = newNode;
    this.nodeCount = this.nodeCount + 1;
    this.isEmpty = this.nodeCount < 1;
  }
  pop() {
    // returns the TOP node or item (LIFO) from the stack
    if (this.isEmpty) {
      return 'Stack is empty';
    }
    let tempNode = this.top;
    this.top = tempNode.next;
    this.nodeCount = this.nodeCount - 1;
    this.isEmpty = this.nodeCount < 1;
    return tempNode.data;
  }
  peek() {
    // returns a copy of the value at TOP node without removing it
    if (this.isEmpty) {
      return 'Stack is empty';
    }
    return this.top.data;
  }
}

While this is not fully vetted (unit tests etc), the properties are updated correctly, and the pop(), peek(), and push() functions operate as expected.

The technical interview question was to track the maximum value within a Stack, so I worked on some code to implement that feature. Below is the additional code:

// the code above...
  maxVal() {
    let arr = [];
    let result = this.peek();
    while (!this.isEmpty) {
      let temp = this.pop();
      result = temp > result ? temp : result;
      arr.push(temp);
    }
    for (let idx=arr.length - 1; idx >= 0; idx--){
      this.push(arr[idx]);
    }
    return result;
  }
// end of class definition

The code was all developed using a real dry-erase board and replit. Testing the code required console.log() and replit breakpoints and their built-in debugger. Here is the rest of the code:

let myStack = new Stack();
let emptyStack = myStack.isEmpty;
console.log('Created stack. emptyStack? ', emptyStack);
myStack.push(100);
emptyStack = myStack.isEmpty;
console.log('Pushed a value. emptyStack? ', emptyStack);
let stackPeek = myStack.peek();
console.log('Peeking the stack, value is: ', stackPeek);
let popResult = myStack.pop();
console.log('popResult: ', popResult);
emptyStack = myStack.isEmpty;
console.log('emptyStack? ', emptyStack);
myStack.push(3);
myStack.push(2);
myStack.push(5);
myStack.push(1);
myStack.push(4);
console.log('stack empty should be false: ', myStack.isEmpty);
console.log('peek should be 4: ', myStack.peek());
console.log('maxVal should be 5: ', myStack.maxVal());
console.log('stack empty should be false: ', myStack.isEmpty);
console.log('peek should be 4: ', myStack.peek());

Just now I noticed that replit has a 'unit tests' tool! Something else to check out for sure.

That will be it for today. There is plenty more to do (of course), and never enough time.

Tuesday 23-Aug-2022

After some meetings with Ryan about our MERN-stack project, I decided it would be a good idea to brush-up on various topics so I am primed for planning and development, especially React and CSS/Bootstrap. While I was browsing around my Code Fellows notes, I realized I did a terrible job of organizing my reading notes and in-class notes, so I reorganized them a bit. Several topics were missing altogether, others were incomplete, incoherent, or just not-quite-done. For some of these items I simply went in to the documentation, referenced authoritative materials, and made necessary edits, updates, and additions. For those topics that are missing, I'll have to create new documentation notes - one example is ReactRouter - which will be added to my cont-ed index of topics.

Saturday 20-Aug-2022

Despite telling myself I wouldn't do much "techie" stuff today, here I am working through CSSBattles.

Battle #2, Eye Of The Tiger #16 is pretty great. I couldn't finish it in 10 minutes like these guys but that's not really important. The key take-aways are:

  1. When using display: flex; always try margin: auto; in the child box to center it easily
  2. Creating circular-ish items (think eyelid, teardrop, etc) use border-radius: {top-left} {top-right} {bottom-right} {bottom-left} in that order to control each corner
  3. Margin properties can be short-handed into a single line similar to border and border-radius: margin: {top} {right} {bottom} {left}
  4. Rotating a box with transform: rotate(ndeg); will make your margin-adjusting efforts confusing - just remember the previous take-away (tilt your head)

A decent overview of flex box.

Details about CSS margin property.

Friday 19-Aug-2022

Over the past 2 weeks I have been busy with preparing for, and participating in, volunteer activities. The Multiple Sclorosis NW Division holds fund-raising bike rides throughout the US, and I helped by providing amateur radio and transportation services to promote a successful, incident-free, and enjoyable event for all participants and the MS Society itself. Less than a week later, I travelled into the woods to support Destination Trail's "Bigfoot 200" ultra-trail-marathon through the Gifford-Pinchot National Forest. Again, I provided ham radio communications to support the success of this event in terms of tracking runner's bib numbers as they enter and leave aid stations, as well as ones that "drop out" of the race due to time cutoff or exhaustion. Logistics is another big part of my volunteer efforts in person as well as "on the air" using ham radio, to help arrange supply deliveries, transportation of runners and crew from an Aid Station to another location, etc.

CodeWars challenges are a great way to prepare for technical interviews, especially wnen using a whiteboard to rationally work through the problem and design a possible solution. Practicing javascript challenges will help prepare me for anticipated work in the EnigmaBay team, on the Lingo Bingo WebApp.

Fridays at Code Fellows tend to be busy with streams of final presentations, mid-term presentations, guest speakers, and collective social events for CF students and alumni. Today's JavaScript 401 Finals presentations included a team with Andrew S, whom I hadn't talk to in a while. He was a peer in previous CF classes with me, and it was great to see him present his team's project. All teams presented very well and it was great to see their progress toward graduation!

There was also a Python Midterm presentation. The first team included previous team-mate Liesl, and the team obviously had a lot of fun presenting their app. The next team included previous team-mate Dana H and Gina N, as well as co-Code Fellows team mate Vinny S! Their app searches Wikipedia and finds related articles that link together a "start" and "end" article. The other teams also had amazing projects including a Chess game built from the ground up that included a console version as well as a GUI, and an app that scaped Canvas data and provided graphs, calendaring items, and quick links to common tools and areas of Canvas.

Back into coding practice, I work on CSSBattle.dev again. I need to remember how to make trangles, so here is an example of an upright isocolese triangle in red:

  1. Set the left border as 100px solid and transparent
  2. Set the right border as 100px solid and tranparent
  3. Set the top border as 100px solid and red (or your preferred color for the entire triangle)

It is important to remember that the vertex angle is determined by border-left and border-right unit settings.

Tuesday 2-Aug-2022

Lots of little work done on the Bigfoot WL Bib Record Form project, and some pretty good collaboration started with a small group of 4-5 others. Success for this iteration of the form looks promising!

Yesterday I spent several hours reviewing bogposts and freebie articles about interviewing. Turns out a lot of my fears about interviewing are not really justified, and my approach to interviewing is what needs to be adjusted. An adversarial interview is not what anyone is looking for (if they are serious about filling a position). Instead, my view needs to focus on researching the company and the position I am interested in, and during the interview use that information to help inform my responses. The research should also answer lots of questions about a company and the position but it cannot possibly answer them all, so I should bring those remaining questions to the interview with me, and learn what I can while I have the inside opportunity to ask them. There is opportunity on both sides, and I need to leverage this to help me have positive interviewing experiences, regardless if an interview turning into an offer.

Over the weekend I began working on a collaboration project with Ryan S in Bellingham. We agreed to work on a mern-stack project, basically rewriting a project I already have underway using DotNet. We are both looking to gain more experience with most (if not all) aspects of software development, but especially javascript, react-js, node, and probably express-js and mongo. We will also benefit from utilizing common software management tools like GitHub and Trello, and following some good practices to plan-out this project. Also, there is already a 'customer' for this project, so I suspect we will some experience with engaging with a client and honing the project to a real use-case. I'm looking forward to working with Ryan, and moving this project forward!

These last few days I learned about:

Friday 29-July-2022

At some point in the future, I'll want to change-up this format to something like a more formal blog article. I haven't decided yet what it will be, other than not a massively long MD file with a FILO stack of entries.

I finished up the Zip Linked Lists code challenge review by performing a mock whiteboard interview within a 45 minute period and then adding the whiteboard to the solution. This is not really sustainable in that it will cause a tremendous number of repositories to appear in my GH profile with little benefit (to anyone), so I plan to set up separate code challenge repositories for various languages.

Related, I worked my way through a CodeWars challenge in javascript (which I haven't written much of lately). I followed the general rubrik outlined by Code Fellows for a technical interview and produced reasonable code that passed the default CodeWars unit tests. Not that that is everything! So this prompted me to create a new js-specific code challenge repository, so this a future efforts will have a place to live.

Somehow I decided today was a good day to look up how to add emojis to markdown files. There are at least two ways:

For example:

:smile: in supported markdown interpreters results in a :smile:

!["smiley"](https://github.githubassets.com/images/icons/emoji/unicode/1f603.png?v8) results in a vvv large smiley vvv

"smiley"

Here are a couple of references with more info:

Emoji Cheat Sheet

Markdownguide.org's Extended Syntax guide

Thursday 28-July-2022

Building Java Projects in GitHub using GH Actions. There is a template in github repo 'actions/starter-workflows' that is a good starter. Originally I copied an existing yml file from a CodeFellows example, but that was designed for a slightly different environment and project, so I had to modify it. There were a couple issues:

  1. gradlew could not be found. This was probably because I was forcing a CHDIR in the yml file and I didn't need to.
  2. gradlew could not be executed. In Linux, file permissions are managed using bits for Read, Write, eXecute, etc. Windows does as well but it is a little different. In my yml I defined an Ubuntu environment for building and testing, so permissions could be a problem. Git has the ability to set permissions via git update-index --chmod= and to add eXecute permissions append +x to the end.
  3. The last change that was required was to set the JDK compatibility level to 11, instead of 17 (not supported in GH Actions?).

Earlier today was a Code 401 instructor's panel where they discussed current content in those classes. There was a good amount of discussion around C#/DotNet, and TypeScript (which is starting to make inroads to the JS class due to increased use in the industry). There was also good discussion around strategies to deal with learning to code, especially JS, such as breaking down the problem in words, and writing solutions as comments rather than code, and then worry about coding the problem once an algorithm appears to solve the problem at hand.

Wednesday 27-July-2022

Today I passed the final technical interview at Code Fellows and am officially an alum! Certificate is due in a week or so!

Passing the technical interview was extremely difficult, and I followed the advice I'd received from Code Fellows instructors and staff: Stick with it, pay attention to the details, break down a problem into the smallest parts, and take care of myself along the way. I will continue to do more technical interview practicing while I job hunt, so that I am well practiced and can more easily get over nervousness during a real interview.

Today I picked-up where I left off with one of my older projects, the Bigfoot Bib Report WL Form. The BigFoot 200 event is coming up and during a recent preparatory meeting the form was re-introduced (much to my surprise and delight) and there was new (and renewed) interest in it. I'm going to try and get this as ready as possible, with help from other interested volunteers to test it and provide feedback on possible improvements.

There are a ton of projects on my pet-project kanban board that I stil need to get to. There is definitely more work than there is time. At least these projects and tasks are centered around the goals of improving my software developer skills in every regard, and prepare me for my next big thing.

Back to root README