article banner

Exercise: Implement shop functions

Implement the following functions:

  • getWaitingCustomers that returns the list of customers who ordered products that have not been delivered yet.
  • countProductSales that returns the number of times a given product was ordered.
  • getCustomers that returns the list of customers who made orders with total price greater than or equal to the given amount.

Starting code:

fun Shop.getWaitingCustomers(): List<Customer> = TODO() fun Shop.countProductSales(product: Product): Int = TODO() fun Shop.getCustomers(minAmount: Double): List<Customer> = TODO() data class Shop( val name: String, val customers: List<Customer> ) data class Customer( val name: String, val city: City, val orders: List<Order> ) data class Order( val products: List<Product>, val isDelivered: Boolean ) data class Product( val name: String, val price: Double ) data class City( val name: String )

This problem can either be solved in the below playground or you can clone kotlin-exercises project and solve it locally. In the project, you can find code template for this exercise in functional/collections/Shop.kt. You can find there starting code and unit tests.

Once you are done with the exercise, you can check your solution here.

Playground

import org.junit.Test import kotlin.test.assertEquals fun Shop.getWaitingCustomers(): List<Customer> = TODO() fun Shop.countProductSales(product: Product): Int = TODO() fun Shop.getCustomers(minAmount: Double): List<Customer> = TODO() data class Shop( val name: String, val customers: List<Customer> ) data class Customer( val name: String, val city: City, val orders: List<Order> ) data class Order( val products: List<Product>, val isDelivered: Boolean ) data class Product( val name: String, val price: Double ) data class City( val name: String ) class ShopFunctionsTests { @Test fun `getWaitingCustomers should get customers with any delivered order`() { // given val shop = Shop( name = "Test shop", customers = listOf( Customer( name = "Customer 1", city = City("City 1"), orders = listOf( Order( products = listOf( Product("Product 1", 1.0), Product("Product 2", 2.0), ), isDelivered = true, ), Order( products = listOf( Product("Product 3", 3.0), Product("Product 4", 4.0), ), isDelivered = false, ), ), ), Customer( name = "Customer 2", city = City("City 2"), orders = listOf( Order( products = listOf( Product("Product 5", 5.0), Product("Product 6", 6.0), ), isDelivered = true, ), Order( products = listOf( Product("Product 7", 7.0), Product("Product 8", 8.0), ), isDelivered = true, ), ), ), ), ) // when val result = shop.getWaitingCustomers() // then val expected = listOf( Customer( name = "Customer 1", city = City("City 1"), orders = listOf( Order( products = listOf( Product("Product 1", 1.0), Product("Product 2", 2.0), ), isDelivered = true, ), Order( products = listOf( Product("Product 3", 3.0), Product("Product 4", 4.0), ), isDelivered = false, ), ), ), ) assertEquals(expected, result) } @Test fun `getWaitingCustomers should not return customers with no orders`() { // given val shop = Shop( name = "Test shop", customers = listOf( Customer( name = "Customer 1", city = City("City 1"), orders = listOf( Order( products = listOf( Product("Product 1", 1.0), Product("Product 2", 2.0), ), isDelivered = true, ), Order( products = listOf( Product("Product 3", 3.0), Product("Product 4", 4.0), ), isDelivered = false, ), ), ), Customer( name = "Customer 2", city = City("City 2"), orders = listOf(), ), ), ) // when val result = shop.getWaitingCustomers() // then val expected = listOf( Customer( name = "Customer 1", city = City("City 1"), orders = listOf( Order( products = listOf( Product("Product 1", 1.0), Product("Product 2", 2.0), ), isDelivered = true, ), Order( products = listOf( Product("Product 3", 3.0), Product("Product 4", 4.0), ), isDelivered = false, ), ), ), ) assertEquals(expected, result) } @Test fun `getWaitingCustomers should not return customers all orders delivered`() { // given val shop = Shop( name = "Test shop", customers = listOf( Customer( name = "Customer 1", city = City("City 1"), orders = listOf( Order( products = listOf( Product("Product 1", 1.0), Product("Product 2", 2.0), ), isDelivered = true, ), Order( products = listOf( Product("Product 3", 3.0), Product("Product 4", 4.0), ), isDelivered = true, ), ), ), Customer( name = "Customer 2", city = City("City 2"), orders = listOf( Order( products = listOf( Product("Product 5", 5.0), Product("Product 6", 6.0), ), isDelivered = true, ), Order( products = listOf( Product("Product 7", 7.0), Product("Product 8", 8.0), ), isDelivered = true, ), ), ), ), ) // when val result = shop.getWaitingCustomers() // then assertEquals(listOf(), result) } @Test fun `countProductSales should count repeating sales`() { // given val p1 = Product("Product 1", 1.0) val p2 = Product("Product 2", 2.0) val p3 = Product("Product 3", 3.0) val shop = Shop( name = "Test shop", customers = listOf( Customer( name = "Customer 1", city = City("City 1"), orders = listOf( Order( products = listOf(p1, p2), isDelivered = true, ), Order( products = listOf(p1, p3), isDelivered = false, ), ), ), Customer( name = "Customer 2", city = City("City 2"), orders = listOf( Order( products = listOf(p1, p1), isDelivered = true, ), Order( products = listOf(p2, p3), isDelivered = true, ), ), ), ), ) // then assertEquals(4, shop.countProductSales(p1)) assertEquals(2, shop.countProductSales(p2)) assertEquals(2, shop.countProductSales(p3)) } @Test fun `countProductSales should count sales with exactly the same product`() { // given val shop = Shop( name = "Test shop", customers = listOf( Customer( name = "Customer 1", city = City("City 1"), orders = listOf( Order( products = listOf(Product("Product 2", 1.0), Product("Product 1", 2.0)), isDelivered = true, ), ), ), ), ) // then assertEquals(0, shop.countProductSales(Product("Product 1", 1.0))) assertEquals(1, shop.countProductSales(Product("Product 2", 1.0))) assertEquals(1, shop.countProductSales(Product("Product 1", 2.0))) assertEquals(0, shop.countProductSales(Product("Product 2", 2.0))) } @Test fun `getCustomers should get customers with orders with total price greater than minAmount`() { // given val p1 = Product("Product 1", 1.0) val p2 = Product("Product 2", 2.0) val p3 = Product("Product 3", 3.0) val p4 = Product("Product 4", 4.0) val p5 = Product("Product 5", 5.0) val p6 = Product("Product 6", 6.0) val p7 = Product("Product 7", 7.0) val p8 = Product("Product 8", 8.0) val c1 = Customer( name = "Customer 1", city = City("City 1"), orders = listOf( Order( products = listOf(p1, p2), isDelivered = true, ), Order( products = listOf(p1, p3), isDelivered = false, ), ), ) val c2 = Customer( name = "Customer 2", city = City("City 2"), orders = listOf( Order( products = listOf(p1, p1), isDelivered = true, ), Order( products = listOf(p2, p3), isDelivered = true, ), ), ) val c3 = Customer( name = "Customer 3", city = City("City 3"), orders = listOf( Order( products = listOf(p4, p5), isDelivered = true, ), Order( products = listOf(p6, p7), isDelivered = true, ), ), ) val c4 = Customer( name = "Customer 4", city = City("City 4"), orders = listOf( Order( products = listOf(p8, p8), isDelivered = true, ), ), ) val shop = Shop( name = "Test shop", customers = listOf(c1, c2, c3, c4), ) // then assertEquals(listOf(c1, c2, c3, c4), shop.getCustomers(0.0)) assertEquals(listOf(c3, c4), shop.getCustomers(10.0)) assertEquals(listOf(c3), shop.getCustomers(20.0)) assertEquals(listOf(), shop.getCustomers(30.0)) } }