# Coding For Parents: Roman Numerals

Usually kids are only introduced to our 10 based Arabic numerals. It is unfortunate because it can be hard to grasp the concept of numbers when you only learn one system. Often it helps seeing different approaches to understand better the underlying concept.

It why I think it is useful to teach them about alternative ways of dealing with numbers.

# Why Learn Roman Numerals

Probably the most common alternative number system to show kids is Roman numerals as they are still used today in various forms e.g. on clocks.

What I like to show to my kids when explaining roman numerals is how they were used in practice, with a roman counting table or abacus. The way we learn for how to perform arithmetic with pen and paper in school, is not very efficient to do with roman numerals. But one thing I’ve learned from investigating old number systems is that you have to understand how they were used. People did not tend to perform elaborate calculations with pen and paper as today, but rather with counting tables or abacus as the one below.

With the roman system worked very well, and was quite logical. You see that we got the I, X, C columns. In the I column, every pebble is a 1. In the X column every pebble is a ten. And in the C column every pebble is a hundred. Above we got the V, L and X, which are fives, fifties and five hundred.

With the roman system you basically just write down what the pebbles say. That is quicker than converting to Arabic numerals. Likewise when reading a Roman number it is quick to put that down on a Roman abacus. For this reason Roman numerals were used all the way into the 1500s on Europe, long after Arabic numerals had been introduced.

Anyway, this story is about coding. Lets look at how we can parse roman numerals and turn them into Arabic numerals. Then the kids can try out themselves the numbers and convert them.

`roman_numerals =     Dict('I' => 1, 'X' => 10, 'C' => 100, 'M' => 1000,	 'V' => 5, 'L' => 50, 'D' => 500)function parse_roman(s::AbstractString)    s = reverse(uppercase(s))    vals = [roman_numerals[ch] for ch in s]    x = 0    for (i, v) in enumerate(vals)        if i > 1 && v < vals[i - 1]            x -= v        else            x += v        end    end    x end`

Here is an example from the Julia REPL of using the function to parse roman numerals.

`julia> parse_roman("II")2julia> parse_roman("IV")4julia> parse_roman("VI")6julia> parse_roman("IX")9julia> parse_roman("XI")11`

Lets have a look at how it works.

## Dictionaries

We map or translate the roman letter I, V, X etc to numbers using what is called a dictionary. A dictionary is made up of multiple pairs.

Here is a pair of the letter X and 10.

`julia> 'X' => 10'X'=>10`

We can put the pair in a variable `pair` and examine it.

`julia> pair = 'X' => 10'X'=>10`

The `dump()` function allows us to see which fields the pair is made up of.

`julia> dump(pair)Pair{Char,Int64}  first: Char X  second: Int64 10julia> pair.first'X': ASCII/Unicode U+0058 (category Lu: Letter, uppercase)julia> pair.second10`

We give a list of these pairs to create a dictionary.

`julia> roman_numerals =     Dict('I' => 1, 'X' => 10, 'C' => 100, 'M' => 1000,	 'V' => 5, 'L' => 50, 'D' => 500)`

The first values in each pair are called the keys in the dictionary, and the second value are called the value. So I, X and C are keys, while 1, 10 and 100 e.g. are values. We can ask a dictionary for the value corresponding to a key like this:

`julia> roman_numerals['C']100julia> roman_numerals['M']1000`

I utilize this dictionary to turn a string of roman letters into an array of regular numbers like this:

`vals = [roman_numerals[ch] for ch in s]`

This is a fancy way of creating an array in Julia, called a list comprehension. Let me show how it works by setting a value for `s`

`julia> s = "XVI"julia> vals = [roman_numerals[ch] for ch in s]3-element Array{Int64,1}: 10  5  1`

We could have achieved the same with more plain code:

`julia> for ch in s           push!(vals, roman_numerals[ch])       endjulia> vals3-element Array{Int64,1}: 10  5  1`

Before we do this lookup we perform the following

`s = reverse(uppercase(s))`

That is in case the we wrote the roman letters in lower case letters. Our dictionary relies on the letters being uppercase. We also reverse the order of character because it makes more sense to process them from low to high values.

## Conversion

`if i > 1 && v < vals[i - 1]   x -= velse   x += vend`

If we consider the roman number XVI, if we reverse it and turn it into numbers it will be `[1, 5, 10]`. So when e.g. `i = 2` then `v = 5`. If the numbers are in ascending order we just add them up, and get 16 in this case.

However if we process XIV, it will turn into the array `[5, 1, 10]`. In this case when we reach 1, we get the condition

`v < vals[i - 1]1 < vals[2 - 1]1 < vals[1]1 < 5`

Which means we subtract from the total value `x -= v`.

# Conclusion

My purpose with these articles about programming for parents is to show how even quite small and simple programs can be useful. Once you know enough programming, it will often be faster to write these programs than to search for a ready made programming doing what you want.

It is a fun exercise to do and doesn’t take that long time. As kids get older you can encourage them to experiment with changing these programs themselves.

Importantly when writing the programs yourself, you have the option to tailor them to your needs. You could e.g. easily modify this to work with the multiplication program from my previous article, to create a program for kids to practice roman numerals and get a score for how many they get correct.

When a ready made program, you are locked down to whatever the creators decided to use it for.

--

--

## More from Erik Engheim

Geek dad, living in Oslo, Norway with passion for UX, Julia programming, science, teaching, reading and writing.

Love podcasts or audiobooks? Learn on the go with our new app.

## Erik Engheim

Geek dad, living in Oslo, Norway with passion for UX, Julia programming, science, teaching, reading and writing.