Two dice with an ATTiny13

A long time ago, I designed my own board using an ATTiny85, a 74HC595, two buttons and 14 LEDs to create a simple board with 2 6-sided dice. Pressing a button would roll one of the dice. It was fun, but I forgot about that project until I decided to redo it again. And this time, I designed a new, round board that would use capacitive buttons. And the result? This video, this design, this Gerber file (zipped) and this picture:

In the above picture you’ll see two round boards, two rectangle boards and two square boards. These are some boards that I’ve been working on.

The rectangular board supports an 74HC165 IC, which is an input shift register. I have a similar board for an output shift register. Basically, the 165 reads voltages (High or Low) from 8 pins to translate them to bits in a byte. The 595 translates bits in a byte back to voltages. Having this on a special board is just practical.

The square board combines the 74HC595 shift register with an ATTiny processor, which is linked again to an ESP8266 module. (The ESP-01.) This basically makes a multi-processing board where the ATTiny can handle various LEDs while the ESP sends commands to the ATTiny based on input from the Internet. And the ESP still has 3 pins available for other input or output. But this board is for a later post…

It’s the round board that matters, though. This is what you need to roll two dice. And it has three major parts. The first part is the design of the board. The second part is choice of hardware. The third part is the code to roll dice.

Design

Two dice, by W.A. ten Brink.

Well, the design is reasonably simple. Power is on the left and the yellow lines are on the top while the orange lines are on the bottom. The 74HC595 has 4 pins per die so with 8 pins I can handle 2 dice. If I want more dice then I would need to chain more of these 595 IC’s. On the right is the 8-pin ATTiny and pins 0 and 1 go to the bottom, allowing communications with “something else”. Three other pins are needed to control the 595. And then there are 14 LEDs consisting of 6 pairs and 2 loose LEDs, resulting in just 4 combinations for every die. Which is exactly what I need.

Hardware

Now, for the hardware I have many options. For my first board, I decided to use an ATTiny13 as this processor is very limited in it’s options. It only has a kilobyte of RAM! And in a time where computers have lots of gigabytes of RAM, a single kilobyte is just unimaginable. It’s slightly more than a thousand characters so this post is likely to be bigger than this RAM can handle. But to roll dice, you don’t need much code…

For the LEDs I’ve picked purple-UV LEDs just for fun. These are pretty clear in the day yet not too bright. And in the dark they provide a blacklight-effect. I did not add any resistors as the whole setup doesn’t use that much power to begin with. These LEDs can handle the voltage.

As for input, I decided to add two capacitive buttons. These will already respond when your finger is near the button so you don’t have to touch them. Which is interesting as I’m planning to cast the LEDs and buttons in resin to give it a smooth surface.

Code

And then the code for all of this. I still needed 105 lines of code but that’s mostly because I use a lot of ‘define’ statements and added several comments. This is the code:

#define CLEARLEFT 0b11110000
#define CLEARRIGHT 0b00001111

#define LEFT_2  0b00000001 // LB-RT
#define LEFT_3  0b00000010 // Horizontal
#define LEFT_4  0b00000100 // RB-LT
#define LEFT_1  0b00001000 // Center
#define RIGHT_2 0b00010000 // LB-RT
#define RIGHT_3 0b00100000 // Horizontal
#define RIGHT_4 0b01000000 // RB-LT
#define RIGHT_1 0b10000000 // Center

#define ROLL_L1 LEFT_1
#define ROLL_L2 LEFT_2
#define ROLL_L3 LEFT_1 | LEFT_2
#define ROLL_L4 LEFT_2 | LEFT_4
#define ROLL_L5 LEFT_1 | LEFT_2 | LEFT_4
#define ROLL_L6 LEFT_2 | LEFT_3 | LEFT_4

#define ROLL_R1 RIGHT_1
#define ROLL_R2 RIGHT_2
#define ROLL_R3 RIGHT_1 | RIGHT_2
#define ROLL_R4 RIGHT_2 | RIGHT_4
#define ROLL_R5 RIGHT_1 | RIGHT_2 | RIGHT_4
#define ROLL_R6 RIGHT_2 | RIGHT_3 | RIGHT_4

// Value of (last) roll.
int left = 0;
int right = 0;
// Pin for left button.
int leftPin = 0;
// Pin for right button
int rightPin = 1;
//Pin connected to data pin of 74HC595
int dataPin = 2;
//Pin connected to clock of 74HC595
int clockPin = 3;
//Pin connected to latch pin of 74HC595
int latchPin = 4;

int LeftValue(int value) {
  switch (value) {
    case 1: return ROLL_L1;
    case 2: return ROLL_L2;
    case 3: return ROLL_L3;
    case 4: return ROLL_L4;
    case 5: return ROLL_L5;
    case 6: return ROLL_L6;
  }
  return 0;
}

int RightValue(int value) {
  switch (value) {
    case 1: return ROLL_R1;
    case 2: return ROLL_R2;
    case 3: return ROLL_R3;
    case 4: return ROLL_R4;
    case 5: return ROLL_R5;
    case 6: return ROLL_R6;
  }
  return 0;
}

void WriteDice() {
  int lastRollValue = 0;
  if (left > 0 && left < 7) lastRollValue = (lastRollValue & CLEARLEFT) | LeftValue(left);
  if (right > 0 && right < 7) lastRollValue = (lastRollValue & CLEARRIGHT) | RightValue(right);
  // Avoid flickering LEDs, disable LEDs.
  digitalWrite(latchPin, LOW);
  // Send out the byte value.
  shiftOut(dataPin, clockPin, MSBFIRST, lastRollValue);
  // Avoid flickering LEDs, enable LEDS.
  digitalWrite(latchPin, HIGH);
}

void setup() {
  randomSeed(millis());
  pinMode(dataPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  digitalWrite(latchPin, HIGH);
  for (left = 1; left <= 6; left++) {
    for (right = 1; right <= 6; right++) {
      WriteDice();
      delay(10);
    }
  }
  left = 1;
  right = 1;
  WriteDice();
}

int Roll() {
  return random(1, 7);
}

void loop() {
  // Check if we're pressing a button. If so, update time!
  if (digitalRead(leftPin) == HIGH) left = Roll();
  if (digitalRead(rightPin) == HIGH) right = Roll();
  // Display the rolled results.
  WriteDice();
  delay(50);
}

I start by defining the left and right sides. Left are the 4 bits on the right and right are the 4 bits on the left. Meh. I should have thought about that before…

I then define the four channels that each die has. These four channels per die allow me to define the combinations needed to display the values 1 through 6.

All these defines will translate to hardcoded values so that saves a few bytes in variables. But I do need a few global variables, though. I need variables for the pins and I need variables to remember the values of the left and right die. Well, I could have used “define” for the pin values but I seem to prefer to use variables for pins. Not sure why, exactly.

Two functions called LeftValue() and RightValue() are used to translate a number between 1 and 6 to the proper bit-pattern. All other values will result in 0.

The WriteDice() function will handle sending the dice values to the LEDs using the 595. It’s not too complex. Calculate the proper byte value to hold both dice and then send it to the 595. (Turning off the latch so it won’t flicker.)

The setup() function is also a simple one, but I want to show the dice are working during start-up. That’s why I loop through all possible combinations before displaying snake-eyes.

A simple Roll() method returns random values between 1 and 6 so that’s where dice are rolled.

The Loop() function is just checking if any of the input pins is getting a signal. If the voltage is high, it will roll for that die. If low then the old value remains. As this is inside a loop, it will just keep rolling for as long as the voltage is high.

I used touch buttons as input so as long as you keep your finger on it or close above it, it will just keep rolling. Which gives an interesting effect. This is done on purpose, allowing a player to “shake” the dice for a while. But instead of these buttons I could also have chosen another form of input. Even more interesting, I could have set up serial communication over these two pins with another board, allowing a secondary device to control the rolls.

So, I could attack an ESP-01 to it and let the rolls be made over WiFi, sending the results back to some web server. This is where my other board with the ESP-01 and the ATTiny could be used.

Conclusion

It is a bit challenging to come up with a simple idea like this. Especially when you’re still not very experienced in electronics. The use of the ATTiny13 was very challenging because it is so limited in memory. The ATTiny85 has 8 kilobytes of RAM, which is more practical. Still not a lot, but enough for many simple purposes.

The whole device works on a 3.6 volts battery but I want to cast the whole thing into opaque resin just to make it look more interesting. But I’m also considering making another one that is connected to an ESP-01 so it has WiFi capabilities. (The IC’s and ESP won’t be cast inside the resin, though!)

Once it’s finished I should be able to connect it to a battery or USB port or some other power source, which will make sure the voltage doesn’t exceed the 3.6 volts.

The use of raw ATTiny processors is very interesting because of it’s limitations. For a software developer, these IC’s are really interesting as you need to optimise for size, while keeping speed high. You’re thinking more in clock cycles and bits. It’s a huge difference compared to designing a whole website with database backend where the amount of executables is easily megabytes in size while data can exceed gigabytes of disk space. Good developers can think small and big.

Fizz Buzz gets chained…

There’s a simple child’s game called Fizz Buzz that is also used as a test for developers to show basic coding skills. Jeff Atwood even mentioned in his blog the use of this game as a simple test to weed out the bad developers before hiring new ones. And there are still developers being hired these days that would fail the simple FizzBuzz test. And that’s a shame.

So, what is Fizz Buzz? Well, basically you will count from 1 to 100 but when you encounter a multiple of three, you say “Fizz” instead of the number. And if it’s a multiple of five, you’ll say “Buzz” instead. So if you encounter a multiple of three and five, you’ll have to say “Fizz Buzz”. It’s a simple math challenge for children and a coding challenge for developers. A good developer should be able to write this code within 10 minutes or so, which makes it an excellent test during the hiring process…

Now, the website “Rosetta Code” has an excellent solution of solving this problem, and many others, in a lot of different programming languages. These include several solutions for C#. (With C# being my most popular choice these days.) But I want to show how to FizzBuzz in a complex way with lots of data analysis and solve it through method chaining. In my previous post I already mentioned why using methods that return void will break a method chain. This post will show some interesting code aspects of how to split even a simple problem into many smaller parts so each piece can be solved and managed but also reused in other projects.

So, let’s analyse the data we need and the data we will generate. Basically, we start with an array of numbers that gets translated to a single string. So, here we go:

  • We need to make a list of numbers.
  • Create pairs so we can store each call.
  • We need to return “Fizz”.
  • We need to return “Buzz”.
  • We need to return numbers as string values.
  • We need a condition telling us when to Fizz.
  • We need a condition telling us when to Buzz.
  • We need a condition telling us when we to use a number.
  • We need to select just the string values.
  • We have to join the string values into a comma-separated string.

So, I generally start with creating a static class as I’m going to make a bunch of extension methods for C#. Why? Because extension methods allow me to add functionality to objects and classes without modifying them! But first let’s make a few friendlier names for data types that we will be “using”… (Pun intended!)

using IntEnum = IEnumerable<int>;
using Pair = KeyValuePair<int, string>;
using PairEnum = IEnumerable>< KeyValuePair<int, string>>;
using StringEnum = IEnumerable<string>;

That’s the data we will need. We will need an enumeration of integers. Those will be converted to pairs so we can maintain the proper order and know which number belongs to which result. These pairs are also enumerated and in the end, they will be converted to strings before we make a single string out of them all…

So now we’re going through the list of functions:

Make a list of numbers.

This is an easy one. But while many might just create a for-loop to walk through, I prefer to create an enumeration instead, as this allows me to “flow” all the data. So my first method:

public static IntEnum MakeArray(this int count, int start = 0) => Enumerable.Range(start, count);

This is a simple trich that not many developers are familiar with. Instead of using a for-loop, I use Enumerable.Range() to create an enumeration to start my method chain. I can now use 50.MakeArray(10) to make an enumeration that starts at 10 and goes up to 50.

Create pairs so we can store each call.

Here we will create a few methods. First, we’ll start with:

public static Pair NewPair(this int key) => new Pair(key,string.Empty);

This code takes an integer and will return a key pair with empty string as value. Then we’ll create:

public static Pair NewPair(this Pair pair, string data) => new Pair(pair.Key, data.Trim());

Here we create new key pair based on the old key pair. Thus we won’t change existing key pairs as those might still be used for other purposes. We also trim the string value to remove excess spaces.

We need to return “Fizz”.

Seriously? Well, yeah.

public static Pair DoFizz(this Pair data) => data.NewPair("Fizz " + data.Value);

The reasoning behind it is that we want to add the word “Fizz” in front of the string that we already have. As we start with empty strings and trim the value when creating a new pair, we should just get “Fizz” as result. But if the result already contains “Buzz”, we will get “Fizz Buzz” as result. Including the space!

We need to return “Buzz”.

This is oh, so simple. šŸ™‚

public static Pair DoBuzz(this Pair data) => data.NewPair(data.Value + " Buzz");

The difference between this method and the DoFizz() method is that this one adds “Buzz” at the end of the result, not at the start. So it doesn’t matter if we first Fizz or Buzz, the result is always “Fizz Buzz”. Including the space…

We need to return numbers as string values.

More simple code, but even simpler…

public static Pair DoNumber(this Pair data) => data.NewPair(data.Key.ToString());

When we put a number in the result, we don’t care about it’s content. It gets replaced in all cases…

We need a condition telling us when to Fizz.

We can’t Fizz all the time so we need to have a condition check.

public static bool IsFizz(this Pair data) => data.Key % 3 == 0;

I could have made it even more generic with an int as parameter but I use this solution to make it readable!

We need a condition telling us when to Buzz.

We also need to determine when to Buzz…

public static bool IsBuzz(this Pair data) => data.Key % 5 == 0;

We need a condition telling us when we to use a number.

And we need to decide when we want to have a number as result!

public static bool IsNumber(this Pair data) => string.IsNullOrEmpty(data.Value);

But how to get those conditional statements inside my enumerations?

Well, we need the if-statement to become part of the method chain. So we create another extension method for it.

public static T If(this T data, Func condition, Func action) => condition(data) ? action(data) : data;

This shows some power behind extension methods, doesn’t it? Because I’ve declared both the condition and action as separate methods, I can use a shorthand method when calling them. And the shorthand I will use for the Fizz(), Buzz() and Number() methods I’m creating:

public static Pair Fizz(this Pair data) => data.If(IsFizz, DoFizz);
public static Pair Buzz(this Pair data) => data.If(IsBuzz, DoBuzz);
public static Pair Number(this Pair data) => data.If(IsNumber, DoNumber);

And as these methods work on just a single pair, I also need methods to use for the full enumeration. Fortunately, I can use the same name, with different types:

public static PairEnum Fizz(this PairEnum data) => data.Select(Fizz);
public static PairEnum Buzz(this PairEnum data) => data.Select(Buzz);
public static PairEnum Number(this PairEnum data) => data.Select(Number);

The PairEnum is just an IEnumerate<Pair> as declared by the “using” before. Rather than declaring a new class, I prefer to create an alias for this type.

The result is that we have three methods now which each will work on an enumeration, changing the result of each pair where this is required.

We need to select just the string values.

This is another simple one, but here the data flow changes type. Selecting the results can be done by using:

public static StringEnum Values(this PairEnum data) => data.Select(p => p.Value);

But before selecting all results, we might want to put all items in the correct order:

public static IOrderedEnumerable SortPairs(this IEnumerable data) => data.OrderBy(p => p.Key);

Now, this sort is not required when you go through the enumerations normally. But because you can also do parallel enumerating and thus use multiple threads to walk through everything, you might also get all results in a random order. So, sorting it will fix this…

How do we make it execute parallel? Well, I would just need one adjustment to one method:

public static PairEnum Number(this PairEnum data) => data.AsParallel().Select(Number);

I only added AsParallel() in this method to change it from a synchronous to an asynchronous enumeration. But the result is that all numbers will be executed asynchronously. This means the order of my data becomes unpredictable. And let’s make it even better:

public static PairEnum Number(this PairEnum data, bool asynchronous = false) => asynchronous ? data.AsParallel().Select(Number) : data.Select(Number);

Now we can specify if we want to execute the numbering synchronous or not. The default will be synchronous so I would not need to sort afterwards. But if I indicate that I want it executed asynchronous then the order of data will be more randomized and I would need to sort afterwards.

If I also apply this change to Fizz() and Buzz() then it can become extremely interesting when everything is done asynchronous.

We have to join the string values into a comma-separated string.

Well, joining string values in a list is simply done by calling the string.Join() method but as I’m making a lot of methods already, I can just add one more:

public static string Combine(this StringEnum data) => string.Join(", ", data);

And all these methods together allow me to control the data flow in the finest details. Generally too fine for solving the FizzBuzz challenge, but it does make an interesting example…

So, how to FizzBuzz?

Okay, one more method:

public static string FizzBuzz(this int count) =>
count.MakeArray(1)
.MakePairs()
.Fizz()
.Buzz()
.Number()
.Values()
.Combine();

Notice how all methods used so far are basically one-liners. And this method too is just a single statement. It’s just written over multiple lines to make it readable.

And it shows the data flow in reasonably clear names. We take a number and make an array of numbers. These get converted to pairs, the pairs then get Fizzed, Buzzed and numbered before we convert them to strings and join them into a single string result. No sorting as I’m not doing anything asynchronous here. And the result will be: Buzz, 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, Fizz Buzz, 16, 17, Fizz, 19, Buzz, Fizz, 22, 23, Fizz, Buzz, 26, Fizz, 28, 29, Fizz Buzz, 31, 32, Fizz, 34, Buzz, Fizz, 37, 38, Fizz, Buzz, 41, Fizz, 43, 44, Fizz Buzz, 46, 47, Fizz, 49, Buzz, Fizz, 52, 53, Fizz, Buzz, 56, Fizz, 58, 59, Fizz Buzz, 61, 62, Fizz, 64, Buzz, Fizz, 67, 68, Fizz, Buzz, 71, Fizz, 73, 74, Fizz Buzz, 76, 77, Fizz, 79, Buzz, Fizz, 82, 83, Fizz, Buzz, 86, Fizz, 88, 89, Fizz Buzz, 91, 92, Fizz, 94, Buzz, Fizz, 97, 98, Fizz, 100

Which reminds me: I had to use MakeArray(1) to make sure I start with 1, not 0. Otherwise, I would get 100 numbers starting with 0 and ending at 99, not 100…

Now, you’re probably thinking about how this works. And it’s likely that you assume it creates a list of integers, then a list of pairs, then a list of Fizzed pairs, etcetera. And you’re wrong! But let’s modify the code a bit. Let’s display technical information using my Do() method, and a variant of Do()…

Adding Do…

public static T Do<T>(this T data, Action<T> action) { action(data); return data; }
public static T Do<T>(this T data, Action action) { action(); return data; }
public static IEnumerable<T> Do<T>(this IEnumerable<T> data, Action<T> action) { foreach (var item in data) { action(item); yield return item; } }

These three Do() methods are very generic and as I’ve mentioned in my previous post, it allows using methods returning void within a method chain.

The first Do() will perform an action and pass the data back to that method. As we just want to do simple WriteLine statements, we won’t use that.

The second Do() can perform actions that don’t depend on the data. This is ideal to “step out” of the method chain to do something else before returning to the chain.

The third Do() will do an action for each item inside an enumeration without breaking the enumeration! And why we want to do this will be shown when we call this monster:

public static string FizzBuzzNormalStatus(this int count) =>
count.Do(() => Console.WriteLine("Linear: Initializingā€¦"))
.MakeArray()
.Do(() => Console.WriteLine("Linear: Array createdā€¦"))
.MakePairs()
.Do(pair => Console.WriteLine($"Pair: {pair.Key} -> {pair.Value}"))
.Do(() => Console.WriteLine("Linear: Pairs madeā€¦"))
.Fizz()
.Do(pair => Console.WriteLine($"Fizz: {pair.Key} -> {pair.Value}"))
.Do(() => Console.WriteLine("Linear: Fizzedā€¦"))
.Buzz()
.Do(pair => Console.WriteLine($"Buzz: {pair.Key} -> {pair.Value}"))
.Do(() => Console.WriteLine("Linear: Buzzedā€¦"))
.Number()
.Do(pair => Console.WriteLine($"Number: {pair.Key} -> {pair.Value}"))
.Do(() => Console.WriteLine("Linear: Numberedā€¦"))
.SortPairs()
.Do(pair => Console.WriteLine($"Sort: {pair.Key} -> {pair.Value}"))
.Do(() => Console.WriteLine("Linear: Sortedā€¦"))
.Values()
.Do(() => Console.WriteLine("Linear: Extractedā€¦"))
.Combine()
.Do((s) => Console.WriteLine($"Linear: Finalizing: {s}ā€¦"));

And yes, this is still a single statement. It’s huge because I’m writing a line after each method indicating that this method has just fired after writing all the data it has processed. So, you would expect to see “Linear: Array createdā€¦” being written, followed by a bunch of pairs and then “Linear: Pairs madeā€¦”.

Wrong!

But I’ll show this by FizzBuzzing just the numbers 0 to 4:

Linear: Initializingā€¦
Linear: Array createdā€¦
Linear: Pairs madeā€¦
Linear: Fizzedā€¦
Linear: Buzzedā€¦
Linear: Numberedā€¦
Linear: Sortedā€¦
Linear: Extractedā€¦
Pair: 0 ->
Fizz: 0 -> Fizz
Buzz: 0 -> Fizz Buzz
Number: 0 -> Fizz Buzz
Pair: 1 ->
Fizz: 1 ->
Buzz: 1 ->
Number: 1 -> 1
Pair: 2 ->
Fizz: 2 ->
Buzz: 2 ->
Number: 2 -> 2
Pair: 3 ->
Fizz: 3 -> Fizz
Buzz: 3 -> Fizz
Number: 3 -> Fizz
Pair: 4 ->
Fizz: 4 ->
Buzz: 4 ->
Number: 4 -> 4
Sort: 0 -> Fizz Buzz
Sort: 1 -> 1
Sort: 2 -> 2
Sort: 3 -> Fizz
Sort: 4 -> 4
Linear: Finalizing: Fizz Buzz, 1, 2, Fizz, 4ā€¦

And yes, that’s the output of this code! It tells you the array was created, the pairs prepared, Fizzed, Buzzed, Numbered before sorting and extracting and only then will it do all those things!

This is what makes enumerations so challenging to understand! They’re not arrays or lists. They’re something many developers are less familiar with. This is why “yield result” is so useful when enumerating data. I don’t need a lot of memory to store lists of data but instead will process each item in the enumeration up to the point where the data gets aggregated.

Which in this case happens when I sort the data, as I need all data before I can sort it. If I don’t sort in-between, the data will only be aggregated when I call the Combine() method.

This is important to remember during data processing, as an exception in one of these methods can have unexpected consequences. That’s because all data before the faulty data will have been processed by the aggregator function. For FizzBuzz, that wouldn’t be a problem. But if one of the methods in the chain would write data to a database or file then it will have partially written some data up until it gets the exception.

So, when using enumerators, you might end up with garbage if you’re unaware of how data passes from one method to another. It feels unnatural for inexperienced developers yet it makes this FizzBuzz example so much more interesting…

Avoid the void, introducing Do!

I’ve been programming for a very long time. I wasn’t even 10 years old when I got access to computers and that was back around 1975! My first programming experience were on a programmable calculator and later with BASIC on a ZX-81. Around 1985 I started learning other programming languages and around 1988 I even used Turbo Pascal 5.5 which has support for object-oriented programming. Well, a bit limited.

When I started using Turbo Pascal and later Delphi, I also learned the value of methods that would return objects. But it would still take a while before I realized the full power of this. Still, in Turbo Pascal 6 there was a feature called Turbo Vision that could be used to create complete menu structures and dialog screens on a text console! It made extensive use of methods returning objects to make method chaining possible.

Method chaining is a simple principle. You have a class and the class has methods. And each method can return an object of a specific class. So that gives access to a second method. And a third, a fourth, a fifth until you get to a method that returns void.

That’s a dead stop there!

I recently worked on a project where I used a long method chain to keep a clear workflow visible in my code. And my code was selecting data, ordering it, manipulating it and then saved it to a comma-separated file or CSV file. Something like this:

MyData
.ToList()
.OrderBy(SortOrder)
.Take(50)
.Select(NewDataFormat)
.SaveToCSV(Filename);

But SaveToCSV was a method that returned void, so the chain breaks there! But I wanted to continue the workflow as I needed to do more with this data. I also wanted to display it on screen, save it to a database or even filter it a bit more. So, to resolve this I needed a better method that would allow me to continue the chain.

Of course, I could also have written my code like this:

var myList = MyData.ToList();
var mySortedList - myList.OrderBy(SortOrder);
var myTop50 = mySortedList.Take(50);
var myNewList = myTop50.Select(NewDataFormat);
myNewList.SaveToCSV(Filename);

This code would allow me to also continue the workflow and would also allow me to use myNewList for further processing. But it also introduces a bunch of variables and it allows non-related code to be included within these lines, obscuring the workflow! That would not work! The chain of work would be broken by irrelevant tasks.

So, now I have two options. Either I modify the SaveToCSV method so it will return a value (preferably the object itself) or I make an extension method inside a static class that would allow me to put a void method within my chain. And I came up with this beautiful, yet simple method:

public static T Do<T>(this T data, Action<T> action){ action(data); return data; }

And this simple, yet beautiful construction is a generic method that can be used for any class, any object! And it can change my code into this:

MyData
.ToList()
.OrderBy(SortOrder)
.Take(50)
.Select(NewDataFormat)
.Do(d=>d.SaveToCSV(Filename))
.Do(d=>Console.WriteLine(d));

Now my data flow is still intact and the flow of the code is still very readable. It is easy to see that this is just one block of code. Most people tend to forget that programming isn’t about writing code. It’s about how to process data.

Using a method chain is a perfect way to visualize data flow inside your code. But to allow proper method chaining, each method will have to return some kind of object for further processing. Otherwise, you will need a Do<> extension method in your project to make a void method part of the chain.

But to keep it simple, when using a void method, you’ll basically put a stop to the data flow within your application. You would then have to start a new data flow for further processing. This is okay, but generally not the best design in programming. While not everyone might be a fan of method chaining, it still is a very powerful way to write code as it forces you to keep irrelevant code outside of the flow.

Richard Stallman is failing…

Richard Stallman is the founder and President of the Free Software Foundation and creator of the GNU project, the force behind the GPL licenses. He’s also affiliated to MIT, having worked there in the past as an unpaid visiting scientist.

Stallman is also known to avoid anything that could be used to follow his actions. He considers mobile phones to be “tracking devices” so he refuses to own one. He also avoids browsing the Internet directly and uses an email-based proxy instead to read content from various websites. And he uses the Tor network in recent years, just to stay anonymous. And more importantly, he’s very active in making software freely available for everyone at no costs, fighting against copyrights, patents and more.

So, Stallman is a pretty important force in the ICT World. He has a lot of followers, a lot of admirers. Especially many students are happy with him as he made it possible for them to get software for free. How? Because Stallman promotes open source with the preference for the GPL license. And the GPL license is a license system that could forcibly be used to make other projects open source also, if those other projects use any GPL’d code…

And while open source has been popular before Stallman started the GNU project, it did become very popular after GNU. Especially after Linux became a thing and the world suddenly started to get new, free operating systems that could be ported to many different systems. And while there are many other open source licenses, the GNU license became popular as it is an open source license that adds restrictions on how you can use any of it. Some consider the GPL to be contagious as the use of GPL code in your project will force your project to be part GPL, thus forcing you to publish some of your own code as open source. Which was disliked by many companies. But the end users love it…

But recently, Stallman made a huge mistake. He wrote an email defending Jeffrey Epstein… Epstein was arrested on federal charges of sex trafficking of minors and has been convicted in the past for child molestation and prostitution. Serious charges but Epstein’s apparent suicide a month after his arrest put an end to the case, although a lot of people still doubt Epstein killed himself. It’s all too suspicious. And by defending Epstein, Stallman will now become part of any future conspiracy theories.

Which is bad, as Stallman is single, never married, never had children and we don’t even know if he has any sexual preference. He could be asexual, bisexual, hetero, gay, pansexual. Not that it matters, but people will start wondering about this now. After all, why would Stallman get involved in this whole affair.

So, what did Stallman say in his email? Well, from a source, I got this anonymized version:

The announcement of the Friday event does an injustice to Marvin Minsky: ā€œdeceased AI ā€˜pioneerā€™ Marvin Minsky (who is accused of assaulting one of Epsteinā€™s victims)ā€ The injustice is in the word ā€œassaultingā€. The term ā€œsexual assaultā€ is so vague and slippery that it facilitates accusation inflation: taking claims that someone did X and leading people to think of it as Y, which is much worse than X. The accusation quoted is a clear example of inflation. The reference reports the claim that Minsky had sex with one of Epsteinā€™s harem. (See https://www.theverge.com/2019/8/9/20798900/marvin-minsky-jeffrey-epstein-sex-trafficking-island-court-records-unsealed.) Letā€™s presume that was true (I see no reason to disbelieve it). The word ā€œassaultingā€ presumes that he applied force or violence, in some unspecified way, but the article itself says no such thing. Only that they had sex. We can imagine many scenarios, but the most plausible scenario is that she presented herself to him as entirely willing. Assuming she was being coerced by Epstein, he would have had every reason to tell her to conceal that from most of his associates. Iā€™ve concluded from various examples of accusation inflation that it is absolutely wrong to use the term ā€œsexual assaultā€ in an accusation. Whatever conduct you want to criticize, you should describe it with a specific term that avoids moral vagueness about the nature of the criticism.

I’ve underlined “Epstein’s harem” as Stallman refers to Epstein’s underage victims here in a very unflattering way. It’s a bad remark, and it’s costing him dearly. He clearly misunderstands the concept of “Consent” and ignored the age of consent, which is 18 in the US Virgin Islands. There, Marvin Minsky was accused of sexually assaulting a 17 year old girl. A girl who was apparently provided to him by Epstein.

And Minsky was a scientist working for MIT on artificial intelligence just like Stallman. Shortly after his death, he was accused by one of Epstein’s underage victims but as he was dead, there would not be any case anymore. After all, Minsky can’t defend himself, nor could he be a witness in this case.

So there’s a connection between Stallman and Epstein through MIT and Minsky. And there’s reason to believe that Epstein was part of a huge sex trafficking operation involving minors in the USA and possibly all over the World. An operation that would have to involve a lot of other high-placed people. This is bad when you consider the suspicious way in which Epstein died and the link to some very smart ICT people at MIT, who are working on artificial intelligence. There’s no evidence but there’s ‘smoke’. And smoke tends to mean something is on fire…

Stallman now quit his affiliation with MIT as his single email will damage his reputation and any of his affiliations. To protect MIT, he needed to quit immediately, even though MIT will still be in deep trouble because the rumors will become bigger after this. Because of Epstein and Minsky were related to MIT (Epstein donated a lot of money) there’s a good chance that people will start investigating things that are happening at MIT. After all, this is a place with a lot of young students, many minors, who might be involved in “improper extracurricular activities”. Especially the poorer students might be tempted if they get paid enough. It could be that there are many victims at MIT who don’t want to talk about it because they now have families and well-paying jobs. This will mostly be rumors and it’s not likely that we’ll discover i these rumors are true or not. But Stallman had to go to avoid any future rumors.

Stallman also quit as President of the FSF. And for the same reasons. The FSF will get hurt once Stallman’s reputation gets dragged through the dirt. And with the FSF, the GNU project and the GPL will also become damaged goods. This is because in the near future there will be a lot of attention to Stallman and questions if he harassed or even sexually abused any women. So he needs to distance himself from the FSF to protect it.

Stallman made one single mistake by writing that email. It has ended up in this Vice article, which is basically very damaging already. Reporters are trying to find out more about the connection between Epstein, Minsky, MIT and now Stallman. And maybe even the FSF. A post on Medium makes it even worse.

So, Stallman is falling after one huge mistake. One simple email that draws a shitstorm all over him now. And it is bad! And people will wonder about it. Many will continue to defend Stallman, as they should. He just posted his opinion, even though it’s a very bad opinion. He should not have said it, but he did. And now he pays the price and will need to stay quiet and out of the public eye for a while. As he’s 66 years old now, I would suggest that he’d just retire and will just have public speeches once in a while once the worst part of this all is over.

As for MIT, they will continue to have problems but not because of Stallman. Minsky, Epstein and a few other suspects have already caused enough damage. But as Minsky and Epstein are both dead, it’s very likely that they can get out of these problems as long as no new names pop up. Well, Stallman just popped up, but he’s clean, right? Right? Well, let’s hope so. Innocent until proven otherwise.

And the FSF will need to get a new President. And this president will likely have a different opinion on open source. It will change the FSF and their future. But it’s impossible to tell how they will change.

Still, there’s one more thing Stallman said in the past that will be used against him. On his website, he says something about Dutch paedophiles who created their own political party that would legalize sex with minors, under specific conditions. He said: I am skeptical of the claim that voluntarily pedophilia harms children. The arguments that it causes harm seem to be based on cases which aren't voluntary, which are then stretched by parents who are horrified by the idea that their little baby is maturing.

That won’t make him very popular and will make people more sceptical about his motives. His argument is basically that voluntary sex should be just fine. But no one questions that, hopefully. But people will question if minors can actually volunteer to have sex, assss in most cases they are pressured and forced into having sex. Sometimes by peer pressure, or by adults bringing presents and money. Because it’s so hard to tell if someone really volunteered, we will have to assume the worst when children have sexual relations as their safety comes first.

So, the Epstein affair now caught Stallman and there will be a lot of conspiracy theories in the future. Some will be complete crazy stories and it’s very likely that Stallman isn’t involved in aaaaanaughty business. It’s very likely that he just said something stupid and now regrets it. But he’s falling now and people who try to stop his fall might end up falling with him…

Which is sad, as Stallman was a positive force in the computer world. This whole thing will only create more victims and won’t resolve anything.

Dear Stallman, Retire in Peace.

Mijn hond is dood! (My dog has died…)

Vandaag is het zondag. Zoals gewoonlijk ben ik met mijn hondjes op bezoek gegaan bij mijn moeder. Mijn hondje Lasja was lekker actief maar mijn hondje Cees had het niet makkelijk en was kortademig. Een slecht voorteken maar verder liet hij niets merken. Hij at nog lekker, hij dronk nog wat en het werd gezellig bij mijn moeder.

Nog even de hondjes uitgelaten in de wijk bij mijn moeder, waar Cees nog even ging poepen en snuffelen en hij had er nog duidelijk zin in. Maar we moesten naar huis.

Thuis aangekomen bleek hij het al moeilijk te hebben en was hij kortademig. Maar daarvoor heb ik een hondenkar dus Cees de kar in en naar huis. Maar hij was duidelijk niet goed eraan toe.

Thuis aangekomen had hij geen trek en trok hij zich terug. Ik hield hem in de gaten maar moest ook eten en tijdens het eten merkte ik een zwaar gehijg. Cees zat op bed in de lucht te staren en te en had duidelijk luchtproblemen. Dus direct 144 gebeld voor de dierenambulance en aangegeven dat ze moesten langskomen. Ook via de dierenambulance een nummer gekregen van een spoedarts voor dieren om alvast contact te leggen.

De dierenambulance kwam snel en het was duidelijk dat we direct naar de dierenarts moesten voor een zuurstoftent. Ik had mij al voorbereid en mijn jas al aan en of ik Cees wilde optillen naar de ambulance. Dat was prima.

Met Cees in mijn armen naar de ambulance gegaan, Lasja alleen thuis achterlatend. Op weg naar het Medisch Centrum voor Dieren. Ik stap in, ga zitten en doe een gordel om terwijl ik Cees met mijn arm vast hou. Maar in mijn armen verslapt hij al en op het moment dat de ambulance weg rijdt neemt de ambulancebroeder Cees van mij over en geeft hartmassage. Maar het mocht niet baten.

Het is 21:00 en Cees is vreedzaam in mijn armen gestorven…

Seriously?

I noticed a very interesting post today on LinkedIn and I seriously have to rant about how dumb it really is. But look for yourself first and see if you’re good enough as a developer to see the flaws in it.

This is a preview image for a free course on C++ programming. Now, I’m no expert at C++ as I prefer C# and Delphi but I can see several flaws in this little preview. Yes, even though it’s a very tiny piece of code, I see things that trouble me…

And the reason for ranting is not because the code won’t work. But because the code is badly written. And a course is useless when it encourages writing code badly… So, here it is:

But keep in mind that code can be bad but if it works just fine then that’s good enough. Good developers will go for great products, not great code. It’s just that some bad code makes software development a bit harder… In general, coding practices include the use of proper design patterns and to make sure code is reusable.

So, not counting the lines with just curly brackets, I see five lines of code and two serious problems. And that’s bad. But the flaws are related because the person who wrote this C++ code seems to ignore the fact that C++ supports objects and classes. But it probably works so these aren’t really errors. They’re flaws in the design…

So, the first flaw should be obvious. I see various variable names that all start with a single letter and an underscore. The “m+” seems to suggest that these variables are all related. That means, they should be part of an object instead of just some random variables. The “m_ probably stands for “man” or whatever so you would need a class called “Man” and it has properties like ‘IsJumping’, ‘IsFalling’, ‘TimeThisJump’ and ‘JustJumped’. It suggests that Man is in a specific state like falling or jumping. And as it is a state, you would expect a second class for the “Jump” state. And probably others for “Falling”, “Walking” and other states.

The action triggered is a jump so the Man needs to be in a state that supports a jump. Jumping and Falling would not support this state so if man is in one of those states, he can’t jump. Otherwise, his state is changed to Jumping and that would start the timer. And if the timer is zero then ‘JustJumped’ would be true, right? So, no need to keep that property around.

So, all this code should have been classes and objects instead. One object for the thing that is doing something and various “State” classes that indicates what’s he doing at that moment. The fact that the author did not use classes and objects for this example shows a lack of OO knowledge. Yet C++ requires a lot of OO experience to use it properly and allow code reuse. After all, other items might jump and fall also, so they would use the same states.

The next flaw is less obvious but relates to “Keyboard::IsPressed”. This is an event that gets triggered when the user presses a key. It’s incomplete and there’s a parenthesis in front of it so I don’t see the complete context. But we have an event that is actually changing data inside itself, rather than calling some method from some class and let that method alter any data. That’s bad as it makes code reuse more difficult.

One thing to avoid when writing code is doing copy and paste of code from somewhere else. If a piece of code is needed in two or more places then it should be encapsulated in a single method that can be called from multiple locations. So this event should call a method “DoJump”, for example, so you can also have other calls to this method from other locations. For example, if you also want to support jumping on a mouse click.

Too many developers write events and fill these events with dozens of lines of code. Which is okay if this code is only called at one moment. But it’s better to keep in mind that these event actions might also get triggered by other events so you need to move them into a separate method which you can then call.

That would allow you to reuse the same code over and over again without the need for copy and paste programming.

So, in conclusion, I see a preview for a C++ course that looks totally flawed to me. No errors, just flawed. This is not the proper way to write maintainable code!

A fifth pillar for programming?

For many years I’ve been comfortable knowing that programming is build on just four pillars. These are all you need to develop anything you want and these would be:

  • Statements, or basically all the actions that need to perform.
  • Conditions, which determines in which direction the code will flow.
  • Loops for situations where actions need to be repeated.
  • Structures to organize both code and data into logical units like records and classes, databases with indices and even protocols so two applications can communicate with one another.

But as I’m developing more and more asynchronous code where you just trigger an action and later wait for the response, I start wondering if there should be a fifth one. So, should there be a fifth one?

  • Parallel tasks, where two or more flows run concurrently.
Parallel execution?

It’s a tricky one and if you learned to use flow charts and Nassiā€“Shneiderman diagrams to design applications then you’ll discover that these diagrams don’t have any popular option to represent parallel tasks in any way. Well, except in the way I just said, by triggering an external event and ignore the result until you need it.

Well, Nassi-Shneiderman does have this type for concurrent execution:

File:NassiShneiderman-Parallel.svg

Image by Homer Landskirty, CC-BY-SA 4.0 International.

And flowcharts also have a fork-join model to represent concurrent execution. So these diagrams do provide some way to indicate parallel execution. But the representation is one that suggests several different tasks are executed at the same time. But what if you have an array of records and need to execute the same task on every record in a parallel way instead?

Parallel execution is quite old yet I never found a satisfying way to display concurrency in these kinds of diagrams. Which makes sense as they are meant to define a single flow while parallel execution results in multiple, simultaneous flows. And parallel execution can make things quite complex as you might just want to cancel all these flows if one of them results in an error.

But it is possible to represent them in diagrams for a long time already even though their usage was rare in the past. But in modern times where computers have numerous cores and multithreading has become a mainstream development technique, it has become clear that parallel or concurrent execution is becoming an important standard in programming.

So it’s time to recognize that there’s a fifth pillar to programming now. But mainly because it has become extremely common nowadays to split the flow of execution only to join things at a later moment.

But this will bring many challenges. Especially because forking can result in similar tasks being executed while they don’t have to join all at once either. It basically adds a complete new dimension to programming and while it’s an old technique, it isn’t until recently that mainstream developers have started using it. The diagrams are still limited in how it can be executed while developers can be extremely creative.

Of course, there’s also a thing like thread pools as computers still have limits to how many threads can be executed simultaneously. You might trigger 50 threads at once yet add limitations so only 20 will run at the same time while the rest will wait for one of those threads to finish.

It becomes even more complex when two or more threats start sending signals to one another while they continue running. This is basically a start for event-driven programming, which doesn’t really fit inside the old diagram styles. You could use UML for various of these scenarios but it won’t fit in a single diagram anymore. A sequence diagram could be used to display parallel execution with interprocess communications but this focuses only on communication between processes. Not the flow of a single process. Then again, UML doesn’t even have those kinds of flow diagrams.

So, while programming might have a fifth pillar, it also seems it breaks the whole system due to the added complexity. It also makes programming extremely different, especially for beginners. When you start to learn programming then the four pillars should teach you what you need to know. But once you start on the fifth pillar, everything will turn upside down again…

So maybe I should even forget about my four pillars theory? Or add the fifth one and ignore the added complexity?