Skip to content

Commit

Permalink
✨ validate amounts
Browse files Browse the repository at this point in the history
  • Loading branch information
velizartodorov committed Oct 19, 2024
1 parent 5b534e9 commit 77556d5
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 30 deletions.
30 changes: 28 additions & 2 deletions src/main/kotlin/coin/Coin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,39 @@ enum class Coin(val value: Int) {
TWO_EUROS(200);

companion object {
val descending = values().reversed()
private val descending = values().reversed()

fun getArray(numbers: List<Int>): Array<Coin> {
fun format(numbers: List<Int>): Array<Coin> {
return numbers.mapNotNull { coin ->
values().find { it.value == coin }
}.toTypedArray()
}

fun format(coins: Array<Coin>) = format(get(coins.toList()))

fun format(coins: List<Coin>) = format(get(coins))

fun get(coins: List<Coin>?): Int {
return coins?.sumOf { it.value } ?: 0
}

fun format(cents: Int): String {
val euros = cents / 100
val remainingCents = cents % 100
return String.format("%d.%02d €", euros, remainingCents)
}

fun get(input: Int): List<Coin> {
val coins = mutableListOf<Coin>()
var amount = input
for (coin in descending) {
while (amount >= coin.value) {
coins.add(coin)
amount -= coin.value
}
}
return coins
}

}
}
25 changes: 5 additions & 20 deletions src/main/kotlin/drinks/impl/Drink.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ sealed interface Drink {

fun prepare(order: Order): OrderResponse {
val drink = order.drink ?: throw IllegalArgumentException("Drink not specified")
val amount = getAmount(order.coins)
val amount = Coin.get(order.coins)
val change = amount - price
val status = if (amount >= price) DONE else IN_PROGRESS
val orderResponse = OrderResponse(getChange(change), status, drink)
val orderResponse = OrderResponse(Coin.get(change), status, drink)
println("$name ordered successfully! Preparing ...")
prepareDrink(order)
if (change > 0) {
println("Take your change: ${orderResponse.change}")
val formatChange = Coin.format(orderResponse.change)
println("Take your change: $formatChange")
}
if (orderResponse.status == DONE) {
println("$name prepared successfully! Take it!")
Expand All @@ -35,22 +36,10 @@ sealed interface Drink {
return orderResponse
}

private fun getChange(change: Int): List<Coin> {
val coins = mutableListOf<Coin>()
var remainingChange = change
for (coin in Coin.descending) {
while (remainingChange >= coin.value) {
coins.add(coin)
remainingChange -= coin.value
}
}
return coins
}

private fun getErrorMessage(order: Order) =
"Amount insufficient for $name! " +
"Needed amount: $price " +
"Current amount: ${getAmount(order.coins)}"
"Current amount: ${Coin.get(order.coins)}"

fun getAmount(strength: Strength?): Amount = when (strength) {
LOW -> Amount.LOW
Expand All @@ -77,10 +66,6 @@ sealed interface Drink {
?: throw IllegalArgumentException("Number unsupported: $number")
}

fun getAmount(coins: List<Coin>?): Int {
return coins?.sumOf { it.value } ?: 0
}

fun getDrink(drinkType: String?): Drink {
val drinks = Drink::class.sealedSubclasses
for (drinkClass: KClass<out Drink> in drinks) {
Expand Down
18 changes: 10 additions & 8 deletions src/main/kotlin/vending_machine/intefaces/CoinsInterface.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ object CoinsInterface : UserInterface {
███████╗██║ ╚████║ ██║ ███████╗██║ ██║ ╚██████╗╚██████╔╝██║██║ ╚████║███████║
╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝╚══════╝
====================================================================================
Price: ${Drink.getDrink(order.drink).price} cents
""".trimIndent()
""".trimIndent()
)
}

Expand All @@ -33,12 +32,13 @@ object CoinsInterface : UserInterface {
"""

override fun process(order: Order): Order {
val value: List<Int> = inputCoins()
val coins = Coin.getArray(value)
val value: List<Int> = input(order)
val coins = Coin.format(value)
val price = Drink.getDrink(order.drink).price
val amount = Drink.getAmount(coins.toList())
val amount = Coin.get(coins.toList())
val formatPrice = Coin.format(coins)
if (amount >= price) {
println("Coins inserted: ${coins.contentToString()}")
println("Amount inserted: $formatPrice")
order.coins(*coins)
} else {
println(insufficientAmount(order, price, amount))
Expand All @@ -48,10 +48,12 @@ object CoinsInterface : UserInterface {
return order
}

private fun inputCoins(): List<Int> {
private fun input(order: Order): List<Int> {
val drink = Drink.getDrink(order.drink)
println("Price: ${Coin.format(drink.price)}")
val value: List<Int>
while (true) {
println("Please enter the coins (only numbers allowed):")
print("Please enter the coins (only numbers allowed): ")
val input = readln()
if (input.all { it.isDigit() || it.isWhitespace() }) {
value = input.split(" ")
Expand Down

0 comments on commit 77556d5

Please sign in to comment.