Thursday, February 8, 2024

Quick Bytes: Javascript Hex To Uint8Array

In a recent project I needed some javascript code to take a hex string and then convert to a Uint8Array.

Here's some quick code to get that done.

function hexStringToUint8Array(hexString) {
    if (hexString.length % 2 !== 0) {
        throw "Invalid hexString";
    }
    var arrayBuffer = new Uint8Array(hexString.length / 2);
    for (var i = 0; i < hexString.length; i += 2) {
        var byteValue = parseInt(hexString.substring(i, i + 2), 16);
        if (isNaN(byteValue)) {
            throw "Invalid hexString";
        }
        arrayBuffer[i / 2] = byteValue;
    }
    return arrayBuffer;
}


Wednesday, January 17, 2024

Foundations: Events And C#

 

I was going over some notes on events, event handlers, etc. and I thought I'd post up some general foundational information that I have written in the past, as it's still relevant today (as are most foundational topics). As is always the case with some older foundational code, you may need to update for current versions, etc.

What really are Events, Event Handlers, Raising Events, etc. and how can you create your own class that has its own Events which can be consumed? This series of articles takes a look at what Events are, how to implement them within your own classes, and how they are useful.

Don’t I already create Events when I say what happens when something like a "submit" button is pressed?

No. You’re telling what should occur when an Event takes place, and this is very helpful in learning how to create a class with its own Events, but you’re already working with a class that has its own Events, Event Handlers (or what should take place when an event happens), and methods to raise the Events.

So can you tell me what is an Event, an Event Handler, and show me Event Messaging in simple terms?

Yes! And that’s what this article is all about. Rather than talk about telephones, callers, and things like that it’s much easier to take a look at an example that you’re already familiar with to see what Events are and what Event messaging is all about.

First though, let’s just take a look at an easy definition of an Event, which simply is: a way for a client, program, object, etc., to be notified when another object does something, or changes, or something happens to that object.

An easy example is the Page class and how you work with it in ASP.NET. When a page Loads that’s the Event (specifically the Event is called a Load). Remember, an Event is something that simply happens, like in normal everyday life.

So when the Event happens, in our example, the loading of a page, something should happen. In order to say what happens when an Event occurs, you set what’s called an Event Handler. An Event Handler does exactly what its name suggests: it allows you to point to a method, or methods, that handle the Event, in our case the loading of a page.

This shouldn’t be a new concept to you as you do it all the time. Take the code below:

this.Load += new System.EventHandler(this.Page_Load);

The code above simply says “when the event Load occurs, handle it by running the method Page_Load”. An Event Handler simply points to a method with a specific signature.

So how do you know when an Event happens, or more specifically, say that the event took place? The Event must be raised, and is done so with a method that is defined as OnEventName. This method can be called from any type of client, and in ASP.NET for the Page class, usually happens behind the scenes (as a series of events are raised as an ASP.NET page is run) and should be in the class where the event is declared.

To that extent, event messaging is the whole process of what happens when an event takes place, how it is handled, and how it is raised.

So to quickly recap, an Event is something that occurs, and needs to be raised (in order to let us know it’s happening). When the event is raised it should be handled by a method, which is set by an event handler.

So can you give me an example of how I create a class with an event and how to use it in an ASP.NET page?

Below is a simple class called InnerPanelClass which has one event, called Load (the code will be walked through in the rest of the article).

namespace MyEventClasses{

  public delegate void PanelEventHandler (object sender,     
  System.EventArgs e);
	
	
  //Now the class
  public class InnerPanelClass 
  {
     //The event is called “Load”
     public event PanelEventHandler Load;
     
     //The constructor for the class
     public InnerPanelClass() {}

     //The method that raises the event
     public void OnLoad()
     {	
       System.EventArgs e = new System.EventArgs();
       Load(this,e);
       return;
     }
   }
}

Some of the code should look familiar like the class definition, constructor, and namespace definition. So let’s take a look at actually declaring the Event in our class.

public event PanelEventHandler Load;

When you declare an Event the syntax is public event A Delegate Type The name of your Event. A delegate is simply a way of allowing anonymous methods to be invoked, but with a specific signature. In essence what we’re doing when we declare our Event is saying “The Event is called Load, to handle that event a client using our class needs to use an Event Handler, specifically the PanelEventHandler, which is actually a Delegate. So let’s take another look at that Delegate code (for more information on Delegates please see the article Using Delegates in C# ):

public delegate void PanelEventHandler (object sender,System.EventArgs e);

What's great about Delegates is that they allow you to specify any method as long as it has the signature defined by the Delegate. In our case, that means that a new PanelEventHandler can be any method which takes an object and System.EventArgs as its parameters.

The last piece of code in our class is the method OnLoad which will actually raise the event and is pretty easy to follow:

public void OnLoad()
{	
  System.EventArgs e = new System.EventArgs();
  Load(this,e);
  return;
}

When you create your method to raise the Load Event, you’re just calling the Event with the proper parameters of the Delegate, in our case an object (which should be itself using the keyword "this", and a System.EventArgs object) and returning it. When the Event is raised, it will then execute any new PanelEventHandlers set up by the client who is using the class.

Using the class

So now it’s just using the class, which is pretty easy to do. Below is the full code needed for this example:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace MyWeb
{

  public class EventSample : System.Web.UI.Page
  {
    //Create a new instance of our class.	
    public MyEventClasses.InnerPanelClass Ip = new MyEventClasses.InnerPanelClass();
		
    private void Page_Load(object sender, System.EventArgs e)
    {
     Response.Write("This is a page load");
    }
    
    //Set the method to be called when the event occurs.	
    public void Panel_Load(object sender, System.EventArgs e)
    {
     Response.Write("This is my InnerPanel load");
    }

    #region Web Form Designer generated code
    override protected void OnInit(EventArgs e)
    {
     //
     // CODEGEN: This call is required by the ASP.NET Web Form Designer.
     //
     InitializeComponent();
     base.OnInit(e);
     
     //Raise the Event when the page initializes
     //using the object’s method “OnLoad”.
     Ip.OnLoad();		
     }
		

    private void InitializeComponent()
    {    
     this.Load += new System.EventHandler(this.Page_Load);
     
     //Create an Event Handler for the Load Event and point it 
     //to the method "Panel_Load".
     Ip.Load += new MyEventClasses.PanelEventHandler(this.Panel_Load);
    }
    #endregion

  }
}

namespace MyEventClasses{

  public delegate void PanelEventHandler (object sender,     
  System.EventArgs e);
	
	
  //Now the class
  public class InnerPanelClass 
  {
     //The event is called “Load”
     public event PanelEventHandler Load;
     
     //The constructor for the class
     public InnerPanelClass() {}

     //The method that raises the event
     public void OnLoad()
     {	
       System.EventArgs e = new System.EventArgs();
       Load(this,e);
       return;
     }
   }
}

As you can see, once you create your class with the Events and necessary methods and delegates, using it from a client (our ASP.NET page) is easy to do.

While this example is simple, it creates the foundation and understanding for working with more advanced type of scenarios, like creating your own class of Event Arguments, passing in Event Data, and creating your own classes which define more user controlled Events (like a click event for a button object) and will go a long way in understanding the role of Events which help to modularize programs.

-----

But what about sending data along with the Event? In order for this to happen, you can setup your own EventArgs class which is really easy to do. Just create a new class which inherits from System.EventArgs. After that you can then create properties just like any other class. Building on the example from the previous article on Events, we'll create our own class called InnerPanelEventArgs which has one property called MyData that can be used to send data along with the event.

public class InnerPanelEventArgs: System.EventArgs
{
  private string _MyData;
  public InnerPanelEventArgs(){}
		
  public string MyData
  {
   get {return _MyData;}
   set {_MyData = value;}
  }
}

Now instead of using System.EventArgs for the Delegate, we'll use our new class instead and also make sure that when the Event is raised, it also needs to pass in an object reference, so the new code would be:

namespace MyEventClasses{
	
	public delegate void PanelEventHandler (object sender, InnerPanelEventArgs e);
	
	public class InnerPanelEventArgs: System.EventArgs
	{
		private string _MyData;
		public InnerPanelEventArgs(){}
		
		public string MyData
		{
			get {return _MyData;}
			set {_MyData = value;}
		}
	}

	public class InnerPanelClass 
	{
		
		public event PanelEventHandler Load;
	
		public InnerPanelClass() 
		{
		}

		public void OnLoad(MyEventClasses.InnerPanelEventArgs e)
		{	
			Load(this,e);
			return;
		}
	}
}

Since the signature has changed for the EventHandler you'll also need to change the signature for the method (and then at the same time we'll print out the new property for the Event data):

public void Panel_Load(object sender, MyEventClasses.InnerPanelEventArgs e)
{
   Response.Write("This is my InnerPanel load"+e.MyData);
}

When the Event is raised, since it needs to pass in an object reference to InnerPanelEventArgs, this is where you can also set and pass in any Event data:

override protected void OnInit(EventArgs e)
{
  InitializeComponent();
  base.OnInit(e);
  MyEventClasses.InnerPanelEventArgs ipArgs = new MyEventClasses.InnerPanelEventArgs();
  ipArgs.MyData="This is some event data";
  Ip.OnLoad(ipArgs);		
}

Now when the page is run, you will not only see the message "This is my InnerPanel load", but also the string "This is some event data". From here, it should be pretty easy to see how you can than pass in information when an Event occurs from other data, like a control's properties or other client information which can be useful to know when an Event happens.

Monday, January 8, 2024

Quick Bytes: Solidity Function To Convert Uint256 To String

 Here's a quick piece of code for a Solidity function to do the conversion:

  // Converts a uint256 variable to a string
  function uint2str(uint256 _i) private pure returns(string memory) {

      if (_i == 0) {
          return "0";
      }
      
      uint256 j = _i;
      uint256 length;

      while (j != 0) {
          length++;
          j /= 10;
      }
 
      bytes memory bstr = new bytes(length);
      uint256 k = length;

      while (_i != 0) {
          k = k - 1;
          uint8 temp = (48 + uint8(_i % 10));
          _i /= 10;
          bstr[k] = bytes1(temp);
      }

      return string(bstr);

  }

2024 Is My Year (To Blog Here)

This is in some ways more for me than it is for you, but I think this is truly my year to be blogging down here like I had hoped to last year and while I know from past blogging daily is truly the way to go, and many times a lot of articles a day---

I have a day job as an engineer/developer/architect, etc.

So maybe it's more like once a week for sure, and if there's more (which there typically tends to be if I get into a run)--good deal--but I think I'll go for at least one a week, no matter how long or short.

And using that metric...I'm already ahead this week!

Hey--I know what you're saying, but I'll take those wins where I can!


Dont Forget About HTML And Standards


I've noticed, throughout my time in tech that while I love some of the newest technology, I love standards, or at least the initial drive for us to have those--because they absolutely matter.

The Apple Store, the Google Play store--so many of those apps rely on standards like HTTP/TCP and standards like HTML and Javascript.

I understand the need for different types of technologies--like a Windows Forms app, but as an example, if you needed a form to collect data and that form needs to be available on web sites, intranets, and could be  ingested by another UI/program--why would you use something else other than HTML?

HTML is what has allowed us to interact and create this amazing world we code in (at least parts of it)--free to everyone to create, guided by a standards body who is at least thinking about the community and world as a whole (versus a private company who may not care as much about that type of interoperability and other users outside of their ecosystem).

Let's keep leaning into that.

Tuesday, May 23, 2023

Housecleaning: Blogging Notes

I've been a little busier these days, so I was not able to blog as much over the last few weeks, but looking to get on a regular cadence again, at least a couple times a week and hopefully more, or some good sessions just posting up on a lot of things. 

As I've blogged before, it is a marathon...

Quick Code: AZ CLI To Get Storage Accounts And Redundancy Type (AKA sku.name)

Here's some quick code to get a list of your Storage accounts from a cloud shell in the Azure Portal.

az storage account list --query "[].{Name:name, Redundancy:sku.name}" --output table

That's it!

It will output something similar to this:

mystorageaccount1    Standard_LRS
mystorageaccount131    Standard_RAGRS

By default this will list everything for the subscriptions you have checked to show resources for in the portal.

Tuesday, April 18, 2023

ChatGPT Files: Thinking More Modular (aka Script Cut-Off)

Sometimes when I've been writing scripts with ChatGPT I've asked it to do a little too much where it either stops sending in code, or the code gets put into code and non-code boxes. At times ChatGPT will stop giving me the code all together, and I'll get into a continuous loop where I keep asking it to finish, it starts over, I ask it again, and then I finally say stop.

So what I've been trying to do instead is ask it to do things differently, where instead of putting all the code in one HTML file, if I'm building a front-end, I'll ask it to put it into different files, like one for HTML and one for Javascript. 

That way it helps it write code a little more modular, and where it doesn't break up or stop generating code. This will still depend on what you are having it write, but altogether, it does help.

At the same time instead of asking it to create whole new scripts, use it to update pieces of scripts, specific functions, or ask it more general questions like how you would do it in theory vs code.

 

Creating A Pilot Program For ChatGPT And Other AI Tools

 
Like others, I've been working with ChatGPT from a developer and engineering perspective over the past few months, and as developers, we can't shy away from these tools. We have to know and understand them, just like other tools, albeit with the knowledge and understanding that there's a difference in what these new AI tools are offering both from a development standpoint, and a human standpoint.

Lately I've been thinking about how to start a pilot program for developers and engineers for tools like ChatGPT where it's not overly prescriptive, but also has guardrails if being used and paid for like any other software, and how to gather research on that use.

This post outlines some of the pieces to get up and running, and to use as a template for further development of a pilot program specific to your team/department including:

  1. Goal Of The Initiative
  2. Outcomes And Objectives
  3. Pilot Guidelines/Standards
  4. Pilot Project Milestones
  5. Use Case Template


Goal Of The Initiative

To explore the use of ChatGPT and GitHub Copilot/X in the development process and create general guidelines, standards, and feedback on the effective/efficient use and acknowledgment of AI tools.

Research has shown that ChatGPT and GitHub Copilot can help developers write code more efficiently and accurately. For example, ChatGPT can assist with natural language processing tasks, such as summarizing text, answering questions, and generating text. GitHub Copilot, on the other hand, uses machine learning models to suggest code snippets and even whole functions based on the context of the code being written.

However, there are also potential risks and limitations associated with using these tools. For instance, ChatGPT can generate biased or inappropriate text if it is trained on biased or inappropriate data. GitHub Copilot may suggest code that is not optimized or secure, which can lead to software bugs or vulnerabilities.

To address these concerns, it is important for users to understand the capabilities and limitations of the tools. This can include training on how to evaluate the quality of the suggestions provided by the tools, how to review the code generated by the tools, and how to incorporate these tools into the software development process

Outcomes And Objectives

The main objectives and outcomes are the following:

  • Capture general use of the tools during the pilot by developers/engineers/consultants

  • Capture capabilities of ChatGPT and GitHub Copilot specific to organizational domain.
    • Capture and Define use cases where most appropriate with notes.
    • Capture general poll/data on use, effectiveness, etc.

  • Understand metrics around effectiveness.
     

  • Capture and Define limitations and potential risks of use (PHI/Security/Specific Organizational IP)

  • Define some standards/ethics/guidelines around the use of the tools

Pilot Guidelines/Standards

Some specific standards/rules at the outset of the pilot to be adhered to:

  • ChatGPT/AI Tools are still just programs and tools. While tools should help make some tasks and coding easier and to take less time, it is not a solution for everything and the developer/engineer/user, still needs to code, test, understand, and do the work, even if that involves working with AI tools. These are still programs and tools. It is like a camera with AI to help make the image better. You still need the photographer.

  • At the end of the day, the code is yours. While AI tools can help development they are only part of the solution, and like any other tool, is guided by the user. You are responsible for the code, including the understanding of that code (vs just copy/paste).

  • Do not send in any PHI information.

  • Use judgement on any code/data/information being used to create a solution, document, etc.
     
  • Efficiency in code should only be a part of the equation in assigning and taking on more work.

  • The use of AI tools should help us be better developers, programmers, and humans.


Pilot Project Milestones

  • Select the users of the tools for the pilot program

  • Create and define use cases and templates for user input

    • Create an initial set of use cases for ChatGPT/Other OpenAI technologies, and GitHub Copilot. These can be both general and unique to specific technology domains.

    • Create a template for each user to be able to add in their own use case.
       
    • Set schedule/guidelines for when these are updated.

  • Incorporation of the tools into the software development process.
    • This will include setting up paid accounts for each of the developers

  • Initial meeting to walk through different scenarios for use at the beginning of the project

  • One month check-in

  • Two month final check-in

  • Sharing and summary of results internally

  • Standardizing guidelines, rules of use, documentation, and any trained data/models where appropriate

  • Sharing and summary of results to the rest of the IS.

  • Follow up conversations to other tools/phases


Use Case Template

Below is a general list of use cases and a sample table to store information in for each user. Rows could be deleted as needed, and more specific examples could be documented by each user in the pilot program (e.g. "Had bug in code and fixed it").

Use Case Category Was This Used For A Specific Project/Ticket? Did It Save Time? Can you give a percentage (only)
Ask To Create Code You Know Testing


Ask To Create Code You Don't Know Testing


Creating Unit Tests Testing


Code Review Testing


Creating CSS/HTML Frontend Development


Creating Javascript and HTML code together Frontend Development


Creating C# Code Backend Development


Creating Python Code Backend Development


Creating SQL Code Database Development


Creating Excel Function, DAX, Macro Data Analysis


Make Script/Code Run More Efficiently Performance Optimization


Creating Templates For X Code Development Workflow


Explain Code To Me General



Other Information For Consideration 

 

Sunday, April 16, 2023

Creating A Simple Ethereum Token And Deploying In Remix (Ethereum's Browser Based IDE)

If you wanted to dabble in Solidity and Ethereum tokens, you can create a simple token that you can send to you and your friends, or for anything else. Once a wallet has the tokens, while you can have a smart contract that trades Eth for your token, you can just give them away as well, or if you wanted to, have them go through an off-chain process (like a registration on a web site) and then send them the tokens from the main account (which you could automate as well). 

Here's the contract to create a simple token (and yes, this is using an older version, but it works for this simple token and speaks backwards compatibility).

pragma solidity ^0.4.16;

interface tokenRecipient {
    function receiveApproval(address _from, uint256 _value, address _token, 
 bytes _extraData) public;
    }

contract AnhAnhTokenv1 {
    string public name;
    string public symbol;
    uint8 public decimals = 18;
    uint256 public totalSupply;

    mapping (address => uint256) public balanceOf;
    mapping (address => mapping (address => uint256)) public allowance;

    event Transfer(address indexed from, address indexed to, uint256 value);

    function AnhAnhTokenv1 (
        uint256 initialSupply,
        string tokenName,
        string tokenSymbol
    ) public {
        totalSupply = initialSupply * 10 ** uint256(decimals);
        balanceOf[msg.sender] = totalSupply;
        name = tokenName;
        symbol = tokenSymbol;
    }

    function _transfer(address _from, address _to, uint _value) internal {
        // Prevent transfer to 0x0 address. Use burn() instead
        require(_to != 0x0);
        // Check if the sender has enough
        require(balanceOf[_from] >= _value);
        // Check for overflows
        require(balanceOf[_to] + _value > balanceOf[_to]);
        // Save this for an assertion in the future
        uint previousBalances = balanceOf[_from] + balanceOf[_to];
        // Subtract from the sender
        balanceOf[_from] -= _value;
        // Add the same to the recipient
        balanceOf[_to] += _value;
        Transfer(_from, _to, _value);
        // Asserts are used to use static analysis to find bugs in your code. 
// They should never fail
        assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
    }

    function transfer(address _to, uint256 _value) public {
        _transfer(msg.sender, _to, _value);
    }

}

The program creates a basic ERC-20 token with some additional functions and interfaces. Here are some if the main pieces of code to understand.

1. The interface "tokenRecipient" allows external contracts to interact with the token contract, specifically through a function called "receiveApproval".

2. The beginning variables are used to help set values when you are deploying, and creating the token (in the constructor). You'll see these in Remix when you deploy your contract.

3. "balanceOf" is a key/value pair that maps addresses to their balances, which anyone can check. "allowance" as a data structure works similar but the value is another data structure of addresses and values as it checks token that one address has allowed another address to spend on their behalf.

4. The event "Transfer" is emitted to the blockchain when tokens are transferred.

The contract can go anywhere (you can save as a text file or more specifically a ".sol" file) Ultimately though you will put it into Remix.

Compile And Deploy

Got to https://remix.ethereum.org. When you first open it you will see the menu on the left and other information in the main window. You want to focus on the left menu and click on the top icon (which is the File Explorer)

Right-click afterwards on "contracts" and select "New File" from the menu.

You will get a box in contracts to create the file name. Name it "MyTokenTest.sol" and then paste in the contract. 

 
Once you have the file created with the code click on the third menu option which is Solidity compiler. Once you get to that page, make sure you have selected the same compiler version as in the code (sometimes Remix might say it is updating it and it may get close but you can choose the specific version).

After that - you can click on the "Compile MyTokenTest.sol" button and it should compile without any issues which is indicated by the green check mark, versus any errors which you would see under the Compilation Details section. As everything has compiled and is looking good, the only thing left to do is deploy it to a test network! 

To deploy the contract click on the menu item below the compiler:

When you first go to that screen the "ENVIRONMENT" input is set to Remix. 

You want to change that to be MetaMask and then connect to your wallet and select the network (a test network) and an account that has some ether in it.

Next to the orange Deploy button select the down arrow and you will see the parameters to fill in for your token:

Initial supply is the amount you want of your tokens without commas: 1000000.

Token name is the name of the token: Anh Anh Token

And the token symbol is: AANHTI.


Everything else can be left the same and then just press on the transact button and MetaMask will open, confirming the transaction--which is creating a new contract on the Ethereum test blockchain. Remix will then also show the log as well.

After the transaction is complete you will see a line in your wallet like this:


When you click on that entry you can click to view the entry on the "blockchain explorer" (which is Etherscan). 

The entry should look similar to the one below:


The From should be the address you were connected to when you deployed it in Remix. When you click on the To link that will take you to the Contract Address for the token you created (tokens can only be created via smart contracts). That page will show you information about the deployment/transaction as well as to drill into your token.

It's not the most advanced contract, but it's an ERC-20 token and everything works like it should. You can check out the actual token for this post here: https://goerli.etherscan.io/address/0xf3ab79837d63c4105f15b4d777c407d176c1760b

Saturday, April 15, 2023

Quick Bytes: Generate A QR Code

Some quick code to generate a QR code image with HTML and Javascript

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>QR Code Generator</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/qrious/4.0.2/qrious.min.js"></script>
</head>
<body>
    <form>
        <label for="qr-text">Enter text to generate QR code:</label>
        <input type="text" id="qr-text" name="qr-text">
        <button type="button" onclick="generateQRCode()">Generate QR Code</button>
    </form>
    <canvas id="qr-code"></canvas>
    <script>
        function generateQRCode() {
            var text = document.getElementById("qr-text").value;
            var qr = new QRious({
                element: document.getElementById("qr-code"),
                value: text,
                size: 300 // Change the size to 300 pixels
            });
        }
    </script>
</body>
</html>

A SharePoint JSON Example For Adding In A Record To A List

 
I've been involved in more projects with SharePoint where different stakeholders want to use SharePoint for a front-end but want to get data from different data sources, typically from JSON data, so it makes it easy to help transform that data.

One of the easier ways to add data to a SharePoint List is via JSON with the key/values with a few rules to follow:

  1. If a column name is not found, the post will error out.
  2. The column name has to be the actual column name in the List.
  3. For simple types (see the example of Title and FirstName) it's just a key/value pairing.
  4. For complex types you have to include the __metadata information for each column and the type.

See the example below. 

{
  "__metadata": {
    "type""SP.Data.NewsReservationList_x0020_Request_x0020_NewEntry"
  },

  "Title""New 4:30 Reservation",
  "FirstName""Ginny",
  "LastName""Joe",

  "Time": {
    "__metadata": {
      "type""Collection(Edm.String)"
    },
    "results": [
      "4:30 pm - 6 pm"
    ]
  },

  "HearAboutUs": {
    "__metadata": {
      "type""Collection(Edm.String)"
    },
    "results": [
      "Advertisement",
      "Family"     ]
  }
}

What can be tricky at first is seeing a SharePoint List with one value, even though it can handle more, and thinking it's not a complex type, when it really is.