Antony Denyer

Tilling the land of software

about me

I am passionate about creating great software and am particularly interested in associated supporting methodologies, namely XP and TDD.

recent public projects

Status updating…

found on

contact at

email@antonydenyer.co.uk

Private Blockchain Use Case for Reference Rate Data

- - posted in blockchain, libor, quorum, smart contracts | Comments

Reference Rate Data Use Case

Many financial instruments use reference data to perform their calculations. For instance, LIBOR is widely used as a baseline for contracts. Consequently, there is a need to have a trusted source of truth about that data for a given point in time. Currently, that service is proved by Thomson Reuters.

TL;DR

You could use blockchain to make data access cheaper.

LIBOR Panel

First a bit of background about how it gets calculated. The panel consists of several large banks who all contribute to the calculation of rates. In essence, each bank is asked at what rate they would be willing to lend to the other banks. This is then packaged together with the average being calculated and published every day.

Greater transparency

By recording the panel members responses on a blockchain, you can improve the level of trust people have in the panel. Each panel member would want to keep their rates private. While the averaged calculated rate would be made public. Each panel member has an interest in maintaining the validity of the network as the panel is already a consortium of members it easy to represent using a Quorum network. With each member running a private permissioned node and enclave.

Walled Garden

The problem with running a private network is that people don’t have easy access to the data. What you want is the calculated rate to be available on a public network. While ensuring that the trust and validation of the original contract is maintained.

Trustless cross-chain interaction

To get the data onto a public network in a trustless way is hard. There has to be some interaction at the application level. Someone needs to take an action to publish the data. However, there are some things you can do to improve verification beyond just putting another hash on the blockchain (notarize). You could use something like Ion Interoperability Framework to validate that the data was verified by someone on the reference data network. The problem is that you can not guarantee that that is always the truth. At best you can attest that the data was correct at that point in time. What you need is a further application level confirmation. You need to have every panel member also confirm that the public chain record is the same as the private chain record that they have.

Summary

You have a situation with multiple parties that have a vested interest in the integrity of the published data. The cost of accessing the data would be reduced as it would be available on a public network. Furthermore, stronger guarantees can be provided about the truthfulness of the data than can be achieved at present with a single information provider.

Roman Numerals Kata in Elixir With Pattern Matching

- - posted in elixir, tdd | Comments

Roman Numerals Kata

I wanted to have a play about with pattern matching a bit more in Elixir so I thought I would see if I could do the roman numerals kata using pattern matching and no looping.

Basic tests I -> III

I started off in the usual TDD way of writing a test for “I”

1
2
3
4
5
6
7
  test "one is I" do
    assert Roman.to_roman(1) == "I"
  end

  def to_roman(number) 
    String.duplicate("I", number) 
  end

18d663

No great shakes, we can print up to “III”. So far so simple. The next step I normally take is “IV”. It’s a bit more interesting in elixir as I wanted to exercise Guard Clauses in elixir.

Pattern Matching IV and V

What you need to do is define a guard for when you want to execute the function.

1
2
3
4
5
6
7
  test "four is IV" do
    assert Roman.to_roman(4) == "IV"
  end

  def to_roman(number) when number == 4 do
    "IV"
  end

9dcb82

All we have here is a conditional guard clause to say if the number is equal to 4 then run this function. If it doesn’t match, we don’t care. It is not our responsibility to deal with, which for me is extremely interesting, we are in effect following the SRP at a function level.

One thing that caught me out was guard precedence, basically, it’s top to bottom.

Let’s move on, next is 5

1
2
3
  def to_roman(number) when number == 5 do
    "V"
  end

b427555

Boom, done.

Implementing VI

You may have noticed that we haven’t implmeneted anything interesting yet. We have some behaviour for 1-3, but that is all. 4 and 5 are just lookups. The next exciting thing to implement is 6, which is funny because 4 hasn’t added anything to help us drive out the behaviour. For 6 (VI) we need to accumulate 5 and 1. So let’s get started

1
2
3
  test "six is VI" do
    assert Roman.to_roman(6) == "VI"
  end

What I want to do is match anything greater than 5 and return “V” along with the remaining match for 1. This what I came up with:

1
2
3
  def to_roman(number) when number >= 5 do
    to_roman(number - 5, "V")
  end

The problem is we don’t have anything that will match to_roman/2, so let’s implement that.

1
2
3
  def to_roman(number, roman_accumulator) do
    roman_accumulator <> String.duplicate("I", number)
  end

155de6

And now are concatenating the two string together, the “V” and the “I”. Now, I’ve taken a bit of leap, we have implemented 7 and 8. But, I think that’s okay.

Now, our code is looking a little bit messy. Let’s go ahead and refactor it a bit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  def to_roman(number, roman_accumulator) do
    roman_accumulator <> String.duplicate("I", number)
  end
  
  def to_roman(number) when number >= 5 do
    to_roman(number - 5, "V")
  end

  def to_roman(number) when number == 4 do
    to_roman(number - 4, "V")
  end

  def to_roman(number) do
    to_roman(number, "")
  end

c79d40

We still don’t quite have anything generic yet. Let’s implement “IX” and “X” in the same way, get some tests round them.

238510

A more generic algorithm

Now there’s still nothing going on to help us design our algorithm, let’s move onto “XIV”. There’s a bit more happening, we will need to combine “X” and “IV”. When we run our test for 14 we get a test failure:

1
2
3
4
Assertion with == failed
code:  assert Roman.to_roman(14) == "XIV"
left:  "XIIII"
right: "XIV"

e055fc

So what we need to have is a way for “X” to fall through into “IV”. To achieve this, I’m just going to add in the parameter.

1
2
3
  def to_roman(number, roman_accumulator) when number >= 4 do
    to_roman(number - 4, roman_accumulator <> "IV")
  end

Now we are starting to see some design emerging, but we have two tests failing.

1
2
3
  code:  assert Roman.to_roman(4) == "IV"
     left:  "IIII"
     right: "IV"

The reason is simple; we need to ensure that

1
2
3
  def to_roman(number, roman_accumulator) do
    roman_accumulator <> String.duplicate("I", number)
  end

doesn’t catch the case for 4. We can achieve this in two ways; I’m going to implement both as I think it will make the code clearer. We will implement a guard clause and change the order of the code.

403e18

And now our test passes. Now I think we’re getting closer to something more generic. Let’s implement “XVI” and tidy up. Again when we write our test for 16 we get

1
2
3
4
Assertion with == failed
code:  assert Roman.to_roman(16) == "XVI"
left:  "XIVII"
right: "XVI"

Now, what is going on here? It’s fairly simple when you dig into it. We get the match for 10 (X), remainder 6. We then get match a match on the 6 to “IV” which is incorrect. We need it to match “V”. So let’s go ahead and implement that

1
2
3
  def to_roman(number, roman_accumulator) when number >= 5 do
    to_roman(number - 5, roman_accumulator <> "V")
  end

da5e6a

Now I’m going to tidy up the 9 and 10 so that it follows the same pattern as 4 and 5.

78a7c4

I think we’ve got something that will cover us until the next numeral, let’s just double check with another test.

8a7f9d

What I’m going to do now is go ahead and implement the rest of the algorithm and test it using a doctest

Solution

4a463fe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def to_roman(number, roman_accumulator) when number >= 1000 do
    to_roman(number - 1000, roman_accumulator <> "M")
  end
  
  def to_roman(number, roman_accumulator) when number >= 900 do
    to_roman(number - 900, roman_accumulator <> "CM")
  end
  
  def to_roman(number, roman_accumulator) when number >= 500 do
    to_roman(number - 500, roman_accumulator <> "D")
  end
  
  def to_roman(number, roman_accumulator) when number >= 400 do
    to_roman(number - 400, roman_accumulator <> "CD")
  end
  
  def to_roman(number, roman_accumulator) when number >= 100 do
    to_roman(number - 100, roman_accumulator <> "C")
  end

  def to_roman(number, roman_accumulator) when number >= 90 do
    to_roman(number - 90, roman_accumulator <> "XC")
  end

  def to_roman(number, roman_accumulator) when number >= 50 do
    to_roman(number - 50, roman_accumulator <> "L")
  end

  def to_roman(number, roman_accumulator) when number >= 40 do
    to_roman(number - 40, roman_accumulator <> "XL")
  end

  def to_roman(number, roman_accumulator) when number >= 10 do
    to_roman(number - 10, roman_accumulator <> "X")
  end

  def to_roman(number, roman_accumulator) when number >= 9 do
    to_roman(number - 9, roman_accumulator <> "IX")
  end

  def to_roman(number, roman_accumulator) when number >= 5 do
    to_roman(number - 5, roman_accumulator <> "V")
  end

  def to_roman(number, roman_accumulator) when number == 4 do
    roman_accumulator <> "IV"
  end

  def to_roman(number, roman_accumulator) when number <= 3 do
    roman_accumulator <> String.duplicate("I", number)
  end

  def to_roman(number) do
    to_roman(number, "")
  end

Pretty cool I think :)

Removing the String.duplicate

As a bit of a mental exercise, I thought it would be interesting to remove the String.duplicate basically you end up with a pattern match for 0,1,2 and 3. Interestingly most people don’t test 0 when doing this Kata. It becomes obvious that you need it when you don’t implement a pattern match for 0.

e75fd6

The other thing I wanted to look at was removing the unnecessary fall through for 4 down to 0.

358fade

Summary

We’ve learnt a bit about pattern matching and guard clauses in Elixir as well as introducing doctest. This sort of thing can be done in a few different ways.

My personal favourite is

1
2
3
4
5
6
7
8
9
10
11
12
13
String.duplicate("I", number)
    |> String.replace("IIIII", "V")
    |> String.replace("VV", "X")
    |> String.replace("XXXXX", "L")
    |> String.replace("LL", "C")
    |> String.replace("CCCCC", "D")
    |> String.replace("DD", "M")
    |> String.replace("IIII", "IV")
    |> String.replace("VIV", "IX")
    |> String.replace("XXXX", "XL")
    |> String.replace("LXL", "XC")
    |> String.replace("CCCC", "CD")
    |> String.replace("DCD", "CM")

It’s probably a bit terse; you have to understand whats going on. It’s a little hard to figure our but it’s kind of fun.

The Value of Functions

- - posted in aws, azure functions, faas, lambda, serverless | Comments

With the emergence of FaaS entering the mainstream, we are starting to see some real world business value in using such an architecture. Many of the benefits of using FaaS are discussed elsewhere:

  • pay as you go
  • no-ops
  • limited provisioning
  • performance scalability
  • lower running costs

But some of the benefits are more subtle. The benefit I want to highlight is this:

You can measure how much features cost to run.

While this may not seem like a winning feature, let’s think about it for a second.
You have a feature on your website called ‘price match’. What it does is matches prices against your competitor’s prices. To do this it scrapes each of your competitor’s sites to get their price of the product. If you ask the product owner how often they want the prices updated they’d probably say something like ‘as much as possible’ or ‘real time please’. In the old world, we would probably hit it as often as we could and be done with.

Now with FaaS you have some additional information to help you make decisions, this feature will cost 0.001ยข to run per competitor per product. You can then extrapolate different price points for different frequencies and make a business case for each of them. Or better yet measure the value of having it run every minute vs. every hour.

Summary

As an industry, we can genuinely begin looking at the running costs of an individual feature. This started at the product level with ‘Lean Startup’ and will, I believe, continue to a greater degree with individual features and functions.

Features can be added and removed more quickly with the costs and benefits of them being more transparent to both developers and product owners.