<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Hidde Wieringa</title>
    <description>The latest articles on Forem by Hidde Wieringa (@hiddewie).</description>
    <link>https://forem.com/hiddewie</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F9756%2F1140a450-5fb2-4795-9994-139c81dfc7af.jpeg</url>
      <title>Forem: Hidde Wieringa</title>
      <link>https://forem.com/hiddewie</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hiddewie"/>
    <language>en</language>
    <item>
      <title>A dozenal clock</title>
      <dc:creator>Hidde Wieringa</dc:creator>
      <pubDate>Sat, 08 Oct 2022 20:19:14 +0000</pubDate>
      <link>https://forem.com/hiddewie/a-dozenal-clock-38lp</link>
      <guid>https://forem.com/hiddewie/a-dozenal-clock-38lp</guid>
      <description>&lt;p&gt;Digital clocks around the world use 24 hours each day to display the time. In the night the day starts as 00:00, 00:59, 01:00, 01:59, 02:00, up to 23:00 and 23:59. (Actually, digital time goes up to 24:00 when the day has a leap second.)&lt;/p&gt;

&lt;p&gt;Analog clocks display the night starting at 12 (top of the clock). After the large hand has traveled all the way from 12, 1, 2, ..., 11 and back to 12, an hour has passed and the small hand points at 1. This repeats until afternoon, when the same time displays as the middle of the night and both hands point to the 12. After another 12 hours it is night again and the day has passed.&lt;/p&gt;

&lt;p&gt;Some countries use AM and PM to denote the time. There the first hour of the day is 12PM (in the night), then 1AM, 2AM, until 12AM (end of the morning), which turns to 1PM, 2PM etc. until 12PM in the night. This notation follows the analog clock.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions
&lt;/h2&gt;

&lt;p&gt;For a long time I have wondered why clocks work this way. I asked myself the following questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Why is the fist hour of the day named 12 PM, and the following hours start at 1, 2, 3, etc.?&lt;/li&gt;
&lt;li&gt;Why does the afternoon not start at 10:00 (when the first digit in the hours changes from 0 to 1)?&lt;/li&gt;
&lt;li&gt;Why do we have 60 minutes in an hour, but are analog clocks divided into 12 sets of 5 minutes?&lt;/li&gt;
&lt;li&gt;If the digital time is 13:11, why can't I find these numbers on an analog clock?&lt;/li&gt;
&lt;li&gt;Both 10:00 and 22:00 point at the same number on an analog clock. Why don't these times look similar?&lt;/li&gt;
&lt;li&gt;Why does an analog clock have three numbers on the clock which have two digits, while the other numbers have one digit?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These questions got me thinking about time, the division of hours and minutes, and the representation of hours and minutes on a digital and analog clock.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to base-12
&lt;/h2&gt;

&lt;p&gt;Instead of writing numbers in base 10 (&lt;em&gt;decimal system&lt;/em&gt;), we will write numbers in base 12, the &lt;em&gt;dozenal system&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To do that we need two new symbols to represent the decimal numbers 10 and 11. &lt;/p&gt;

&lt;p&gt;Following the worldwide society that uses base-12 or duodecimal numbers (&lt;a href="http://www.dozenalsociety.org.uk/"&gt;British&lt;/a&gt;, &lt;a href="http://www.dozenal.org"&gt;American&lt;/a&gt;), we shall use the ↊ and ↋ symbols. They are pronounced &lt;em&gt;dek&lt;/em&gt; and &lt;em&gt;el&lt;/em&gt;. (You may also find the Greek symbols χ and ξ used for &lt;em&gt;dek&lt;/em&gt; and &lt;em&gt;el&lt;/em&gt;, but the ↊ and ↋ symbols have been officially accepted into Unicode since 2015.) &lt;/p&gt;

&lt;p&gt;The first twelve numbers are then: 1, 2, 3, 4, 5, 6, 7, 8, 9, ↊, ↋ and 10.&lt;/p&gt;

&lt;p&gt;The digits ↊ and ↋ are easly and uniquely and recognizably representable on a seven-segment display (used in many digital clocks). They can be respresented as 🯲 and 🯳, but turned around 180 degrees. The 🯲 is the same upside down, and the top bar can be removed to make it unique.&lt;/p&gt;

&lt;p&gt;There is even a &lt;a href="https://www.ctan.org/tex-archive/fonts/dozenal"&gt;LaTeX package &lt;code&gt;dozenal&lt;/code&gt;&lt;/a&gt; that supports dozenal numbers. Wikipedia has a comprehensive article about the &lt;a href="https://en.wikipedia.org/wiki/Duodecimal"&gt;dozenal system and its history&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A new way to write the time
&lt;/h2&gt;

&lt;p&gt;We will use the dozenal number system to create a better representation for clocks, both digial and analog.&lt;/p&gt;

&lt;p&gt;For digital clocks, the following system is used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first digit denotes the night/morning as &lt;code&gt;0&lt;/code&gt; and the afternoon/evening as &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The second digit denotes the hour, &lt;code&gt;0&lt;/code&gt; up to &lt;code&gt;↋&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The hours and minutes are separated by a &lt;code&gt;·&lt;/code&gt;, although &lt;code&gt;:&lt;/code&gt; is also accepted.&lt;/li&gt;
&lt;li&gt;The third digit denotes the number of 5-minute groups in the hour, &lt;code&gt;0&lt;/code&gt; up to &lt;code&gt;↋&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The fourth digit denotes the minute in the 5-minute group, &lt;code&gt;0&lt;/code&gt; up to &lt;code&gt;4&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second and third digits can be emphasized either by font size, or by font weight (bold font), although it is not required.&lt;/p&gt;

&lt;p&gt;A whole day then looks as the following on a digital clock:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first minute is &lt;code&gt;00·00&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The second minute is &lt;code&gt;00·01&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The fifth minute is &lt;code&gt;00·04&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The sixth minute is &lt;code&gt;00·10&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;... and so on until the last minute of the first hour is &lt;code&gt;00:↋4&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The first minute of the of the second hour is &lt;code&gt;01:00&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The last minute before noon is &lt;code&gt;0↋:↋4&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Noon is &lt;code&gt;10:00&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The last minute of the day is &lt;code&gt;0↋:↋4&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A leap second would be represented as &lt;code&gt;20:00&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For analog clocks, the numbers from 0 to ↋ are spaced evenly around the clock. The number 0 is at the top.&lt;/p&gt;

&lt;p&gt;For analog clocks we have the following times:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🕛 is &lt;code&gt;00·00&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🕧 is &lt;code&gt;00·60&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🕐 is &lt;code&gt;01·00&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🕜 is &lt;code&gt;01·60&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🕤 is &lt;code&gt;09·60&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🕙 is &lt;code&gt;0↊·00&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🕦 is &lt;code&gt;0↋·60&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that seconds are left out of these examples, but they can be appended and represented the same way as the minutes are represented.&lt;/p&gt;

&lt;p&gt;Think about the representation for a bit. What is often denoted as AM / PM can now be seen as the first digit. The morning and evening times &lt;code&gt;0↊·00&lt;/code&gt; and &lt;code&gt;1↊·00&lt;/code&gt; are represented as almost the same time. Skimming the time, it is usually only neccesary to look at the second and third digit instead of all four digits. The quarters of the hour can be identified by the digits &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;, &lt;code&gt;6&lt;/code&gt; and &lt;code&gt;9&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  In practice
&lt;/h2&gt;

&lt;p&gt;The theory is nice, but I decided to put the theory into practice as well in my life, in as many places as possible.&lt;/p&gt;

&lt;p&gt;For my digital watch (a Garmin device, with programmable clock faces) I made a Garmin watch face that displays the dozenal time. View the &lt;a href="https://apps.garmin.com/en-US/apps/869126ca-c617-4ca3-a23a-f6cae06985ff"&gt;app on Connect IQ&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3W7E0YEm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/scopadwlwes1fkifvxdt.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3W7E0YEm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/scopadwlwes1fkifvxdt.jpeg" alt="Garmin watch face" width="880" height="1173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The wall in my office has a self-made dozenal analog clock. It has been laser-cut from a sheet of steel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A0APakm_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wpht0td3cc536cbnml2b.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A0APakm_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wpht0td3cc536cbnml2b.jpeg" alt="Wall clock" width="880" height="698"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My laptop runs Ubuntu and its system clock is visualized in my task bar using a dozenal clock.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2ONlgu-I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ys5vbjaf4l2esi3wxm1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2ONlgu-I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ys5vbjaf4l2esi3wxm1.png" alt="Laptop system clock" width="870" height="196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are other places where I might implement dozenal clocks to replace the decimal clocks, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;my mobile phone&lt;/li&gt;
&lt;li&gt;my alarm clock&lt;/li&gt;
&lt;li&gt;system-wide date formatting, (I tried, see &lt;a href="https://unix.stackexchange.com/questions/593900/call-script-in-locale-definition"&gt;my question on Unix StackExchange&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me know if you have more ideas!&lt;/p&gt;

</description>
      <category>clock</category>
      <category>dozenal</category>
      <category>base12</category>
      <category>decimal</category>
    </item>
    <item>
      <title>(Java)Money and Kotlin</title>
      <dc:creator>Hidde Wieringa</dc:creator>
      <pubDate>Sat, 17 Apr 2021 14:55:57 +0000</pubDate>
      <link>https://forem.com/hiddewie/java-money-and-kotlin-57ac</link>
      <guid>https://forem.com/hiddewie/java-money-and-kotlin-57ac</guid>
      <description>&lt;p&gt;The &lt;a href="https://javamoney.github.io/"&gt;JavaMoney API&lt;/a&gt; is part of &lt;a href="https://jcp.org/en/jsr/detail?id=354"&gt;JSR 354&lt;/a&gt; and will (hopefully) be part of the Java language in the future. The reference implementation &lt;a href="https://github.com/JavaMoney/jsr354-ri"&gt;Moneta&lt;/a&gt; provides good examples of implementations using the JavaMoney API.&lt;/p&gt;

&lt;p&gt;The JavaMoney API allows working with &lt;em&gt;currencies&lt;/em&gt;, &lt;em&gt;monetary values&lt;/em&gt; and &lt;em&gt;conversion&lt;/em&gt; between monetary values of different currencies through &lt;em&gt;exchange rates&lt;/em&gt;. View the &lt;a href="https://www.youtube.com/watch?v=heH08CROmb0"&gt;Devoxx video&lt;/a&gt; which explains the API in depth.&lt;/p&gt;

&lt;p&gt;Kotlin is interoperable with compiled Java libraries. So the JavaMoney/Moneta library can be used from Kotlin code, and makes working with money in business logic easy. After all, money seems trivial but details like rounding, conversion and catalogues of locales and currencies are hard to implement correctly.&lt;/p&gt;

&lt;p&gt;The JavaMoney API is very flexible and extendable. The classes and interfaces provide a Builder pattern to contruct instances with fluent code. For example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Construct a monetary value of €200 using the FastMoney implementation&lt;/span&gt;
&lt;span class="nc"&gt;Monetary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAmountFactory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;FastMoney&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCurrencyUnit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EUR"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setNumber&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MonetaryContextBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MathContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DECIMAL128&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The builder pattern does not look like ideomatic Kotlin. In Kotlin, &lt;a href="https://kotlinlang.org/docs/type-safe-builders.html"&gt;builder DSLs&lt;/a&gt; are used instead to fluently construct complex objects.&lt;/p&gt;

&lt;p&gt;That is exactly what I implemented in &lt;a href="https://github.com/hiddewie/money-kotlin"&gt;Money-Kotlin&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Money-Kotlin
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/hiddewie/money-kotlin"&gt;Money-Kotlin&lt;/a&gt; library extends the JavaMoney API with Kotlin extension functions.&lt;/p&gt;

&lt;p&gt;The example above could be rewritten in Kotlin as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Construct a monetary value of €200 using the FastMoney implementation&lt;/span&gt;
&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ofCurrency&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FastMoney&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;monetaryContext&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MathContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DECIMAL128&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More details are given below. Some of the (Java) examples are taken from the &lt;a href="https://github.com/JavaMoney/jsr354-ri/blob/master/moneta-core/src/main/asciidoc/userguide.adoc"&gt;Moneta User Guide&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monetary amounts
&lt;/h3&gt;

&lt;p&gt;The first example displayed above shows how to construct monetary values. Often we do not need a monetary context.&lt;/p&gt;

&lt;p&gt;Java:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Monetary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAmountFactory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;FastMoney&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCurrencyUnit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EUR"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setNumber&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;200.01&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;money&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;200.01&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ofCurrency&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FastMoney&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can manipulate money amounts as well, just like regular numbers. This has been implemented using Kotlin operator overloading.&lt;/p&gt;

&lt;p&gt;Java:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;MonetaryAmount&lt;/span&gt; &lt;span class="n"&gt;money&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...;&lt;/span&gt;

&lt;span class="c1"&gt;// add&lt;/span&gt;
&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;plus&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// subtract &amp;amp; negate&lt;/span&gt;
&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subtract&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;negate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// multiply&lt;/span&gt;
&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// divide &amp;amp; remainder&lt;/span&gt;
&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;divide&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;money&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remainder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// add&lt;/span&gt;
&lt;span class="n"&gt;money&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;money&lt;/span&gt;
&lt;span class="p"&gt;+&lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;

&lt;span class="c1"&gt;// subtract &amp;amp; negate&lt;/span&gt;
&lt;span class="n"&gt;money&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;money&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt;

&lt;span class="c1"&gt;// multiply&lt;/span&gt;
&lt;span class="n"&gt;money&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;
&lt;span class="mf"&gt;2.0&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;money&lt;/span&gt;

&lt;span class="c1"&gt;// divide &amp;amp; remainder&lt;/span&gt;
&lt;span class="n"&gt;money&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;
&lt;span class="n"&gt;money&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Currencies
&lt;/h3&gt;

&lt;p&gt;You can access a default or self-implemented currency (like Bitcoin) from the &lt;code&gt;Monetary&lt;/code&gt; singleton.&lt;/p&gt;

&lt;p&gt;Java:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;CurrencyUnit&lt;/span&gt; &lt;span class="n"&gt;currencyEUR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Monetary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCurrency&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EUR"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="s"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asCurrency&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Locales
&lt;/h3&gt;

&lt;p&gt;The JavaMoney API associates a locale with a currency. For example, in The Netherlands the official currency is the Euro. Some countries have multiple currencies.&lt;/p&gt;

&lt;p&gt;Java:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"NL"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Monetary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCurrency&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"NL"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;Monetary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCurrencies&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"NL"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="s"&gt;"NL"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asCountryLocale&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="s"&gt;"NL"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asCountryLocale&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getCurrency&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="s"&gt;"NL"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asCountryLocale&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getCurrencies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Rounding
&lt;/h3&gt;

&lt;p&gt;A monetary value can be rounded in a specific way. Construct a rounding query to get a &lt;code&gt;MonetaryRounding&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Java:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Monetary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRounding&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;RoundingQueryBuilder&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setScale&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RoundingMode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HALF_UP&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;Monetary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRounding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;roundingQuery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setScale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RoundingMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HALF_UP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Currency conversion
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;MonetaryAmount&lt;/code&gt; can be converted from one currency to another currency through a &lt;code&gt;CurrencyConversion&lt;/code&gt;. A &lt;code&gt;CurrencyConversion&lt;/code&gt; depends on a conversion provider. There are some default providers implemented out of the box, like the &lt;em&gt;European Central Bank&lt;/em&gt; (ECB) and &lt;em&gt;International Monetary Fund&lt;/em&gt; (IMF). These providers provide currency exchange rates, in particular historic rates.&lt;/p&gt;

&lt;p&gt;The order of the default providers are configurable, and you can implement your own conversion provider as well.&lt;/p&gt;

&lt;p&gt;Java:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;ExchangeRateProvider&lt;/span&gt; &lt;span class="n"&gt;rateProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MonetaryConversions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getExchangeRateProvider&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ECB"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"IMF"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;MonetaryAmount&lt;/span&gt; &lt;span class="n"&gt;amountInEUR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...;&lt;/span&gt;
&lt;span class="nc"&gt;MonetaryAmount&lt;/span&gt; &lt;span class="n"&gt;amountInCHF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;amountInEUR&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rateProvider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getExchangeRate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EUR"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"CHF"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Using the default rate providers&lt;/span&gt;
&lt;span class="nc"&gt;MonetaryAmount&lt;/span&gt; &lt;span class="n"&gt;amountInCHF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;amountInEUR&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MonetaryConversions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getExchangeRateProvider&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getExchangeRate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EUR"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"CHF"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;rateProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MonetaryConversions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getExchangeRateProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ECB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"IMF"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;amountInEUR&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;amountInCHF&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;amountInEUR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;convertTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CHF"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rateProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Using the default rate providers&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;amountInCHF&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;amountInEUR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;convertTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CHF"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Formatting
&lt;/h3&gt;

&lt;p&gt;Monetary amounts are formatted in the context of a locale.&lt;/p&gt;

&lt;p&gt;Java:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;MonetaryAmountFormat&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MonetaryFormats&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAmountFormat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GERMANY&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;MonetaryAmount&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...;&lt;/span&gt;
&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;amount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;format&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Locale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GERMANY&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;monetaryAmountFormat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;You can use the Money-Kotlin library today! It has been published on &lt;a href="https://search.maven.org/artifact/nl.hiddewieringa/money-kotlin/"&gt;Maven Central&lt;/a&gt;, and can be added as a dependency.&lt;/p&gt;

&lt;p&gt;There are many more examples in the &lt;a href="https://github.com/hiddewie/money-kotlin/#readme"&gt;project readme&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Gradle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"nl.hiddewieringa:money-kotlin:$moneyKotlinVersion"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maven:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;nl.hiddewieringa&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;money-kotlin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;${moneyKotlin.version}&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/hiddewie/money-kotlin"&gt;Feedback, feature requests and bug reports&lt;/a&gt; are welcome!&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>money</category>
      <category>java</category>
      <category>jsr354</category>
    </item>
    <item>
      <title>Ruby devs, how do you work?</title>
      <dc:creator>Hidde Wieringa</dc:creator>
      <pubDate>Mon, 09 Mar 2020 19:27:06 +0000</pubDate>
      <link>https://forem.com/hiddewie/ruby-devs-how-do-you-work-49ap</link>
      <guid>https://forem.com/hiddewie/ruby-devs-how-do-you-work-49ap</guid>
      <description>&lt;p&gt;This post is more like a request for discussion thread than a normal 'informational' post. First some history.&lt;/p&gt;

&lt;h3&gt;
  
  
  Daily work
&lt;/h3&gt;

&lt;p&gt;In the company I work at, we use many different languages, but mostly based on the Java (JVM) ecosystem (Java, Groovy, Kotlin, etc.) and Ruby ecosystem (Rails, etc.). Most of the teams work with one language/ecosystem, but once in a while we collaborate on some code work in a different language than our daily work. That is fun, challenging and very good for learning new patterns and code styles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Observations
&lt;/h3&gt;

&lt;p&gt;I usually work within the JVM ecosystem (mostly Kotlin), and feel very confortable there. The standard library is great, there is a lot of learning content available for such a new language, and it is possible to build on the shoulders of a giant (Java) in terms of libraries and performance.&lt;/p&gt;

&lt;p&gt;Whenever I collaborate and write Ruby code, I feel a little bit powerless. The first thing I do when I open a project which is not my daily code base, I scroll around the directories and files, and look around.&lt;/p&gt;

&lt;p&gt;Then, when we start working on the problem at hand, we open the corresponding files and start editing. The first thing I do is Ctrl + click two times:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find all the usages of the class/function we are working in (get to know the context of the work);&lt;/li&gt;
&lt;li&gt;Find the definition of a referenced class or variable (what are we working with).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This does not work in Ruby (and many other interpreted languages), as any piece of code can call any other piece of code. Even methods (Ruby does not seem to have properties) can be added dynamically. Things like dependency injection are not really a thing (&lt;a href="http://weblog.jamisbuck.org/2008/11/9/legos-play-doh-and-programming"&gt;http://weblog.jamisbuck.org/2008/11/9/legos-play-doh-and-programming&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This leads me to the following set of questions I would like to ask the community.&lt;/p&gt;

&lt;h3&gt;
  
  
  Questions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;How do you find out about usages or definitions of models in code that you did not write, know little about but have to refactor for some reason?&lt;/li&gt;
&lt;li&gt;Apart from test coverage, how do you make sure you do not break anything when changing something else? Even with test coverage: do you unit test every property call?&lt;/li&gt;
&lt;li&gt;How do you store knowledge in the code about some model, like which properties mean what, which are required during construction, which must exist together etcetera? Ruby is object-oriented to its core (&lt;a href="https://www.ruby-lang.org/en/about"&gt;https://www.ruby-lang.org/en/about&lt;/a&gt;), so encapsulation is important. I fail to understand how to encapsulate something that any other piece of code can extend or modify.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hopefully this lets me get a better feeling on how developers can work with interpreted languages like Ruby. Thanks in advance for the discussion!&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>healthydebate</category>
    </item>
    <item>
      <title>Creating a custom cycling map from open data</title>
      <dc:creator>Hidde Wieringa</dc:creator>
      <pubDate>Mon, 09 Sep 2019 19:22:49 +0000</pubDate>
      <link>https://forem.com/hiddewie/creating-a-custom-cycling-map-3g2a</link>
      <guid>https://forem.com/hiddewie/creating-a-custom-cycling-map-3g2a</guid>
      <description>&lt;p&gt;During the past month, I have created a specific style for generating cycling maps, using only publicly available data.&lt;/p&gt;

&lt;h1&gt;
  
  
  Goal
&lt;/h1&gt;

&lt;p&gt;In July and August, I was on holyday in Poland, Slovakia and Hungary. For finding the way in those countries, I had a map (good old paper). I was cycling from camping to camping, so a good map was required. Unfortunately, Poland and Hungary had no good maps made for the purpose of cycling. That means that sometimes I could not find the way, and needed to use a mobile phone (mostly using the app Maps.Me with data of OpenStreetMap).&lt;/p&gt;

&lt;p&gt;This problem stayed in my head. I am very enthusiastic about projects like OpenStreetMap, which collects and publishes the data for free (license: &lt;a href="https://www.openstreetmap.org/copyright" rel="noopener noreferrer"&gt;ODbL&lt;/a&gt;). The data quality is usually great, and the map details are far greater than for example Google Maps, Apple Maps or TomTom. Also, the data is updated very quickly if something changes, all by volunteering contributors.&lt;/p&gt;

&lt;p&gt;The goal of this project is as follows: “Generate a printable map of any region in the world, using only publicly available data and tools, usable for cycling.” The process described in the following sections is the end result of this project. It took some weeks to learn about the technology, tooling and data. Then, by trial and error, the resulting map was improved step by step.&lt;/p&gt;

&lt;h1&gt;
  
  
  Stack
&lt;/h1&gt;

&lt;p&gt;To reach the project goal, some tooling is needed. Fortunately, many people have gone before me that have a lot of knowledge about generating maps. I collected this knowledge from blogs, guides and websites.&lt;/p&gt;

&lt;p&gt;For this project, I used the following stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Linux Subsystem for Windows&lt;/em&gt;. My main machine is Windows, and most of the tools do not run on Windows. Also, command-line scripting is not that easy in Windows. The command-line, apt, and the Linux ecosystem is essential for getting and running the needed tools.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Mapnik 2.x&lt;/em&gt;. C++ and Python bindings are available, so it is more a library than a program. There is a newer version of Mapnik (3.x), but the Python bindings do not exist or have no documentation (or both).&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Python 2.7&lt;/em&gt;. For Mapnik 2.x the bindings are for Python 2.7. This is pre-installed in every mainstream Linux installation.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;GDAL&lt;/em&gt;. These libraries are used for generating the contour lines and hillshade for the height data. There is a command-line interface with very good online documentation.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Postgres (with GIS extensions)&lt;/em&gt;. A Postgres database has extensions (PostGIS) which allow loading spatial data (with locations), and generating efficient indices for querying spatial data. This is essential for processing the data quickly from the database to the map.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Getting the data
&lt;/h1&gt;

&lt;p&gt;The data comes from two places. The content of the map (roads, features, land use, etc.) comes from OpenStreetMap. That data has been refined (sorted, filtered and grouped) by &lt;a href="https://www.geofabrik.de" rel="noopener noreferrer"&gt;GeoFabrik&lt;/a&gt;. This means that ambiguity of some data is removed, and the data is labeled in a structured way. Also, they publish a nice document describing the structure of the data. For each country (and sometimes part of the country) a separate zip file must be downloaded.&lt;/p&gt;

&lt;p&gt;The other required data is height data. This data is used for generating contour lines and ‘hillshading’ (if there is a steep hill, it is colored a darker shade on one side). The height data of the world is available from a number of different sources, but I get it from &lt;a href="https://dds.cr.usgs.gov/srtm/version2_1/SRTM3" rel="noopener noreferrer"&gt;here&lt;/a&gt;. The data is measured by NASA satellites of the Shuttle Radar Topography Mission (SRTM) project.&lt;/p&gt;

&lt;p&gt;Finally, I use the OpenStreetMap data a second time. This time, it is downloaded from another source. For the borders of countries, the GeoFabrik data is not usable (their free service doesn’t have this data, but their premium service does). The boundaries are downloaded from &lt;a href="https://wambachers-osm.website/boundaries" rel="noopener noreferrer"&gt;wambachers-osm.website&lt;/a&gt; instead.&lt;/p&gt;

&lt;h1&gt;
  
  
  Processing the data
&lt;/h1&gt;

&lt;p&gt;A common way for spatial data (any data with a location attached to it) to be formatted is shapefiles. A shapefile describes vector data, a point, line or polygon, possibly with attributes. For example, a shapefile containing roads will contain lines with the shapes of the roads, and attributes with the name of the road and the speed limit. The lines can be used on the map, and the attributes can be used to style the data differently for each type of road. Each set of data has multiple files, each with a different responsibility. Most GIS applications and scripts can work with shapefiles.&lt;/p&gt;

&lt;p&gt;For our use case shapefiles would work, but they are limited in their performance and possibilities. For example, if I want to create a map that spans multiple areas or countries, I would have to change the script to add more data sources. That is why all shapefiles are imported into a Postgres database. Shapefiles with the same kind of data are imported into the same table, and can be queried once to find all the data of that type for the map.&lt;/p&gt;

&lt;p&gt;The height data also has to be processed. The height data does not come as a shapefile (it does not have a vector shape), but rather as a raster file. It can be seen as a large grid of ‘pixels’ having some value. In addition to the value, each pixel can have attributes, just like shapefiles. The SRTM3 data has a file per latitude and longitude degree squared.f&lt;/p&gt;

&lt;p&gt;The height data is processed in two ways. First of all, the contour lines are generated from the height raster. The GDAL libraries are used for this. The interval of the contours can be specified (I use every 20 meters). The result is a shapefile, containing lines for each contour, with a height attribute which can be used to style the contour on the map.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gdal_contour &lt;span class="nt"&gt;-i&lt;/span&gt; 20 &lt;span class="nt"&gt;-snodata&lt;/span&gt; &lt;span class="nt"&gt;-32768&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; height N49E019.hgt N49E019.shp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In addition to contour lines, I also generate the hillshading. This is also done with the GDAL libraries, with the hillshade command. Note that the result is not a shape file, but another raster file. The raster file contains the ‘shade’ of the hill, a value between 0 and 1 depending on the orientation and steepness of the slope. The defaults work well: the light source comes from the north west (default for many maps), at an angle of 45 degrees.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gdaldem hillshade N49E019.hgt N49E019.shade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h1&gt;
  
  
  Creating the map style
&lt;/h1&gt;

&lt;p&gt;Once the data is ready, the map can be generated by making style for each part of the data. The description that follows took many steps, and manual checking of the rendered result. This styling is in no way perfect, but at least optimized for cycling.&lt;/p&gt;

&lt;p&gt;Each section below can be seen as a layer (actually, they are the names of the Mapnik layers). The first layer is on the bottom, and every following layer is printed ‘over’ it. Sometimes I use a transparent layer to add information to the map, while keeping the information under it visible.&lt;/p&gt;
&lt;h4&gt;
  
  
  Background: land use
&lt;/h4&gt;

&lt;p&gt;The background of the map will be white, with an overlay of forest (light green).&lt;/p&gt;
&lt;h4&gt;
  
  
  Contours and hillshade
&lt;/h4&gt;

&lt;p&gt;Over the background, the hillshade will be printed (with a low opacity), such that hills become visible. The contours are added to that, such that hills and mountains will become visible by rings of contour lines. Normal contour lines are every 20 meters, while thicker contour lines are every 100 meters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fefo8qfd5tc93tnrr3zym.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fefo8qfd5tc93tnrr3zym.png" alt="Hillshade"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Cities and military
&lt;/h4&gt;

&lt;p&gt;Two special types of land use are added after the hillshading. Cities (with residential land use), and military areas are marked especially. Cities need to be visible on the map: they give structure to the road network and names. Military areas are off-limits for civilians.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8ueofxuxy0z605oomvh7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8ueofxuxy0z605oomvh7.png" alt="Cities and military"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Borders
&lt;/h4&gt;

&lt;p&gt;Borders of countries need to be visible. They get a transparent thick background such that they are easily visible in the large-scale structure of the map.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fd1nkohmnqoa3o5214khs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fd1nkohmnqoa3o5214khs.png" alt="Border"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Water
&lt;/h4&gt;

&lt;p&gt;Water is important to get a good overview of the area (together with forest areas). Lakes give structure to the map, and streams and rivers also give information on hills, mountains and valleys. Rivers and streams always flow perpendicular to contour lines, and parallel to valleys.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1s00a8txawv9dhzkhe2b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1s00a8txawv9dhzkhe2b.png" alt="Water"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Trains
&lt;/h4&gt;

&lt;p&gt;Train tracks show connections between large cities and towns. They are visible in the landscape because they are long and straight. Stations are often listed on road signs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fy21dujgpc5hsedx6pxse.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fy21dujgpc5hsedx6pxse.png" alt="Trains"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Roads (and bridges)
&lt;/h4&gt;

&lt;p&gt;Most of the work has been done on roads. They sound easier than they are, because there are many types and they connect with each other.&lt;/p&gt;

&lt;p&gt;The general idea for roads is “more important is on top”. That means small paths first, then dirt roads, then general small roads, then tertiary roads (small roads with a name), then secondary roads, primary roads and trunk roads (between a primary road and motorway, the use differs per country). Finally, motorways. And to make things hard: cycleways need to be visible over every kind of road, but not too invasive.&lt;/p&gt;

&lt;p&gt;But that is not always the case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  For all roads, the borders should always be on the bottom, and the roads themselves should be on top.&lt;/li&gt;
&lt;li&gt;  If a tertiary road contains a bridge over a motorway, it has to be displayed over the motorway (even the border!).&lt;/li&gt;
&lt;li&gt;  If there are ‘link’ segments, for example going from a secondary road to a trunk road, the crossing has to contain the link sections on the bottom, and the main roads on top.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These requirements make a beautiful list of (some repeated) styles for roads and their borders.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffbyi8n7528gq672qhfvq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffbyi8n7528gq672qhfvq.png" alt="Roads"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Names of cities, roads, and contours
&lt;/h4&gt;

&lt;p&gt;One of the primary features of a map is the names of the things on the map. Cities are the most important: they give information on where roads lead. All names of cities, villages, hamlets and even suburbs of cities are printed.&lt;/p&gt;

&lt;p&gt;But roads also have names (references). They are often listed on road signs. If there is space on the map, the names are printed along the road.&lt;/p&gt;

&lt;p&gt;Finally, the contour line heights. They have little priority, but can give context how high the surroundings are. If there is any space left on the map, the heights of the 100-meter contour lines are also printed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fj4tmhz03cvyu92734zwc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fj4tmhz03cvyu92734zwc.png" alt="labels"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Places of interest (icons)
&lt;/h4&gt;

&lt;p&gt;The last layer of the map are icons of places of interest. Especially in a city they can be good references (think of churches with a high tower). I have selected a list of places of interest that do not clutter the map too much, and give enough information to be useful. The map contains places of worship (churches, mosques, synagogues, etc.), shops, bicycle repair shops, campings and castles.&lt;/p&gt;

&lt;p&gt;Each icon has a circle background (partly transparent) to make it more visible in the whole.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fonf1slnyf20nk670vm2v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fonf1slnyf20nk670vm2v.png" alt="Places of interest"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Creating the map
&lt;/h1&gt;

&lt;p&gt;In Mapnik the layers above can be defined using a Python script. For each layer a data source is used, and the features of that data source are printed on the map using some style. The features can be filtered such that a style is only applied to some features. For example: the data source for roads contain all roads. It has many styles, for example one for primary roads which are a bridge.&lt;/p&gt;

&lt;p&gt;The Python script creates all layers, and Mapnik generates an XML of the description of the map. This XML file is portable and can be used directly by anyone, without running the Python script.&lt;/p&gt;

&lt;p&gt;Using the map description (either from the XML file of from the Python script), Mapnik can output many kinds of images. It has many options for JPG and PNG files, but it can also create PDF files. That is useful for vector features with infinite resolution (good for printing).&lt;/p&gt;
&lt;h1&gt;
  
  
  Scripting it all together
&lt;/h1&gt;

&lt;p&gt;In addition to the Python script for creating the map, I have also made a bash script which downloads the data required for the map in an automated way. For some areas multiple files have to be downloaded and processed, and this is cumbersome to do by hand.&lt;/p&gt;

&lt;p&gt;The bash script will download all the height data, process it into hillshade and contour lines and add it to the Postgres database. Then it will download the country borders of the selected countries and add them to the Postgres database. Finally, the map data is downloaded and also added to the database.&lt;/p&gt;

&lt;p&gt;This makes running the scripts for a different set of countries easy: only the names of the countries, and the latitude/longitude ranges of the map are needed.&lt;/p&gt;
&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;This is the end result of the map.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fghe904aqf0bdg8ep17i0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fghe904aqf0bdg8ep17i0.png" alt="End result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For me, this is a long time wish which has come true. I just needed a problem for which generating a custom map was the solution. I plan to use a printed version of my own map the next time I go on a cycling holiday, and test it in the real world.&lt;/p&gt;

&lt;p&gt;The source code and scripts can be found on in the GitHub repository. Feel free to leave comments and suggestions for improvement!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/hiddewie" rel="noopener noreferrer"&gt;
        hiddewie
      &lt;/a&gt; / &lt;a href="https://github.com/hiddewie/osm-cycling-maps" rel="noopener noreferrer"&gt;
        osm-cycling-maps
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Generating beatiful cycling maps using Mapnik and OpenStreetMap data
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Generating a custom cycling map with Mapnik and Carto&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;View the blogpost describing this project at &lt;a href="https://dev.to/hiddewie/creating-a-custom-cycling-map-3g2a" rel="nofollow"&gt;https://dev.to/hiddewie/creating-a-custom-cycling-map-3g2a&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Download the &lt;a href="https://github.com/hiddewie/map-it/releases/download/v5.0.0/map.pdf" rel="noopener noreferrer"&gt;example PDF output&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/hiddewie/osm-cycling-mapsassets/cover.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fhiddewie%2Fosm-cycling-mapsassets%2Fcover.png" alt="Expected output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/hiddewie/osm-cycling-mapsassets/printed3.jpg"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fhiddewie%2Fosm-cycling-mapsassets%2Fprinted3.jpg" alt="Printed map"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/hiddewie/osm-cycling-mapsassets/printed4.jpg"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fhiddewie%2Fosm-cycling-mapsassets%2Fprinted4.jpg" alt="Printed map"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/hiddewie/osm-cycling-mapsassets/printed5.jpg"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fhiddewie%2Fosm-cycling-mapsassets%2Fprinted5.jpg" alt="Printed map"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Cartography and features&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/hiddewie/osm-cycling-mapsdocs/cartography.md" rel="noopener noreferrer"&gt;Cartography&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hiddewie/osm-cycling-mapsdocs/features.md" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting started&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;There are three scripts in this repository:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/hiddewie/osm-cycling-mapsscripts/download.sh" rel="noopener noreferrer"&gt;&lt;code&gt;scripts/download.sh&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Downloads the required data into a Postgres database for the map.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/hiddewie/osm-cycling-mapsscripts/generate.py" rel="noopener noreferrer"&gt;&lt;code&gt;scripts/generate.py&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A Python script which will generate the map for a Mapnik configuration. The Mapnik configuration can be generated by running
Carto against &lt;code&gt;carto/project.mml&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/hiddewie/osm-cycling-mapsscripts/bounds.py" rel="noopener noreferrer"&gt;&lt;code&gt;scripts/bounds.py&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A Python script which will output a list of bounding boxes that will fit the configured page size and bounding box perfectly.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See the environment variables which can be configured for the scripts below.&lt;/p&gt;

&lt;p&gt;Copy the distributed environment file &lt;a href="https://github.com/hiddewie/osm-cycling-maps.env.dist" rel="noopener noreferrer"&gt;&lt;code&gt;.env.dist&lt;/code&gt;&lt;/a&gt; to &lt;code&gt;.env&lt;/code&gt;. Fill in the required credentials for the &lt;a href="https://www.usgs.gov/" rel="nofollow noopener noreferrer"&gt;U.S. Geological Survey&lt;/a&gt;. You can modify the &lt;code&gt;.env&lt;/code&gt; file to suit your needs.&lt;/p&gt;

&lt;p&gt;The scripts are packaged as Docker images, and configured in…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/hiddewie/osm-cycling-maps" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>map</category>
      <category>mapnik</category>
      <category>script</category>
      <category>python</category>
    </item>
    <item>
      <title>From QWERTY to Colemak</title>
      <dc:creator>Hidde Wieringa</dc:creator>
      <pubDate>Sat, 22 Jun 2019 14:14:59 +0000</pubDate>
      <link>https://forem.com/hiddewie/from-qwerty-to-colemak-1nmo</link>
      <guid>https://forem.com/hiddewie/from-qwerty-to-colemak-1nmo</guid>
      <description>&lt;p&gt;This year I made the successful switch from a QWERTY to a Colemak layout for all my keyboards. This is the story of my journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  QWERTY and its problems
&lt;/h2&gt;

&lt;p&gt;Most people in the world that communicate using Latin characters use a QWERTY layout (or some variant like AZERTY, QUERTZ, etc.) for their keyboards. This is because of historical reasons: typewriters became popular and they had the QWERTY layout. The reason was not for improving ergonomics, but rather to avoid jamming.&lt;/p&gt;

&lt;p&gt;For computers, jamming is not an issue. Multiple layouts that have most keys different from the QWERTY layout have been invented. Examples are Dvorak, Colemak and Maltron. There are also layouts that are not widely used but shared online. Anyone can make and share a keyboard layout nowadays, for example using a tool like &lt;a href="https://www.microsoft.com/en-us/download/details.aspx?id=22339"&gt;Microsoft Keyboard Layout Creator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The QWERTY layout is not designed for ergonomics. For persons who write (either words or code) whole days on end, this can become an issue. Also, it is interesting to experience an alternative to the layout everyone is using.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dvorak
&lt;/h2&gt;

&lt;p&gt;A few years ago, I started learning the Dvorak layout. This layout is a popular alternative to QWERTY based layouts. There is some documentation online, and in most systems the layout is built in as a keyboard selection.&lt;/p&gt;

&lt;p&gt;I practiced online until I could type reasonably well (but not very quickly) using the layout. After a few months I was seriously considering switching permanently. However, for my day-to-day work I noticed a large problem. The shortcuts for cut, copy and paste (and some others), were suddenly in a very different location on the keyboard. Of course, it is possible to remap these shortcuts but that was not an option. I want to be able to use a system and program as is, independent of the keyboard layout.&lt;/p&gt;

&lt;p&gt;This was a blocker. I stopped practicing and reverted quickly to QWERTY.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;Luckily, the story did not end there. The idea to learn an alternative keyboard layout stayed in my head. I had three goals I wanted to achieve, namely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Have around the same typing speed as I had using QWERTY (not quantified).&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Type with ten fingers.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;I could not type with ten fingers, but rather used around six fingers in strange combinations and patterns.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Reduce the number of errors while typing.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I made many typing errors when using QWERTY. This made for quick typing but I still lost a lot of performance because I had to ‘backspace’ to correct mistakes.&lt;/p&gt;

&lt;p&gt;I compiled a list with requirements I wanted to have for my ideal layout. I came up with the following list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Good ergonomic properties.&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;Measuring ergonomics can be done in many different ways. Layouts are often optimized for different metrics. For me, the layout must score well in usage of the home row, and alternating letters between two hands.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Some widespread use around the world.&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;This makes sure that there is documentation, and tools for practicing are available (online or offline). There will also be some analysis of the ergonomics available.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Software switchable&lt;/em&gt;.  &lt;/p&gt;

&lt;p&gt;The layout must be available by switching using software only. This is usually independent of the layout and most OSes support this.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Has to fit basic system/program shortcut keys.&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;I want to be able to use a system without modifying the entire system before using the layout. This is especially useful if I have to use a someone else’s system. Only a keyboard layout change is needed.   &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Extensible for programming.&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;The layout must be able to allow extensions for programming. Many layouts support this. It usually means switching the numbers and symbols around, independent of the letters.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted to learn to type well (with 10 fingers), so the software requirement meant that I used the other layout when typing on a QWERTY keyboard. Looking at the keyboard while typing did &lt;em&gt;not&lt;/em&gt; help!&lt;/p&gt;

&lt;p&gt;One factor which was not mentioned above but which is important when choosing a layout, is the language you optimize for. For me that is English, although I am Dutch. This influences the layout a lot, because the usage of letters and combinations is different across different languages. In English the combination ‘&lt;em&gt;th’&lt;/em&gt; is common, while in Dutch the combination &lt;em&gt;‘ij’&lt;/em&gt; is common.&lt;/p&gt;

&lt;h2&gt;
  
  
  Colemak, here I come!
&lt;/h2&gt;

&lt;p&gt;My choice for my future keyboard layout became Colemak. As far as I could find, it is the second most used alternative layout for Latin writing, after Dvorak. There is a &lt;a href="https://colemak.com/"&gt;wiki&lt;/a&gt; with some history and many links and tips for learning and troubleshooting Colemak (although some resources are outdated).&lt;/p&gt;

&lt;h3&gt;
  
  
  Tools
&lt;/h3&gt;

&lt;p&gt;Some tools are also highlighted on the wiki. There are many online and offline typing tools, and often different layouts are supported. This is important, because using a typing tool which teaches you the QWERTY layout will have different exercises than one teaching Colemak. (Think of the home row, the first lesson. QWERTY will use the &lt;em&gt;‘F’&lt;/em&gt; and &lt;em&gt;‘J’&lt;/em&gt; keys, but Colemak will use the &lt;em&gt;‘T’&lt;/em&gt; and &lt;em&gt;‘N’&lt;/em&gt; keys.)&lt;/p&gt;

&lt;p&gt;It is important to have a tool which highlights and punishes errors while typing.&lt;/p&gt;

&lt;p&gt;I used &lt;a href="https://www.keybr.com"&gt;keybr&lt;/a&gt; which keeps a history of previous practicing, records typing speed and letters which are ‘hard’ (high error rate).&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation (on Windows)
&lt;/h3&gt;

&lt;p&gt;Windows does not have a native Colemak layout installed. However, the Colemak wiki contains an installer which makes installing it easy. Linux (Debian) and MacOS have the layout installed out of the box.&lt;/p&gt;

&lt;p&gt;Once the layout is installed, switch by finding your keyboard settings and selecting the Colemak layout. Often a preview is available of the mapping.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caps lock
&lt;/h3&gt;

&lt;p&gt;The Colemak layout officially has the Caps Lock key mapped to Backspace. In Windows this can be a problem, so I did not include that mapping in my learning process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hardware layout
&lt;/h3&gt;

&lt;p&gt;There are also keyboards which have a hardware mapping of the Colemak layout. This means that the OS will have the ‘normal’ QWERTY layout, but the keyboard will send Colemak keystrokes as if they had been typed on a QWERTY keyboard.&lt;/p&gt;

&lt;p&gt;I did not use this option, but it can be useful when pair programming with two keyboards. One person can use QWERTY, the other can use Colemak.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practicing
&lt;/h3&gt;

&lt;p&gt;Using the tools listed above, I started practicing. I checked for compatibility with my systems (at home, at work, my mobile devices) and workflow. Most of thetime was used on evenings and in weekends to learn more and more keys of the  layout. I usually took 20-40 minutes per practice session. Actually, this took more energy than I had thought. This is logical: every keystroke of every practice word takes mental effort of growing muscle memory.&lt;/p&gt;

&lt;p&gt;All this time I was using the QWERTY layout in my day-to-day work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Switch
&lt;/h2&gt;

&lt;p&gt;After practicing for around two months, I switched my mobile phone to a Colemak layout. I knew the basic layout by then, and I only use two fingers when typing mobile, while looking at the keyboard. This worked great. My speed dropped for a few weeks, but otherwise the switch was clean. And now I was practicing extra whenever I was using my phone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cold turkey
&lt;/h3&gt;

&lt;p&gt;My grand strategy for making the full switch of all my remaining keyboards was as follows. I had a few weeks of Christmas holiday in which I had to type very little. The perfect moment for activating a new layout and starting to type slowly and painfully. This also made sure that my work did not suffer too much.&lt;/p&gt;

&lt;p&gt;In the Christmas holiday I also started doing that year’s Advent of Code puzzles, in a programming language I never used before (Clojure). This was a great match. Luckily, it worked and I met no surprises that made me have to switch back to QWERTY.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day-to-day work
&lt;/h3&gt;

&lt;p&gt;The second day of January I took up my regular work. This consists of programming, so a lot of typing. Of course, my colleagues knew I had made the switch to Colemak, and I encountered no problems. By forcing myself to use Colemak I quickly came to a basic typing speed which was more than enough to get my work done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Experiences
&lt;/h2&gt;

&lt;p&gt;After the full switch to the Colemak layout, I noticed some things that were not a problem but needed some attention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shortcuts
&lt;/h3&gt;

&lt;p&gt;I use many shortcuts. However, finding them was sometimes difficult. For example, locking my computer uses &lt;em&gt;‘Super + L’&lt;/em&gt;, but the ‘L’ is mapped to the QWERTY ‘U’. The difference between typing and using shortcuts becomes visible: for shortcuts we often look at the keyboard to find a single key. This does not work when the keyboard keys to not match the actual letters when pressed. On the other hand, I now unconsciously remember that locking my computer requires &lt;em&gt;‘Super + U’&lt;/em&gt; when I am using a Colemak layout.&lt;/p&gt;

&lt;p&gt;And to repeat the requirement above: this was not a problem for &lt;em&gt;select all&lt;/em&gt;, &lt;em&gt;cut&lt;/em&gt;, &lt;em&gt;copy&lt;/em&gt; and &lt;em&gt;paste&lt;/em&gt; because those keys are in the same location as in the QWERTY layout.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting up to speed
&lt;/h3&gt;

&lt;p&gt;It took around two months after the full switch to come up to speed. That is around five months since I started practicing with the Colemak layout. Notice that I don’t quantify ‘up to speed’. As discussed in my list of requirements, I wanted to become around as quick as I was before the switch, while making less mistakes and typing with ten fingers.&lt;/p&gt;

&lt;p&gt;I see that typing is ‘quick enough’ for my needs, but also that there is a lot to be learned and practiced. A whole life of training QWERTY cannot be reverted and relearned in another layout, within half a year.&lt;/p&gt;

&lt;h3&gt;
  
  
  Errors
&lt;/h3&gt;

&lt;p&gt;The most errors I make are usages of the ‘D’ and ‘T’ keys. They are present in many words, and typed by the same finger. That means that muscle memory sometimes swaps them around.&lt;/p&gt;

&lt;p&gt;A see the increase of errors especially when typing while thinking hard or explaining something to someone. Hopefully this will improve over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrospective (looking back)
&lt;/h2&gt;

&lt;p&gt;I am very happy with my new layout. Because of my list of requirements, I could learn the new layout and be reasonably sure that it would work out (compared to learning Dvorak). The effort required for learning the new layout is very reasonable in my opinion.&lt;/p&gt;

&lt;p&gt;In my day-to-day work, it can be funny when other people try typing on my keyboard. They want to demonstrate something, try typing it in my console, look at the typed text, backspace it away, try again and then have a beautiful bewildered face. It is nice to see how people expect keyboards to have a certain layout.&lt;/p&gt;

&lt;p&gt;The second thing I noticed, is that QWERTY experience disappears very quickly. Whenever I have to type QWERTY (a public computer, or my disk encryption password before my system is booted), it feels as if I first started with Colemak.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tips
&lt;/h3&gt;

&lt;p&gt;I advise others to switch their layout. The experience alone is worth it, and the benefits of Colemak (or another alternative layout) make the switch worthwhile. When you consider the switch, I found the following points helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Practice first, then make cold switch.&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;Get to know the layout. First study the layout (it will be impossible to remember) and then start practicing. By slowly learning more and more letters you learn to type correctly. When you know the layout, make the cold turkey switch. This forces you to learn the last part of the muscle memory and become really fluent when typing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Focus on making little errors. Speed will come later.&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;If you switch too early, many errors will creep in. They are very hard to unlearn (as I noticed personally when using QWERTY). When using the new layout on a day-to-day basis, speed will come.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Switch mobile quickly.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This helped me a lot when practicing the Colemak layout. Because I was already using the new layout on mobile devices, it became easier to remember the locations of new letters.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;I notice now that there are more things that I can do to improve my typing experience. The switch to Colemak made me more conscious of my keyboard usage, typing habits and shortcut usage.&lt;/p&gt;

&lt;p&gt;For now, I use exactly the same (hardware) keyboards I used before the switch. I am looking for a different keyboard that is ergonomic and supports my Colemak typing. Some properties I want are an ortholinear layout (keys are not staggered horizontally, but rather in a grid) or vertically staggered. Also, a split keyboard would be great, so I can move and tune both parts based on the location of my hands.&lt;/p&gt;

&lt;p&gt;Colemak specific requirements are a better programmer layout (I use the QWERTY number and symbol mappings) and mapping the Caps Lock key to the Backspace key (because who ever uses a Caps Lock key?).&lt;/p&gt;

&lt;p&gt;I hope that this article explains some of my thinking and may inspire you to make the switch to an alternative keyboard layout!&lt;/p&gt;

&lt;h2&gt;
  
  
  Postscript
&lt;/h2&gt;

&lt;p&gt;For this article I had to write the word ‘QWERTY’ a lot. While this is easy on a keyboard with a QWERTY layout, it is strange to type on a Colemak layout.&lt;/p&gt;

</description>
      <category>qwerty</category>
      <category>colemak</category>
      <category>keyboard</category>
    </item>
  </channel>
</rss>
