TPP Topic 38: Programming by Coincidence
Tags: thepragmaticprogrammer, book, programming, education
Published: 2019-11-16 12:20:12

---
categories:
- The Pragmatic Programmer
published: true
tags:
- The Pragmatic Programmer
- book
- programming
- education
title: 'TPP Topic 38: Programming by Coincidence'
---

> This post originally appeared on [steadbytes.com](https://steadbytes.com/blog/the-pragmatic-programmer-20th/topic-38-exercises/) 
<div></div>
> See the [first post](https://dev.to/steadbytes/the-pragmatic-programmer-20th-anniversary-edition-series-1e2l) in The Pragmatic Programmer 20th Anniversary Edition series for an introduction.

## Exercise 25

> A data feed from a vendor gives you an array of tuples representing key-value pairs. The key of DepositAccount will hold a string of the account number in the corresponding value:

```
[
 ...
 {:DepositAccount, "564-904-143-00"}
 ...
]
```

> It worked perfectly in test on the 4-core developer laptops and on the 12-core build machine, but on the production servers running in containers, you keep getting the wrong account numbers. What’s going on?

Assuming that the key-value pairs are read into a hash map (or similar) data structure, for example in Clojure:

```clojure
user=> (into {} [[:DepositAccount "564-904-143-00"] [:OtherKey "Other Value"]])
{:DepositAccount "564-904-143-00", :OtherKey "Other Value"}
```

Then it is possible that the `:DepositAccount` is being overwritten due to multiple occurrences of a `:DepositAccount` tuple in the input array. An array of tuples will not enforce uniqueness of the keys, whereas a hash map does. Most hash map implementations will update the value of an existing key when a duplicate insert is performed:

```clojure
user=> (into {:DepositAccount "111-111-111-11"} [[:DepositAccount "564-904-143-00"]])
{:DepositAccount "564-904-143-00"}
```

The fact that it worked on laptops and the build machine is a coincidence that (I think) the authors included to lure the reader into a trap!

## Exercise 26

> You’re coding an autodialer for voice alerts, and have to manage a database of contact information. The ITU specifies that phone numbers should be no longer than 15 digits, so you store the contact’s phone number in a numeric field guaranteed to hold at least 15 digits. You’ve tested in thoroughly throughout North America and everything seems fine, but suddenly you’re getting a rash of complaints from other parts of the world. Why?

Again, the authors are throwing in additional information to demonstrate the trap of coincidence. The ITU's 15 digit length limit is not the cause of the problem, it is the use of a _numeric_ field to store phone numbers in the database. The ITU [E.164](https://www.itu.int/rec/T-REC-E.164/en) standard specifies that the _international_ call format start with a `+` sign. Characters such as `*` or leading zeros are also used in some areas. None of these can be stored in a _numeric_ field.

## Exercise 27

> You have written an app that scales up common recipes for a cruise ship dining room that seats 5,000. But you’re getting complaints that the conversions aren’t precise. You check, and the code uses the conversion formula of 16 cups to a gallon. That’s right, isn’t it?

The "cup" measurement has a surprising number of interpretations therefore the conversion stated in the exercise is dependent on both location and custom. From [Wikipedia](<https://en.wikipedia.org/wiki/Cup_(unit)>):

- United States

  - Legal cup = 240 ml
  - Customary cup = 1/2 of a liquid pint ~= 237 ml

- Commonwealth of Nations
  - Metric cup = 250 ml
  - Canadian cup = 8 imperial fluid ounces ~= 227 ml
  - United Kingdom = 10 imperial fluid ounces ~= 284 ml
- International
  - Latin American cup = 200 ml _or_ 250 ml _or_ either US cups
  - Japanese cup = 200 ml (legally) _or_ ~180mL (traditionally)

In this case, the programmer made the assumption that the app will only be used within the United States, converting between customary cups and liquid gallons.