How to integrate with Canada Post AddressComplete API  

Canada Post AddressComplete API allows a user to search for an address within Canada and other countries. Within Canada results can be in both English and French languages. There are two ways to invoke Canada Post API: 

  • To embed css and JavaScript flies that can be copy and pasted from the Canada Post website 
  • To directly call Canada Post API 

API setup prerequisites 

This API Key is for all intents and purposes public, since it can be easily discovered by looking at the API calls in the Network tab in a browser’s developer tools. What prevents this API Key from being used by 3rd parties is assigning it to particular URLs that it can be called from and adding rate limiting and other options as discussed here

Embedded css and JavaScript files 

<head> 

<link rel="stylesheet" type="text/css" href="https://ws1.postescanada-canadapost.ca/css/addresscomplete-2.30.min.css?key=<Your API key comes here>" /> 

<script type="text/javascript" src="https://ws1.postescanada-canadapost.ca/js/addresscomplete-2.30.min.js?key=<Your API key comes here>"></script> 

<script type="text/javascript"> 

var fields = [ 

{ element: "street", field: "Line1" }, 

{ element: "city", field: "City", mode: pca.fieldMode.POPULATE }, 

{ element: "province", field: "ProvinceName", mode: pca.fieldMode.POPULATE }, 

{ element: "postcode", field: "PostalCode" }, 

{ element: "country", field: "CountryName", mode: pca.fieldMode.COUNTRY } 

], 

options = { 

key: "YD42-FH68-UZ69-CY67" 

}, 

control = new pca.Address(fields, options); 

</script>  

... 

</head>

Where the css link provides the styling for the Canada Post API script added in the script tag and the second script provides the mapping from the form fields in which you want to use Address Search to the existing fields in the Canada Post API script. More details about how the mapping is done can be found here

Direct call to Canada Post API 

It is also possible to integrate directly with the Canada Post API using their official documentation by using two Find and Retrieve endpoints they expose. More details about each endpoint will be provide below. 

Address Lookup Flow 

Possible search flow scenarios 

 Scenario First endpoint call Next Action (call)  Result Notes 
Look up of a single existing address Find Retrieve Detailed address returned by the Retrieve request  
Look up of a street or an apartment building address Find Find with LastId value from the first call List of houses/apartments In this case there is a need to issue additional Retrieve request to get a detailed address. 
Look up of a specific address by ID from Find request result Retrieve N/A Detailed address returned by the Retrieve request  

Find request 

https://ws1.postescanada-canadapost.ca/addresscomplete/interactive/find/v2.10/json3.ws

Find request endpoint is described in this official page. Its purpose is to look up addresses similar to the search term provided by the user. This endpoint has the following parameters 

NAME Mandatory TYPE DEFAULT DESCRIPTION Notes 
Key Yes String  API Key  
SearchTerm Yes String  The search term to find. If the LastId is provided, the SearchTerm searches within the results from the LastId. URL encoded 
LastId No String  The Id from a previous Find or FindByPosition. URL encoded 
Country No String CAN The name or ISO 2 or 3 character code for the country to search in. Most country names will be recognised but the use of the ISO country code is recommended for clarity.  
LanguagePreference No String en The 2 or 4 character language preference identifier e.g. (en, en-gb, en-us etc).  
MaxSuggestions No Integer The maximum number of autocomplete suggestions to return.  

It is possible to submit request to this endpoint for free using Canada Post website

Example request: 

https://ws1.postescanada-canadapost.ca/AddressComplete/Interactive/Find/v2.10/json3.ws?Key=<your< API Key comes here>&SearchTerm=390&Country=CAN

Response body 

https://ws1.postescanada-canadapost.ca/AddressComplete/Interactive/Find/2.1/json.ws?key=zz99-jd77-nf54-xw26&SearchTerm=234%20Drinkwater%20St

Response

{
    "Items": [
        {
            "Id": "CA|CP|ENG|ON-SUDBURY-DRINKWATER_ST-234",
            "Text": "234 Drinkwater St",
            "Highlight": "0-3,4-17",
            "Cursor": "0",
            "Description": "Sudbury, ON, P3E 3E5 - 7 Addresses",
            "Next": "Find"
        },
        {
            "Id": "CA|CP|A|802566926",
            "Text": "234 Drinkwater St",
            "Highlight": "0-3,4-17",
            "Cursor": "0",
            "Description": "Sudbury, ON, P3E 3E5",
            "Next": "Retrieve"
        }
    ]
}
https://ws1.postescanada-canadapost.ca/AddressComplete/Interactive/Find/2.1/json.ws?key=zz99-jd77-nf54-xw26&SearchTerm=234%20Drinkwater%20St&LastId=CA%7CCP%7CENG%7CON-SUDBURY-DRINKWATER_ST-234

Response

{
    "Items": [
        {
            "Id": "CA|CP|A|9494373",
            "Text": "1-234 Drinkwater St",
            "Highlight": "",
            "Cursor": "0",
            "Description": "Sudbury, ON, P3E 3E5",
            "Next": "Retrieve"
        },
        {
            "Id": "CA|CP|A|17427664",
            "Text": "2-234 Drinkwater St",
            "Highlight": "",
            "Cursor": "0",
            "Description": "Sudbury, ON, P3E 3E5",
            "Next": "Retrieve"
        },
        {
            "Id": "CA|CP|A|17427672",
            "Text": "6-234 Drinkwater St",
            "Highlight": "",
            "Cursor": "0",
            "Description": "Sudbury, ON, P3E 3E5",
            "Next": "Retrieve"
        },
        {
            "Id": "CA|CP|A|22742122",
            "Text": "9-234 Drinkwater St",
            "Highlight": "",
            "Cursor": "0",
            "Description": "Sudbury, ON, P3E 3E5",
            "Next": "Retrieve"
        }
    ]
}
NAME TYPE DESCRIPTION VALUES EXAMPLE 
Id String The Id to be used as the LastId with the Find method.  CAN|PR|X247361852|E|0|0 
Text String The found item.  2701 Riverside Dr, Ottawa, ON 
Highlight String A list of number ranges identifying the characters to highlight in the Text response (zero-based start position and end).  0-2,6-4 
Cursor Integer A zero-based position in the Text response indicating the suggested position of the cursor if this item is selected. A -1 response indicates no suggestion is available.  
Description String Descriptive information about the found item, typically if it’s a container.  102 Streets 
Next String The next step of the search process. Find or Retrieve Retrieve 

Example of response 

{
      "Items": [
         {
            "Id": "CA|CP|A|17427672",
            "Text": "6-234 Drinkwater St",
            "Highlight": "",
            "Cursor": "0",
            "Description": "Sudbury, ON, P3E 3E5",
            "Next": "Retrieve"
        },
        {
            "Id": "CA|CP|A|22742122",
            "Text": "9-234 Drinkwater St",
            "Highlight": "",
            "Cursor": "0",
            "Description": "Sudbury, ON, P3E 3E5",
            "Next": "Retrieve"
        }   
    ] 
}

Since we are talking about web service here the errors that it returns are returned with 200 response while the error itself is contained in the body of the response. Details about all possible errors can be found on Canda Post website

{
    "Items": [
                {
                        "Error": "5",
                        "Description": "Request not allowed from this URL",
                        "Cause": "The request was disallowed from the URL.",
                        "Resolution": "Check the security settings on the key first. If they look fine, please contact 
                        support as it may be from a URL on our blacklist."        
        }    
    ] 
}

Retrieve endpoint

https://ws1.postescanada-canadapost.ca/addresscomplete/interactive/retrieve/v2.11/json3.ws

Retrieve endpoint returns the full address details based on the Id, which is returned as a result of the Find request. 

As was mentioned in the possible flows section above, initial Find request returns a list of addresses that closely match the search term used by the user. Each address contains an Id field. This Id should be used to issue Retrieve request. You can try the request for free on Canada Post website

Parameters 

Each request to the web service requires the following parameters. You can create any number of keys, each of which can be reported on individually and have specific security settings. 

NAME TYPE Mandatory DESCRIPTION DEFAULT EXAMPLE Notes 
Key String Yes The key to use to authenticate to the service.  AA11-AA11-AA11-AA11  
Id String Yes The Id from a Find method to retrieve the details for.  CAN|1520704 Should be URL encoded 

Example of the request 

https://ws1.postescanada-canadapost.ca/AddressComplete/Interactive/Retrieve/2.11/json.ws?key=tf36-ku97-ab94-zc85&Id=CA%7CCP%7CA%7C9494373

NAME TYPE DESCRIPTION VALUES EXAMPLE 
Id String    
DomesticId String    
Language String    
LanguageAlternatives String    
Department String    
Company String    
SubBuilding String    
BuildingNumber String    
BuildingName String    
SecondaryStreet String    
Street String    
Block String    
Neighbourhood String    
District String    
City String    
Line1 String    
Line2 String    
Line3 String    
Line4 String    
Line5 String    
AdminAreaName String    
AdminAreaCode String    
Province String    
ProvinceName String    
ProvinceCode String    
PostalCode String    
CountryName String    
CountryIso2 String    
CountryIso3 String    
CountryIsoNumber Integer    
SortingNumber1 String    
SortingNumber2 String    
Barcode String    
POBoxNumber String    
Label String    
DataLevel String  Unknown
Premise
RangedPremise
Street
City 
 

Example of a response 

{
    "Items": [
        {
            "Id": "CA|CP|A|9494373",
            "DomesticId": "9494373",
            "Language": "ENG",
            "LanguageAlternatives": "ENG,FRE",
            "Department": "",
            "Company": "",
            "SubBuilding": "1",
            "BuildingNumber": "234",
            "BuildingName": "",
            "SecondaryStreet": "",
            "Street": "Drinkwater St",
            "Block": "",
            "Neighbourhood": "",
            "District": "",
            "City": "Sudbury",
            "Line1": "1-234 Drinkwater St",
            "Line2": "",
            "Line3": "",
            "Line4": "",
            "Line5": "",
            "AdminAreaName": "",
            "AdminAreaCode": "",
            "Province": "ON",
            "ProvinceName": "Ontario",
            "ProvinceCode": "ON",
            "PostalCode": "P3E 3E5",
            "CountryName": "Canada",
            "CountryIso2": "CA",
            "CountryIso3": "CAN",
            "CountryIsoNumber": "124",
            "SortingNumber1": "",
            "SortingNumber2": "",
            "Barcode": "",
            "POBoxNumber": "",
            "Label": "1-234 Drinkwater St\nSUDBURY ON P3E 3E5\nCANADA",
            "Type": "Residential",
            "DataLevel": "Premise",
            "AcIlrc": "R",
            "AcUm": "1"
        },
        {
            "Id": "CA|CP|A|9494373",
            "DomesticId": "9494373",
            "Language": "FRE",
            "LanguageAlternatives": "ENG,FRE",
            "Department": "",
            "Company": "",
            "SubBuilding": "1",
            "BuildingNumber": "234",
            "BuildingName": "",
            "SecondaryStreet": "",
            "Street": "Rue Drinkwater",
            "Block": "",
            "Neighbourhood": "",
            "District": "",
            "City": "Sudbury",
            "Line1": "1-234 Rue Drinkwater",
            "Line2": "",
            "Line3": "",
            "Line4": "",
            "Line5": "",
            "AdminAreaName": "",
            "AdminAreaCode": "",
            "Province": "ON",
            "ProvinceName": "Ontario",
            "ProvinceCode": "ON",
            "PostalCode": "P3E 3E5",
            "CountryName": "Canada",
            "CountryIso2": "CA",
            "CountryIso3": "CAN",
            "CountryIsoNumber": "124",
            "SortingNumber1": "",
            "SortingNumber2": "",
            "Barcode": "",
            "POBoxNumber": "",
            "Label": "1-234 Rue Drinkwater\nSUDBURY ON P3E 3E5\nCANADA",
            "Type": "Residential",
            "DataLevel": "Premise",
            "AcIlrc": "R",
            "AcUm": "1"
        }
    ]
}
ERROR DESCRIPTION CAUSE RESOLUTION 
1001 Id Invalid The Id parameter supplied was invalid. Try again, using only IDs from the Find services. 
1002 Not Available This record contains data that is not available on your account. Please contact support to upgrade your account. 

Example of an error response 

{
        "Items": [
                {
                        "Error": "3",
                        "Description": "Account out of credit",
                        "Cause": "Your account is either out of credit or has insufficient credit to service this request.",
                        "Resolution": "Please check your account balance and top it up if necessary."        
        }    
    ] 
}

References 

This is a github repository containing React with classes implementation of two possible ways to integrate with Canada Post AddressComplete API as was explained before. Pay attention that to install the dependencies there is a need to use yarn

How to solve programming tasks with GPT powered chatbot

Photo by D koi on Unsplash

Code generation to the rescue

As you probably have heard by this time ChatGPT a machine learning based chatbot created by OpenAI is very famous. It is based on Generative Pretrained Transformer model, hence, GPT in short. It’s quite successful in various tasks ranging from text summarization, essays generation to questions answering. But did you know that it can also generate working code in various programming languages? If you didn’t then this post will provide you with some ideas to try.

Task at hand

For example, in the JSON Crack online tool below you can see how such a list of objects can look like

To summarize what needs to be done is as follows

Using Java Stream API approach

Java 8 version introduced a powerful Streams API that allows processing of collections in a functional way. For example, it is possible to filter, apply mapping or sorting to a collection in a single line of code using a declarative syntax somewhat similar to SQL. So, accomplishing the task of sorting a list of objects that have a createdDate field of Date type is quite simple and if you google how to do it you’ll find a number of solutions.

For example, this is how it can be done based on the Stack Overflow answer.

List<Order> orders = list.stream().
                        sorted(comparing(Order::getCreatedDate).
                        collect(Collectors.toList());

First prompt

Write a java code to sort a list of objects while converting a string field to date type

and this is the solution that the Bing chatbot provided


Certainly! Here’s an example of a Java code snippet that sorts a list of objects while converting a string field to date type:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<YourObject> yourList = new ArrayList<>();
        // Add objects to yourList

        // Sort the list based on the string field "dateString"
        Collections.sort(yourList, new Comparator<YourObject>() {
            @Override
            public int compare(YourObject o1, YourObject o2) {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                try {
                    Date date1 = dateFormat.parse(o1.getDateString());
                    Date date2 = dateFormat.parse(o2.getDateString());
                    return date1.compareTo(date2);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                return 0;
            }
        });

        // Print the sorted list
        for (YourObject obj : yourList) {
            System.out.println(obj);
        }
    }
}

class YourObject {
    private String dateString;

    public String getDateString() {
        return dateString;
    }

    public void setDateString(String dateString) {
        this.dateString = dateString;
    }

    // Add other fields and methods as needed
}

In this example, we have a list of objects of type YourObject that contains a string field called dateString. We want to sort the list based on this field, treating it as a date.

To achieve this, we use the Collections.sort() method and provide a custom Comparator implementation. Inside the compare() method, we parse the dateString of each object into a Date object using a SimpleDateFormat. We then compare the two dates using the compareTo() method and return the result.

Please note that you need to replace YourObject with the actual class name and modify the code according to your specific requirements.

Let me know if you need any further assistance!

Second more nuanced prompt

write code to sort a list of objects while converting a string field to date type using java stream api

Certainly! Here’s an example of a Java code snippet that sorts a list of objects while converting a string field to date type using the Java Stream API:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<YourObject> yourList = new ArrayList<>();
        // Add objects to yourList

        // Sort the list based on the string field "dateString" using Java Stream API
        yourList.sort(Comparator.comparing(obj -> {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            try {
                Date date = dateFormat.parse(obj.getDateString());
                return date;
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return null;
        }));

        // Print the sorted list
        yourList.forEach(System.out::println);
    }
}

class YourObject {
    private String dateString;

    public String getDateString() {
        return dateString;
    }

    public void setDateString(String dateString) {
        this.dateString = dateString;
    }

    // Add other fields and methods as needed
}

In this example, we have a list of objects of type YourObject that contains a string field called dateString. We want to sort the list based on this field, treating it as a date.

To achieve this using the Java Stream API, we use the sort() method of the List interface and provide a lambda expression as the comparator. Inside the lambda expression, we parse the dateString of each object into a Date object using a SimpleDateFormat. We then return the parsed date for comparison.

Please note that you need to replace YourObject with the actual class name and modify the code according to your specific requirements.

Let me know if you need any further assistance!

Testing the generated code almost as is in an online Java compiler

Well, that last answer was what I needed. We can take it and check that it can run almost as is in an online Java compiler. I made a couple of small adjustments in the generated code:

  • I instantiated three objects with dateString populated.
  • I added these objects to a list and
  • I adjusted println function to print the dateString field, instead of the object itself.

This is how it looked after running

// Online Java Compiler
// Use this editor to write, compile and run your Java code online

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<YourObject> yourList = new ArrayList<>();
        // Add objects to yourList
        YourObject obj1 = new YourObject();
        obj1.setDateString("2023-09-01");
        
        YourObject obj2 = new YourObject();
        obj2.setDateString("2022-07-02");
        
        YourObject obj3 = new YourObject();
        obj3.setDateString("2021-08-06");
        
        yourList.add(obj1);
        yourList.add(obj2);
        yourList.add(obj3);

        // Sort the list based on the string field "dateString" using Java Stream API
        yourList.sort(Comparator.comparing(obj -> {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            try {
                Date date = dateFormat.parse(obj.getDateString());
                return date;
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return null;
        }));

        // Print the sorted list
        yourList.forEach((obj -> System.out.println(obj.getDateString())));
    }
}

class YourObject {
    private String dateString;

    public String getDateString() {
        return dateString;
    }

    public void setDateString(String dateString) {
        this.dateString = dateString;
    }
    

    // Add other fields and methods as needed
}

Blowing your socks off

How to import code into Commodore 64 emulator

Back to BASIC

Recently, I went to BASICs and I found it fascinating. It is much more interesting programming paradigm then compiled languages development as C like languages since you can program in BASIC interpreter and in assembly at once and get feedback instantly. Also, 6502 CPU is quite easy to understand and memory mapping of the 6502 is also straightforward and interesting to play with.

How can you do it?

Prerequisites

Let’s do it

  • Extract the zip file where you want it and review the contents of the folder

  • Open Windows Command Prompt (aka cmd).
  • Run the command below to convert the text file to prg format.
C64List basic.txt -prg

Now let’s go to the Commodore 64 online emulator website and import our file.

Below comes the video of the process above.

Back to BASICs. Commodore 64 BASIC V2.

Fast-forward to nowadays, I continue to be interested in how hardware and software work and watched quite a few reverse engineering videos on YouTube, like Apollo Guidance Computer restoration series on CuriousMarc channel and others. Due to this YT algorithm suggests me similar videos. A couples of days ago it suggested me to watch the 27c3: Reverse Engineering the MOS 6502 CPU video about how 6502 CPU was reverse engineered by peeling layers from the chip, taking photographs and then reconstructing actual transistors from the photos. The talk was given by Michael Steil who extensively contributed to documenting everything there is about MOS 6502 CPU and various types of BASIC it ran.
The people who reversed engineered the MOS 6502, Greg James, Brian and Barry Silverman also wrote a
JavaScript visualization of the inner workings of the 6502 as it chugs alone.

It turns out that Michael Steil implemented a C based simulation of the MOS 6502 and hooked it up to the Commodore BASIC emulator to see how it worked. And it worked indeed!

Prerequisites

  • Interest in this topic 🙂
  • Operating System: Linux or Windows 10 with Windows Subsystem For Linux 2 (WSL2)
  • Source control software: git (should come preinstalled on WSL) to be able to check out the implementation of the 6502 CPU and BASIC
  • make tool installed
  • C compiler like, gcc installed

What to expect?

Let’s begin

Install WSL and Ubuntu

Clone GitHub repository

Now, that we have Ubuntu installed let’s download (clone) the MOS 6502 repository from GitHub to be able to build it locally.

  • When you navigated to that repository in GitHub click on the code button in the right upper hand side,
  • and click on copy icon

Create directory to clone repository into

mkdir perfect6502
cd perfect6502
git clone https://github.com/mist64/perfect6502.git
Cloning into 'perfect6502'...
remote: Enumerating objects: 643, done.
remote: Total 643 (delta 0), reused 0 (delta 0), pack-reused 643
Receiving objects: 100% (643/643), 997.31 KiB | 4.96 MiB/s, done.
Resolving deltas: 100% (391/391), done.

Install make and gcc on Ubuntu

sudo apt install make
sudo apt install gcc
make
amc@MINE-LAPTOP-130JJTQ6:~/perfect6502$ make
cc -Werror -Wall -O3   -c -o perfect6502.o perfect6502.c
cc -Werror -Wall -O3   -c -o netlist_sim.o netlist_sim.c
netlist_sim.c: In function ‘getGroupValue’:
netlist_sim.c:390:1: error: control reaches end of non-void function [-Werror=return-type]

To fix this issue there is a need to apply Pull Request (PR) one of the users submitted.

git fetch origin pull/10/head:pr_number10
OBJS+=measure.o

Update Makefile using Windows notepad

explorer.exe .

amc@MINE-LAPTOP-130JJTQ6:~/perfect6502$ make
cc -Werror -Wall -O3   -c -o perfect6502.o perfect6502.c
cc -Werror -Wall -O3   -c -o netlist_sim.o netlist_sim.c
cc -Werror -Wall -O3   -c -o cbmbasic/cbmbasic.o cbmbasic/cbmbasic.c
cc -Werror -Wall -O3   -c -o cbmbasic/runtime.o cbmbasic/runtime.c
cc -Werror -Wall -O3   -c -o cbmbasic/runtime_init.o cbmbasic/runtime_init.c
cc -Werror -Wall -O3   -c -o cbmbasic/plugin.o cbmbasic/plugin.c
cc -Werror -Wall -O3   -c -o cbmbasic/console.o cbmbasic/console.c
cc -Werror -Wall -O3   -c -o cbmbasic/emu.o cbmbasic/emu.c
cc -o cbmbasic/cbmbasic perfect6502.o netlist_sim.o cbmbasic/cbmbasic.o cbmbasic/runtime.o cbmbasic/runtime_init.o cbmbasic/plugin.o cbmbasic/console.o cbmbasic/emu.o
cbmbasic/cbmbasic

What can you do now?

You can do even more pretty trick using BASIC to print “Hello, world!” in Assembly code. I saw this implementation in the “Hello World” on Commodore 64 in Assembly Language, Machine Code video.

You can watched how it worked in real time below

Some useful commands to know

PRINT CHR$(147)
NEW
SYS 64738
LIST

To update particular line there is a need to retype it in this emulator, while in other emulators you can edit them. As you can see on the C64 online emulator

SUMMARY

REFERENECES

Real examples of inventions. Inventions are all around us.

Some definitions

This post is another one in the series of posts about Inventions and Theory of Inventive Problem Solving (abbreviated in Russian as TRIZ). First, I’d like to call it Inventiveness Theory for short and I’ll use it interchangeably with TRIZ. Because I find it very strange that the Russian acronym ТРИЗ was translated into English as TRIZ and used throughout. Also the Theory of Inventive Problem Solving sounds very cryptic and confusing to an English speaker to say the least.

Why do I write these posts?

The main urge to right these posts is to share the excitement I have about how Inventiveness Theory can help ordinary people to fell like they have tools to be creative in ways that they could hardly imagine, since inventions and inventors are covered with the mythology of divine inspirations and thousands of trial and error attempts before being able to come up with an invention. Inventiveness Theory shows that it’s not exactly the case and its tools and methodology can direct you to invention using algorithmic approach.

Inventiveness is in every engineering field

In the previous post I provided examples of how Inventiveness Theory uses standard solutions to problems that have similar structure. In this post I’d like to show inventiveness is used in every human endeavor. For example, it’s difficult to think of any progress in engineering, physics, mathematics, chemistry without engineers and scientist constantly resolving contradictions and this way making inventions. If you recall Inventiveness Theory defines invention as a resolution of a contradiction that the problem presents.

When Genrikh Altshuller and Rafael Shapiro first wrote about TRIZ in 1956 article1 most of the examples they provided for the applications of this approach were from mechanical engineering. Later Altshuller and his students worked on more advanced version of Inventiveness Theory which was applied to electrical engineering, chemistry and other fields. Only in recent decades TRIZ was applied to electronics, software engineering and other disciplines.

Since, I have an experience in software development and software testing I’d like to provide most of my examples from these fields. But, I’ll also provide examples from electronics, physics and mathematics. It turns out there could be no science or engineering as we know it without creativity.

Computer Science

Hardware

If we look at Computer Science history we’ll see that it evolved from invention to invention. First, there were mechanical calculators, then came electro-mechanical ones using relays, then electronic computers using lamps. Then with an advent of the semiconductors computers were made with hundreds of transistors later to be replaced with microchips having billions of transistors in one single microcircuit.

Software

Software too had an interesting evolution moving from machine language programming to invention of compilers that allowed a more abstract approach to programming to high level programming languages like Java, Python etc. that allowed programmers to reason almost in a human language while righting programs.

Each of these evolutions wouldn’t be possible without a chain of inventions that scientist and engineers made along the way. For example, let’s take Data Structures and Algorithms topics that any programmer learns to some degree. Sorting algorithms like bubble sort or merge sort are an example of inventions when a problem of sorting data is resolved by various creatives ways, like swapping as in bubble sort or divide and conquer as in merge sort approaches.

What is interesting is that in TRIZ there are a number of ways to resolve a physical contradiction2 which are

  • In space
  • In time
  • In structure
  • By condition

And in Computer Science computational complexity is also measured in space by memory storage requirements and in time it takes for an algorithm to run.

Real example

One concrete example of a contradiction in software engineering is how to be able to update software without the need to rebuild it which requires extensive resources and procedures once it is deployed in production. The contradiction here is that software should have certain parameters to function, but there is a need for these parameters to be changed when required. This particular problem was resolved in structure by extracting parameter values into a dedicated configuration file. This file is loaded by the main program on start up and can be even reloaded on the fly. This approach allows to update the parameters as required without a need to invest additional development time and rebuilding the software.

References

  1. Altshuller, Genrikh, Shapiro, Rafael. “On Psychology of Inventive Creativity”. Questions of Psychology, no. 6, 1956, p. 37-49.
  2. Petrov, Vadimir. TRIZ Basics: Theory of Inventive Problem Solving. Self publishing, Kindle edition 2019, p. 368.

Programming and a school algebra formula finally deciphered

Explanation is due

I guess you also could have had the same feeling when you learnt algebra at school. Some formulas were clear and understandable, but some were cryptic and it was unclear how would anyone derive them. And then the only way to master it is to memorize it. For example, there is this known formula for a difference of squares:

a2 – b2 = (a – b) * (a + b) = a2 + ab – ba – b2 = a2 – b2 , (1)

Then, there was a little bit more cryptic formula for a difference of cubes, which is not that obvious for a regular student:

a3 – b3 = (a – b) * (a2 + ab + b2) = a3 + a2b + ab2 – ba2 – ab2 – b3 = a3 – b3, (2)

So, I think you get it and the next formula is for a4 – b4 ,

a4 – b4 = (a – b) * (a3 + a2b + b2a + b3) = a4 + a3b + a2b2 + ab3 – ba3 – a2b2 – b3a – b4 = a4 – b4 , (3)

And finally, we get to the most cryptic formula that could be frustrating in a school algebra lesson, the formula for a difference of two positive whole numbers (integers) of power of n

an – bn = (a – b) * (an−1 + an−2b + an-3b2 + … + a2bn-3 + abn−2 + bn−1) , (4)

Now, the last formula seems frightening, and most interestingly one could ask, how did in the world anyone derive it? Also, how do you use it correctly?

Take it slow

Let’s look at it in a slow motion. If we look at how we get from formula (1) to formula (4) we can notice that there is some symmetry in the numbers in the second braces in each of the formula.

So, the second braces in formula (1) have

(a + b)

the second braces in formula (2) have

(a2 + ab + b2)

the second braces in formula (3) have

(a3 + a2b + ab2 + b3)

the second braces in formula (4) have

(an−1 + an−2b + an-3b2 + … + a2bn-3 + abn−2 + bn−1)

Do you see it? When there is a2 on the left side there is a corresponding b2 on the right, when there is a2b on the left, there is a corresponding b2a on the right side, etc. So this is the symmetry I am talking about. The general formula is actually a factorization of a polynomial formula. But we can look at it in a different manner, just to understand how to use it properly. The derivation of the general formula is a little bit more complex and can be found here.

One interesting thing to notice is that the sum of powers of each a, b or there multiplication ab in the second braces is always n – 1.

(a + b) = a1 + b1 , i.e. the powers are 1, 1

(a2 + ab + b2) = a2 + a1b1 + b2 , i.e. the powers are 2, 1 + 1, 2

(a3 + a2b + b2a + b3) = (a3 + a2b1 + a1b2 + b3) , i.e. the powers are 3, 2 + 1, 1 + 2, 3

(an−1+ an−2b + an-3b2 + … + a2bn-3 + abn−2 + bn−1), i.e. the powers are n – 1, n – 2 + 1 = n – 1 , n – 3 + 2 = n – 1, 2 + n – 3 = n – 1, etc.

Now, also let’s pay attention that we can treat 1 as 1 = a0 or 1 = b0, and let’s look again at the expressions above

(a + b) = a1b0 + a0b1 ,

(a2 + ab + b2) = a2b0 + a1b1 + a0b2 ,

(a3 + a2b + b2a + b3) = (a3b0 + a2b1 + a1b2 + a0b3),

(an−1+ an−2b + an-3b2 + … + a2bn-3 + abn−2 + bn−1)

= (an−1b0+ an−2b1 + an-3b2 + … + a2bn-3 + a1bn−2 + a0bn−1),

I hope you can see that there is a systematic pattern which is going on here.

Rules of the game

Rule 1: The number of members in the second braces is always as the power of the initial expression, say two for a2 – b2; three for a3 – b3 etc.

Rule 2: The sum of the powers of each member in the second braces is n – 1, which was already shown in the previous examples.

Pay attention that this can be also proven by mathematical induction. But I leave it as an exercise for you.

How to use this formula and how to zip it

Now that we’ve noticed there is a pattern this pattern show us how to use the formula in a simple way without the need in rote memorization or blindly using someone else derivation.

The only thing is to remember that the first braces always have (a – b) and in the second braces the sum of the powers of each member is n -1. Let’s look at the concrete example of a8 – b8.

Let’s start from the second braces, and write each member without powers in accordance to Rule 1. We know there should be n, i.e. 8 such members.

(ab + ab + ab + ab + ab + ab + ab + ab)

Now, let’s use the Rule 2 and add powers to each member in the second braces, remembering that for a‘s, powers start from n – 1 and decrement by 1 for each consecutive a, and for b‘s powers start from 0 power and increment by 1 for each b until n – 1. Applied to our example,

for a‘s: a7, a6, a5, a4, a3, a2, a1, a0

and b‘s: b0, b1, b2, b3, b4, b5, b6, b7

Now, putting these together in the formula we get,

a8 – b8 = (a – b) * (a7b0 + a6b1 + a5b2 + a4b3 + a3b4 + a2b5 + a1b6 + a0b7)

= (a – b) * (a7 + a6b + a5b2 + a4b3 + a3b4 + a2b5 + ab6 + b7).

Zip it

So, now we ready to zip this formula using the math notation for the sum:

a^n - b^n=(a - b)\sum^{n - 1}_{k = 0} a^{(n - 1) - k}{b^k}

where k increments from 0 to n – 1, i.e. 0, 1 , 2, …, n – 1.

An interesting turn of events

What is nice about this formula is the fact that it’s actually a concise description of an algorithm that checks whether a certain string is a palindrome.

The main idea is to take a sequence of letters (an array of characters in programming speak), and then start comparing

  1. First vs. last letter
  2. Second vs. one before last
  3. etc
  4. For each such case above check whether letters are the same. If there is at least one instance when they are not the same, then it’s not a palindrome.

In Java programming language this algorithm could be implemented as follows (run this code in online Java compiler)

public class Main {
  public static void main (String[]args){
    String word = "TENET";
    System.out.println (isPalindrome(word));
  }
  
  static boolean isPalindrome (String word){
    char[] charArray = word.toCharArray();
    int n = charArray.length;
    
    for (int k = 0; k <= n - 1; k++){
    	if (charArray[k] != charArray[(n - 1) - k]){
    	    return false;
    	}
    }
    return true;
  }
}

Let’s it. Take care.

When math powers algorithms it’s entertaining

I think that I already wrote previously that a couple of years ago I bought the Elements of Programming book by Alexander Stepanov and Paul McJones. The issue was that the book content was hard for me to grasp at the time. I can hardly say that I now understand it better, but now I got where the rationale for that book came from and why it was written the way it was. It turns out the Alexander Stepanov as a mathematician was influenced deeply by Abstract Algebra, Group Theory and Number Theory. The elements of these fields of mathematics can be traced in the Elements of Programming clearly. For example, chapter 5 is called Ordered Algebraic Structures and it mentions among other things semigroup, monoid and group, which are elements in Group Theory. Overall, the book is structured somewhat like Euclid’s Elements, since the book starts from definitions, that are later used to build gradually upon in other chapters of the book.

Which brings me to the main topic of this post. By the way, the post is about a different book Alexander Stepanov wrote with Daniel Rose and that book was created by refining the notes for the Four Algorithmic Journeys course that Stepanov taught in 2012 at A9 company (subsidiary of Amazon). The course is available in YouTube and it consists of three parts each having a number of videos and the Epilogue part.

I highly recommend to watch it to anyone who is curious about programming, mathematics and science in general. The course is entertaining and it talks about how programming, or more exactly algorithms that are used in programming, are based on algorithms that were already known thousands of years ago in Egypt, Babylon etc. Alexander Stepanov has a peculiar way of lecturing and I find this way of presentation funny. The slides for the course and the notes that were aggregated in the Three Algorithmic Journeys book draft are freely available at Alexander Stepanov’s site.

So the book which I want to mention is From Mathematics to Generic Programming which was published in 2014 and is a reworked version of the Three Algorithmic Journeys draft. This is how Daniel Rose describes this in the Authors’ Note of the book.

The book you are about to read is based on notes from an “Algorithmic Journeys” course taught by Alex Stepanov at A9.com during 2012. But as Alex and I worked together to transform the material into book form, we realized that there was a stronger story we could tell, one that centered on generic programming and its mathematical foundations. This led to a major reorganization of the topics, and removal of the entire section on set theory and logic, which did not seem to be part of the same story. At the same time, we added and removed details to create a more coherent reading experience and to make the material more accessible to less mathematically advanced readers.

My verdict

As authors mentioned the book is geared towards Generic Programming, but I recommend to read both of them in parallel, since each one complements the other. I think that the Three Algorithmic Journeys is even better than the From Mathematics to Generic Programming (FM2GP). First, it’s free and second, ironically, it’s more generic than the FM2GP book.

What the hack is Rule 30? Cellular Automata Explained

Introduction

If you ask the same question, what is this Rule 30, then you are not alone. This rule is related to one-dimensional Cellular Automata introduced by Stephen Wolfram in 1983 and later described in his A New Kind Of Science book. Even though, I skimmed through this book previously, I was never able to understand what was it all about. It had some neat diagrams, but I didn’t try to understand how the diagrams were generated. This changed a day ago when I watched an interesting interview that Lex Fridman had with Stephen Wolfram, where they discussed among other things Rule 30, which was the one that Wolfram described first. This rule is capable of generating a complex behavior even though the rule itself is very simple to define.

Elementary Cellular Automaton

The Elementary Cellular Automaton consists of a one-dimensional array of cells that can be in just two sates, namely, black or white color. The cellular automaton starts from initial state, and then transition to the next state based on a certain function. The next state of the automaton is calculated based on the color of current cell and its left and right neighbors’ colors. By the way, that transition function, gives its name to the cellular automaton rule, just like Rule 30.

Rule 30 transition function

Current Sate111110101100011010001000
Next state00011110

Where, for example, the binary digits ‘111’ in the first column indicate the black color of the left, current and right cells, and the values, ‘0’ or ‘1’ indicate what will be the color of the current cell in the next state (iteration) of the automaton. If we write down all the the binary values of the next state together as a single 8 digit binary number, which is 00011110 and convert it to a decimal number we get 30, and hence the name of the Rule 30. In a Boolean form this transition function is

(left, current, right) -> left XOR (current OR right)

We’ll use this function later in the C++ implementation of the Rule 30.

This is how the output from Rule 30 looks like after 20 and 100 steps respectively.

source: WolframAlpha

How to generate Rule 30?

It is easy to implement the Rule 30 using a 64 bit integer in C++. The only drawback is that we can get only 32 steps with the implementation below taken from Wikipedia.

Note: If this is a little bit to much for you now, then skip to the next part where we’ll use WolframAlpha to program it for us.

In the code below a 64 bit integer is used to generate an initial state using a bit mask in line 6. Then the outer for loop generates 32 steps of the Rule 30 by applying the transition function in line 19. The inner loop generates the black (using character ‘1’) and white (using character ‘-‘) colors using state bit mask.

#include <stdint.h>
#include <iostream>

int main() {
 // This is our bit mask with the 32 bit set to '1' for initial state
  uint64_t state = 1u << 31;

  for (int i = 0 ; i < 32 ; i++) {

    for (int j = sizeof(uint64_t) * 8 - 1 ; j  >=  0 ; j--) {
      // Here we decide what should be the color of the current cell based on the current state bit mask.
     // Bitwise operator is used to accomplish this efficiently
      std::cout << char(state  >>  j & 1 ? '1' : '-');
    }
    std::cout << '\n';
    
    // This is just the (left, current, right) -> left XOR (current OR right) functioned mentioned previously
   // Bitwise operators  are used to accomplish this efficiently
    state = (state >> 1) ^ (state | state << 1);
  }
}

It is possible to run this code in the online C++ compile. Just click on the link and then click on the green Run button at the top of the screen. The result looks similar to below.

The full output for 32 steps looks like this

--------------------------------1-------------------------------
-------------------------------111------------------------------
------------------------------11--1-----------------------------
-----------------------------11-1111----------------------------
----------------------------11--1---1---------------------------
---------------------------11-1111-111--------------------------
--------------------------11--1----1--1-------------------------
-------------------------11-1111--111111------------------------
------------------------11--1---111-----1-----------------------
-----------------------11-1111-11--1---111----------------------
----------------------11--1----1-1111-11--1---------------------
---------------------11-1111--11-1----1-1111--------------------
--------------------11--1---111--11--11-1---1-------------------
-------------------11-1111-11--111-111--11-111------------------
------------------11--1----1-111---1--111--1--1-----------------
-----------------11-1111--11-1--1-11111--1111111----------------
----------------11--1---111--1111-1----111------1---------------
---------------11-1111-11--111----11--11--1----111--------------
--------------11--1----1-111--1--11-111-1111--11--1-------------
-------------11-1111--11-1--111111--1---1---111-1111------------
------------11--1---111--1111-----1111-111-11---1---1-----------
-----------11-1111-11--111---1---11----1---1-1-111-111----------
----------11--1----1-111--1-111-11-1--111-11-1-1---1--1---------
---------11-1111--11-1--111-1---1--1111---1--1-11-111111--------
--------11--1---111--1111---11-11111---1-11111-1--1-----1-------
-------11-1111-11--111---1-11--1----1-11-1-----11111---111------
------11--1----1-111--1-11-1-1111--11-1--11---11----1-11--1-----
-----11-1111--11-1--111-1--1-1---111--1111-1-11-1--11-1-1111----
----11--1---111--1111---1111-11-11--111----1-1--1111--1-1---1---
---11-1111-11--111---1-11----1--1-111--1--11-1111---111-11-111--
--11--1----1-111--1-11-1-1--11111-1--111111--1---1-11---1--1--1-
-11-1111--11-1--111-1--1-1111-----1111-----1111-11-1-1-111111111

Compare the image above to the one generated using WolframAlpha symbolic language in the Wolfram Notebook.

Using WolframAlpha to generate Rule 30

WolframAlpha is a computational knowledge engine developed by Wolfram Research. It is embedded in Mathematica symbolic language and it has a declarative programming style. Which means that you specify what you want to be done instead of how it should be done.

For example, to generate Rule 30 and visualize it one simple writes

ArrayPlot[CellularAutomaton[30, {{1},0}, 64]]

where CellularAutomaton function generates 64 states of the automaton, starting with a one black cell in accordance with the Rule 30 generation function, and ArrayPlot function prints the result.

And the output is

Please follow the this link to the Wolfram Notebook where the various Elementary Cellular Automata Rules are generated.

Summary

Playing with cellular automat rules seems like an interesting game to play, plus doing it using WolframAlpha language is a piece of cake.

Better understanding with Optimization for Machine Learning

Long awaited book from Machine Learning Mastery

Recently, I’ve been reading the new Optimization for Machine Learning book from the Machine Learning Mastery written by Jason Brownlee. It just so happened that I read it fully from start to end, since I was one of the technical reviewers of the book. The book was interesting to read thanks to a number of ingredients.

As always Jason was able to write an engaging book with practical advice that can be actioned right away using open source software on Linux, Windows or MacOS. Apart from this the book has just enough clearly explained theoretical material so that even beginning machine learning practitioners can play with optimization algorithms described in the book.

What I liked and what surprised me in the book

Personally, I think it was while reading and working with this book, that I truly understood what an optimizations is. How it is used in machine learning. What is an optimization algorithm, like gradient descent and how to implement one from scratch. I also very much enjoyed the chapter about Global Optimization with various types of Evolution Algorithms. What was funny, that about two weeks after I finished reading the book I came across Donald Hoffman’s The Interface Theory of Perception with relation to consciousness which is based on The Theory of Evolution by Natural Selection. For example, one of his papers written with colleagues namely Does evolution favor true perception? provides an example of Genetic Algorithm (GA) which very much resembles the GA in Chapter 17 of the book. It is highly recommended reading for anyone interested in how consciousness arises in the mind. By the way, does it?

Overall

The Optimization for Machine Learning book is what you come to expect from Machine Learning Mastery books. It’s interesting, it’s practical and it makes you understand what is that you are doing in Machine Learning. As always, each chapter has extensive references to tutorials, technical papers and books on machine learning. So don’t wait and start reading it, maybe you’ll come up with a new theory of how consciousness emerges in the mind.

References

Donald D. Hoffman, Manish Singh, Justin Mark, “Does evolution favor true perceptions?”, Proceedings Volume 8651, Human Vision and Electronic Imaging XVIII; 865104 (2013)

Playing with the 3D Donut-shaped C code in JavaScript

Background

Having seen a short YouTube video by Lex Fridman about Donut-shaped C code that generates a 3D spinning donut where in comments he encouraged to look at the code and play with I did just that.

But before this, I went to the Donut math: how donut.c works link where the author of that code Andy Sloane described how he came from geometry and math to implementation of the donut in C.

The Andy Sloane’s tutorial has two visualizations that you can launch and also the JavaScript implementation of the donut. One visualization is of ASCII donut while another one uses <canvas>: The Graphics Canvas element to create a visualization.

Playing with the code

The easiest way to play with the 3D spinning donut in JavaScript is to use JSFiddle online editor. When the editor is opened you see four main areas, just like in almost any other JS editor, which are HTML, CSS, JavaScript and Result.

To be able to start playing with donut code like crazy we need to do a number of things.

First

First, there is a need to create a basic HTML page with a number of buttons, a <pre> tag to store ASCII generated donut and a <canvas> tag to be able to show another type of donut animation. To do this just copy and paste into HTML area of JSFiddle editor the code below

<html>
  <body>
    <button onclick="anim1();">toggle ASCII animation</button>
    <button onclick="anim2();">toggle canvas animation</button>
    <pre id="d" style="background-color:#000; color:#ccc; font-size: 10pt;"></pre>
    <canvas id="canvasdonut" width="300" height="240">
    </canvas>
  </body>
</html>

Second

Second, there is a need to copy and past JS code from Andy’s page or copy and paste the code below into JS area of the JSFiddle editor

(function() {
var _onload = function() {
  var pretag = document.getElementById('d');
  var canvastag = document.getElementById('canvasdonut');

  var tmr1 = undefined, tmr2 = undefined;
  var A=1, B=1;

  // This is copied, pasted, reformatted, and ported directly from my original
  // donut.c code
  var asciiframe=function() {
    var b=[];
    var z=[];
    A += 0.07;
    B += 0.03;
    var cA=Math.cos(A), sA=Math.sin(A),
        cB=Math.cos(B), sB=Math.sin(B);
    for(var k=0;k<1760;k++) {
      b[k]=k%80 == 79 ? "\n" : " ";
      z[k]=0;
    }
    for(var j=0;j<6.28;j+=0.07) { // j <=> theta
      var ct=Math.cos(j),st=Math.sin(j);
      for(i=0;i<6.28;i+=0.02) {   // i <=> phi
        var sp=Math.sin(i),cp=Math.cos(i),
            h=ct+2, // R1 + R2*cos(theta)
            D=1/(sp*h*sA+st*cA+5), // this is 1/z
            t=sp*h*cA-st*sA; // this is a clever factoring of some of the terms in x' and y'

        var x=0|(40+30*D*(cp*h*cB-t*sB)),
            y=0|(12+15*D*(cp*h*sB+t*cB)),
            o=x+80*y,
            N=0|(8*((st*sA-sp*ct*cA)*cB-sp*ct*sA-st*cA-cp*ct*sB));
        if(y<22 && y>=0 && x>=0 && x<79 && D>z[o])
        {
          z[o]=D;
          b[o]=".,-~:;=!*#$@"[N>0?N:0];
        }
      }
    }
    pretag.innerHTML = b.join("");
  };

  window.anim1 = function() {
    if(tmr1 === undefined) {
      tmr1 = setInterval(asciiframe, 50);
    } else {
      clearInterval(tmr1);
      tmr1 = undefined;
    }
  };

  // This is a reimplementation according to my math derivation on the page
  var R1 = 1;
  var R2 = 2;
  var K1 = 150;
  var K2 = 5;
  var canvasframe=function() {
    var ctx = canvastag.getContext('2d');
    ctx.fillStyle ='#000';
    ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);

    if(tmr1 === undefined) { // only update A and B if the first animation isn't doing it already
      A += 0.07;
      B += 0.03;
    }
    // precompute cosines and sines of A, B, theta, phi, same as before
    var cA=Math.cos(A), sA=Math.sin(A),
        cB=Math.cos(B), sB=Math.sin(B);
    for(var j=0;j<6.28;j+=0.3) { // j <=> theta
      var ct=Math.cos(j),st=Math.sin(j); // cosine theta, sine theta
      for(i=0;i<6.28;i+=0.1) {   // i <=> phi
        var sp=Math.sin(i),cp=Math.cos(i); // cosine phi, sine phi
        var ox = R2 + R1*ct, // object x, y = (R2,0,0) + (R1 cos theta, R1 sin theta, 0)
            oy = R1*st;

        var x = ox*(cB*cp + sA*sB*sp) - oy*cA*sB; // final 3D x coordinate
        var y = ox*(sB*cp - sA*cB*sp) + oy*cA*cB; // final 3D y
        var ooz = 1/(K2 + cA*ox*sp + sA*oy); // one over z
        var xp=(150+K1*ooz*x); // x' = screen space coordinate, translated and scaled to fit our 320x240 canvas element
        var yp=(120-K1*ooz*y); // y' (it's negative here because in our output, positive y goes down but in our 3D space, positive y goes up)
        // luminance, scaled back to 0 to 1
        var L=0.7*(cp*ct*sB - cA*ct*sp - sA*st + cB*(cA*st - ct*sA*sp));
        if(L > 0) {
          ctx.fillStyle = 'rgba(255,255,255,'+L+')';
          ctx.fillRect(xp, yp, 1.5, 1.5);
        }
      }
    }
  }


  window.anim2 = function() {
    if(tmr2 === undefined) {
      tmr2 = setInterval(canvasframe, 50);
    } else {
      clearInterval(tmr2);
      tmr2 = undefined;
    }
  };

  asciiframe();
  canvasframe();
}

if(document.all)
  window.attachEvent('onload',_onload);
else
  window.addEventListener("load",_onload,false);
})();

Third

After HTML and JavaScript areas were populated click on the Run button (as indicated by me with number 1) in the screenshot below and you should see in the Result area on the right two buttons and two donuts (indicated with number 2).

When each button is clicked relevant animation is turned on. Both of them could run in parallel.

This is how it looks like in real-time

Playground

If you want understand the math of how it’s done then first read the explanation by Andy Sloane here. If you want jump right into messing around with the code then stay here.

Need for speed

To change the speed of the animations Ctrl + F in the JSFiddle and search for setInterval function

tmr1 = setInterval(asciiframe, 50);

tmr2 = setInterval(canvasframe, 50);

The second argument controls the speed of rotation of the donut. Increasing it makes it rotate faster and vice versa.

Paint it black

To change the background color of the donut created with the <canvas> animation search for ctx.fillStyle =’#000′;

ctx.fillStyle='#000'; //this is currently black

To change the color of the donut created with the <canvas> animation search for ctx.fillStyle = ‘rgba(255,255,255,’+L+’)’;

ctx.fillStyle = 'rgba(255,255,255,'+L+')'; // update any of the first three arguments which stand for Red, Green, Black in RGB.

See you

There are plenty other things you can try with this code. So why are you waiting? Just do it!