If you have some basic background in programming, or even if you don’t, but want to get some then you can turn to chatbots and in particular to Windows Copilot (I’ll refer to it as Copilot for shortness). You can use Gemini, ChatGPT, Claude etc. if you prefer, and they’ll be as useful. This is what I did just recently when I stumbled upon a post by Dave Plummer at X, where he talked about the need for programmers to understand how compilers produced their output, hence the need to know assembly language. By the way, Dave Plummer developed Windows Task Manager when he was a programmer with Microsoft . He has a YouTube channel where he posts interesting videos related to programming.
Why chatbots can be helpful in this case? First, if you didn’t program in assembly before it can be difficult to approach it. Second, chatbots are very helpful in explaining existing code in any programming language they had in their training data. And, I guess, it means it should know details about most modern programing languages.
Well, next I’ll provide a screenshot of that post, then I’ll show you that chatbot can transcribe the code from an image alone and explain what we are looking at there. The short summary is that post was about binary to ASCII (BTOA) conversion program written in PDP-11 computer assembly. By the way, all these details where extracted by Copilot from the code in the image. Then, I’ve used Copilot to explain to me in detail how the code works to get full understanding of it.
Pay attention, that I use line separator to mark when the response from chatbot has finished.
Original post
I suppose there's a whole class of programmers for whom a compiler is akin to magic, but knowing what's getting emitted and how it works is fundamental to your success over the long haul.
I suppose there’s a whole class of programmers for whom a compiler is akin to magic, but knowing what’s getting emitted and how it works is fundamental to your success over the long haul. Write some assembly. Read the Dragon book on an airplane. AI will still be here when you get back. In five years, anyone capable of structured thought will be able to become a prompt engineer, but only 1% of software developers will actually be able to debug the stuff that comes out the other end. Be the 1%
What did I do next?
As I’ve mentioned I’ve copy and pasted the image in Copilot and asked it to transcribe the code from the image and explain what it’s doing.
Prompt: Transcribe the code from the image and explain (an image was attached as can be seen in the screenshot below). Response:
Below comes a full response.
Here’s the full transcription of the PDP-11 assembly code using MACRO-11 syntax, followed by a detailed explanation: Transcribed Code
.TITLE BTOA ; Program title
.MCALL .PRINT,.EXIT,.TTYOUT ; System macros
HELLOMSG: .ASCIZ /BTOA Example/
.EVEN ; Ensure we're on a word boundary
START: .PRINT #HELLOMSG
MOV #12345., R0 ; Number to convert
JSR PC, BTOA
.EXIT
BTOA:
MOV R0, -(SP) ; Save R0 on stack
MOV R1, -(SP) ; Save R1 on stack
MOV R2, -(SP) ; Save R2 on stack
MOV R0, R1 ; Move number to R1 (low part of dividend)
CLR R0 ; Clear R0 (high part of dividend)
DIV #10., R0 ; Divide R0:R1 by 10, quotient in R0, remainder in R1
TST R0 ; Check if quotient is 0
BEQ PRINT ; If quotient is 0, print digit
JSR PC, BTOA ; Recursive call with quotient
PRINT: ADD #'0, R1 ; Convert remainder to ASCII
MOV R1, R0 ; Move ASCII digit to R0
.TTYOUT R0 ; Print the digit
MOV (SP)+, R2 ; Restore R2
MOV (SP)+, R1 ; Restore R1
MOV (SP)+, R0 ; Restore R0
RTS PC ; Return
.END START
🧠 Explanation
This program converts a binary number (in this case, 12345) to its ASCII decimal representation and prints it to the terminal.
🔹 Header and Setup
.TITLE BTOA: Sets the title of the program.
.MCALL .PRINT,.EXIT,.TTYOUT: Declares macros for printing, exiting, and terminal output.
HELLOMSG: .ASCIZ /BTOA Example/: Defines a null-terminated string.
.EVEN: Ensures the next instruction is aligned on a word boundary.
🔹 Main Routine (START)
.PRINT #HELLOMSG: Prints the greeting message.
MOV #12345., R0: Loads the number 12345 into register R0.
JSR PC, BTOA: Calls the BTOA subroutine to convert and print the number.
.EXIT: Ends the program.
🔹 Subroutine (BTOA)
Saves registers R0, R1, and R2 to the stack.
Sets up for division: moves the number to R1, clears R0 to form a 32-bit dividend.
DIV #10., R0: Divides R0:R1 by 10. Quotient goes to R0, remainder to R1.
TST R0: Tests if quotient is zero.
If yes, go to PRINT.
If not, recursively call BTOA with the quotient.
PRINT: Converts the remainder (digit) to ASCII by adding '0', then outputs it using .TTYOUT.
Restores registers from the stack and returns.
This recursive approach ensures digits are printed in the correct order (most significant to least significant). Would you like to see how this would look in C or another language for comparison?
Let’s try to understand how it works in more detail.
Question: First of all, what is BTOA?
Response:
Great question! 🧠
BTOA stands for Binary To ASCII. It’s a common abbreviation used in programming to describe the process of converting a binary (or numeric) value into its ASCII character representation, typically for display or output purposes.
🔍 What does “Binary to ASCII” mean?
Binary: In this context, it refers to a numeric value stored in binary format (e.g., the number 12345 in machine-readable form).
ASCII: The American Standard Code for Information Interchange — a character encoding standard that maps numbers to printable characters like '0' to '9', 'A' to 'Z', etc.
Okay, now that we know what that mysterious BTOA was how about we understand what happens inside this block of code that resides inside the BTOA function?
MOV R0, R1 ; Move number to R1 (low part of dividend)
CLR R0 ; Clear R0 (high part of dividend)
DIV #10., R0 ; Divide R0:R1 by 10, quotient in R0, remainder in R1
TST R0 ; Check if quotient is 0
BEQ PRINT ; If quotient is 0, print digit
JSR PC, BTOA ; Recursive call with quotient
Also, before jumping to Copilot for help we can see assembly language program that is doing some computation using registers in CPU such as R0 and R1. We can see the data is moved, cleared, a division is done and then there is a conditional logic on lines 5, 6 and 7. In the screenshot it corresponds to lines 22, 23 and 24.
So what is the explanation ? Response:
This block of PDP-11 assembly code is the core of the binary-to-ASCII conversion logic. It performs division by 10 to extract digits from a number and uses recursion to print them in the correct order. Here’s a breakdown of each line:
🔍 Line-by-Line Explanation
18 MOV R0, R1 ; Move number to R1 (low part of dividend)
Copies the number from R0 to R1.
This sets up the 32-bit dividend for division: R0:R1 (high:low).
19 CLR R0 ; Clear R0 (high part of dividend)
Clears R0 to zero.
Now the full dividend is 0:R1, effectively treating the original number as a 32-bit value with high word = 0.
20 DIV #10., R0 ; Divide R0:R1 by 10, quotient in R0, remainder in R1
Performs a 32-bit division of R0:R1 by 10.
After this:
R0 contains the quotient (i.e., number / 10)
R1 contains the remainder (i.e., number % 10), which is the rightmost digit
22 TST R0 ; Check if quotient is 0
Tests if the quotient is zero.
This determines whether there are more digits to process.
23 BEQ PRINT ; If quotient is 0, print digit
If R0 is zero, it means this is the last digit.
Branches to PRINT to output the digit.
24 JSR PC, BTOA ; Recursive call with quotient
If R0 is not zero, it means there are more digits.
Recursively calls BTOA with the quotient in R0, continuing the process.
🧠 Summary
This block:
Extracts the least significant digit of the number.
Uses division and recursion to process digits from most significant to least significant.
Ensures digits are printed in the correct order by printing only after recursion unwinds.
Conclusion
Well, I guess it clarifies a bit what the code is doing. And you probably got a point of how you can use a chatbot to help you understand a piece of code in a programming language you probably never saw and drill down to nitty gritty details of the implementation and really understand how it works.
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
To be able to call Canada Post AddressComplete API there is a need to setup an account with Canada Post which will provide you with an API Key and also allow you to configure particular URLs to be able to issue search requests using that API Key.
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
One way to integrate with Canada Post API is to add the following three tags in the head tag of the index.html page of the project.
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
There can be a number of possible scenarios while using Canada Post AddressCompleet API to search for an address. For example, issuing a Find request will return a list of addresses that are similar to the search term used by a user.
Also, what is important each address in that list contains a Next field which can have one of two options: Find or Retrieve. This field is important when one of the search results is a street that has a number of houses or an apartment building with a number of apartments. In this case such an address will have Next field with Find value.
Possible search flow scenarios
Scenario
First endpoint call
Next Action (call)
Result
Notes
1
Look up of a single existing address
Find
Retrieve
Detailed address returned by the Retrieve request
2
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.
3
Look up of a specific address by ID from Find request result
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
7
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
The response consists of Items list with addresses as elements.
Pay attention, as described in the possible flows above, if returned address element contains Next field with the value Find it means that to get detailed address there is a need to issue additional Find request with the LastId set with the Id value from that address element.
For example,
First Find request with Search Term: 234 Drinkwater St
The response from the web service is a table containing the elements below. Where no items are found, the response will be empty list (although all endpoints specify the columns). If an error occurs, the response will be an error table instead.
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.
0
Description
String
Descriptive information about the found item, typically if it’s a container.
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.
Example of an error response
For example, the general error below is shown when the API Key is not assigned to get requests from a particular URL.
{
"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 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.
The response consists of Items list with two elements: first element is the address in English, second element is the address in French.
Response Fields
The response from the web service is a table containing the elements below. Where no items are found, the response will be empty list (although all endpoints specify the columns). If an error occurs, the response will be an error table instead.
Below are the errors specific to this web service. If an error occurs, an error table like the one below (but containing a single row) will be returned. (Developers should test for a 4-column table with columns “Error”, “Description”, “Cause” and “Resolution”.)
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
For example, the general error below is shown when the account has no money balance to allow for queries.
{
"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.
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
I am a Java developer and recently at work I need to solve a certain task. The task was to sort a list of objects where each object in the list had a date time field. Date time field may look like this: 2023-09-17 20:01:02.23.
For example, in the JSON Crack online tool below you can see how such a list of objects can look like
This task seems quite straightforward when the field is of a Java Date type, but in this case the field was of type String. It means that sorting the objects by this field won’t be correct since the objects will be sorted alphabetically instead of based on date and time. A solution is to convert the String data time field into proper Date type and then to sort the objects.
To summarize what needs to be done is as follows
Iterate over the list of objects and compare objects createdDate field by first converting it from String type to Date type.
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.
The issue was that I wasn’t quite able to find a solution that exactly would solve the issue I had, even though I searched a lot. Then I had an idea. When I played with ChatGPT at OpenAI’s website I also played with code that ChatGPT generated for various languages. So, I went to Microsoft Edge browser and opened Bing Chatbot, powered by GPT-4, and wrote the following
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!
If you try the example above in a Java online compiler you’ll see that it works right away. Isn’t it amazing? The only issue that I wanted to have this solution using Java Stream API, so I rephrased what I wanted to get.
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
Below come a full source code if you need it
// 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
So there you have it. If you are trying to find a solution for a coding issue you face and you don’t find a good example at Stack Overflow or elsewhere, try using GPT-4 based chatbot, for example, Bing and see how it goes. You can be amazed.
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.
The only issue is that I find it tedious to type the code in the Commodore 64 emulator directly. But there is a solution, it is possible to import files in D64, RPG and other formats that the emulator supports. It means that you can write BASIC or assembly code in your favorite editor and then import it.
How can you do it?
To be able to do this it there is a need to convert the text file to a format that is supported by Commodore 64. If you search you’ll be able to find a number of tools that people wrote to do just that. Since I have a PC with Windows 11 so I am using a Windows based tool. This tool is called C64List and it comes in handy to be able to convert BASIC files into text files and vice versa.
Prerequisites
Operating System: Windows
Download and extract C64List tool
(Optional) Review supporting documentation file with a very detailed and helpful
This story begins around 1988-89 when I first saw ZX Spectrum clone based on Zilog Z80 microprocessor. It had Sinclair BASIC and ran off the cassette recorder. This first computer was responsible for the interest in computers that I have ever since.
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!
In the rest of the post I’ll explain how to run that perfect MOS 6502 CPU simulation that runs Commodore 64 BASIC V2 emulator in WSL2 Ubuntu. So hold on.
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?
First I’ll explain how to install WSL2 if you don’t have one.
Then I’ll explain who to clone locally the repository that contains MOS 6502 and BASIC simulators.
Then we’ll build them and run them locally.
I’ll provide references to good resources on the subject.
Let’s begin
Install WSL and Ubuntu
As I mentioned Michael’s implementation requires a Linux distribution to run. So if you have Windows as I do then there is a need to install Windows Subsystem For Linux (aka WSL) to be able to run Ubuntu natively on Windows. The whole installation process is easy and takes a couple of minutes. To know how to do it just follow one of the tutorials below
After this we can build the project using Linux make tool. But since it’s not installed on Ubuntu WSL we need to install it first.
Also, make tool requires C compiler in order to compile the code. So we need to install one of the available C compilers for Linux. We’ll use gcc compiler.
Install make, by running the command below.
sudo apt install make
Next, let’s install gcc compiler. If you’ll be asked Do you want to continue? type Y.
sudo apt install gcc
Now that both of the tools are installed let’s run make command
make
What you’ll see that there will be an error and it has to do with the source code that we cloned
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.
To do this run this command
git fetch origin pull/10/head:pr_number10
You’d think that’s it. But you are wrong and there is a need to update Makefile to be able to build the project. To do this we need to comment out the line below in the file
OBJS+=measure.o
Commenting out is done using ‘#’ character as a first one in the line.
I am using vi editor to do this. On WSL it is possible to edit this file even in notepad.
Update Makefile using Windows notepad
When you are in the perfect6502 directory type
explorer.exe .
You should see Windows File Explorer opens
Now, you can select open with notepad and comment out that line in notepad.
Okay, now we are good to run 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
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
If you saw similar output then there were no errors and we can finally run the Commodore 64 BASIC emulator on MOS 6502 CPU simulator.
cbmbasic/cbmbasic
And hooray you should see the screen below
What can you do now?
Well, the sky is the limit. Pay attention that since the MOS 6502 simulator simulates real transistors it’s quite slow. Also, there are still some bugs in the Commodore BASIC emulator so not all commands will work as expected. But most will do.
For example, below comes “Hello, world!” program that will print this sentence, and then concatenate two words in one string and print it out.
Pay attention, that BASIC requires upper case for all commands.
Clear screen
PRINT CHR$(147)
Clean memory
NEW
Reset computer (hence emulator)
SYS 64738
List your program so far
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
Well, there you have it you can use your locally running BASIC with pretty good functionality or you can switch to that C64 online emulator which is faster and supports all of the commands.
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.
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 ,
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.
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
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,
= (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:
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
First vs. last letter
Second vs. one before last
etc
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;
}
}
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.
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 Sate
111
110
101
100
011
010
001
000
Next state
0
0
0
1
1
1
1
0
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.
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.
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.
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 namelyDoes 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)