Solution to 2.1.3 with tests