Kotlin: Pluralize amount of currency - kotlin

I want to write some code to determine if I need to write "Quarter" or "Quarters" depending on the amount.
Up to now I have the following code:
fun main(args: Array<String>) {
var changeDue = 1.22;
Change(changeDue);
}
fun Change(changeDue: Double) {
var quarters = Math.floor(changeDue / 1.0);
print(Math.round(quarters * 4) / 1)
if (quarters <= 2)
println(" Quarters")
else if (quarters > 2)
println(" Quarter")
println("")
println(".22 remain")
}
Is it correct?
Is there a better way to achieve it?

It looks like you just have the logic backwards: it should be Quarter if quarters <= 1 and Quarters otherwise.

Related

Billing phone calculator

I have the code for my phone bill calculator. It charges users 0.25 for every minute they were over the plan and 15% tax on the subtotal. Now I have to separate the methods to calculate the tax, overage fees, and final total by printing the itemized bill. Can you help me to separate the methods?
import java.util.*
fun main(args: Array<String>) {
print("Enter the Total Minutes of Calls Made this Month: ")
val scan = Scanner(System.`in`)
val numberOfMinutes = scan.nextInt()
var excessMinutes = numberOfMinutes - 60
if (excessMinutes < 0) {
excessMinutes = 0
}
val bill = 10 + excessMinutes * 0.25
val taxedBill = bill * 1.15
println("\nTelephone Bill this Month = $taxedBill")
}
That's already a pretty short function, so I'm guessing refactoring it like that is a homework exercise! You need to work out how to break the steps down into separate tasks that return a result.
Try replacing this:
var excessMinutes = numberOfMinutes - 60
if (excessMinutes < 0) {
excessMinutes = 0
}
with this:
val excessMinutes = someFunction()
That's a val now, so you can't change it once you get the result. someFunction needs to do all the calculation, and return a result. What needs to go in that function? What type of value does it need to return? Do you need to pass any values into that function as parameters, so it can use them in the calculation?
Once you work that out, the rest should be pretty straightforward!
You can refactor it like that
import java.util.*
fun main() {
print("Enter the Minutes of Calls Made this Month: ")
val scan = Scanner(System.`in`)
val numberOfMinutes = scan.nextInt()
var excessMinutes = numberOfMinutes - 60
if (excessMinutes < 0) {
excessMinutes = 0
}
val bill = 10 + excessMinutes * 0.25
val fees = excessMinutes * 0.25
val taxedBill = bill * 1.15
val tax = taxedBill - bill
println("\nOverage fees = $fees")
println("\nTax = $tax")
println("\nFinal total = $taxedBill")
}

functions with multiple values not returning

fun main(args:Array<String>){
fun multiplyAndDivide(number: Int, factor: Int): Pair<Int, Int> {
return Pair(number * factor, number / factor)
}
val (product, quotient) = multiplyAndDivide(4, 2)
fun multiplyInferred(number: Int, multiplier: Int) = number * multiplier
}
Please I have spent hours trying to execute these codes but nothing is happens.
I only get
Process finished with exit code 0
I think this way you can use Pair in Kotlin to return multiple values from function:
fun returnTwoValues(): Pair<String, Int>{
return Pair("string_result", 15)
}
How to Access result:
val p = returnTwoValues()
val result1 = p.first
var result2 = p.second
To see the Result print it like this:
println("$result1, $result2")

Ranges in Kotlin

How do I write code to return a range of 10 numbers from a given number.
i.e if I am given 5, code should return 0..9
358 should return 350..359
33 should return 30..39 etc
Do you mean something like this?
fun range10(contained: Int): IntRange {
val start = contained - contained % 10
val end = start + 9
return start..end
}
If the given number is integer type, you can simply write
val x = 358
(x / 10 * 10)..(x / 10 * 10 + 9)
You can use the following code:
fun answer(givenNum: Int) : IntRange {
val startOfRange = givenNum - (givenNum % 10)
return startOfRange until (startOfRange + 10)
}
fun main() {
val givenNum = 33
println(answer(givenNum)) // 30..39
}

Operator overloading in Kotlin and how does this code work?

I am reading the following code from a tutorial but I don't really get it.
Basically it tries to use operator overloading so that the following code works:
return today + YEAR * 2 + WEEK * 3 + DAY * 5
What I understand:
This part:
operator fun MyDate.plus(timeInterval: TimeInterval): MyDate {
return addTimeIntervals(timeInterval, 1)
}
Enhances the class MyDate to support the + with a timeInterval so this would work myDate + YEAR for example.
This part:
operator fun MyDate.plus(timeIntervals: RepeatedTimeInterval)
= addTimeIntervals(timeIntervals.timeInterval, timeIntervals.number)
Enhances the class MyDate to support * with a RepeatedInterval
This part just declares an empty class with 2 member variables timeInterval and number
class RepeatedTimeInterval(val timeInterval: TimeInterval, val number: Int)
What I don't understand is how the multiplication is actually happening
since RepeatedInterval is just an empty class.
Could someone please help my understand this?
import TimeInterval.*
data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int)
enum class TimeInterval { DAY, WEEK, YEAR }
operator fun MyDate.plus(timeInterval: TimeInterval): MyDate {
return addTimeIntervals(timeInterval, 1)
}
class RepeatedTimeInterval(val timeInterval: TimeInterval, val number: Int)
operator fun TimeInterval.times(number: Int) = RepeatedTimeInterval(this, number)
operator fun MyDate.plus(timeIntervals: RepeatedTimeInterval)
= addTimeIntervals(timeIntervals.timeInterval, timeIntervals.number)
fun task1(today: MyDate): MyDate {
return today + YEAR + WEEK
}
fun task2(today: MyDate): MyDate {
return today + YEAR * 2 + WEEK * 3 + DAY * 5
}
Also this is part of the tutorial:
import java.util.Calendar
fun MyDate.addTimeIntervals(timeInterval: TimeInterval, number: Int): MyDate {
val c = Calendar.getInstance()
c.set(year, month, dayOfMonth)
when (timeInterval) {
TimeInterval.DAY -> c.add(Calendar.DAY_OF_MONTH, number)
TimeInterval.WEEK -> c.add(Calendar.WEEK_OF_MONTH, number)
TimeInterval.YEAR -> c.add(Calendar.YEAR, number)
}
return MyDate(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DATE))
}
YEAR * 2 is TimeInterval * Int. The compiler sees it isn't a built-in combination, so it looks for a method times marked as operator on TimeInterval which accepts Int (so e.g. TimeInterval.times(Int) or TimeInterval.times(Any)). This method can be a member of TimeInterval or an extension; there's absolutely no reason for it to be a member of RepeatedTimeInterval.
In fact, RepeatedTimeInterval doesn't have any part in resolving YEAR * 2 at all, it just happens to be the return type. Then today + YEAR * 2 is MyDate + RepeatedTimeInterval and the same rule is applied to pick operator fun MyDate.plus(timeIntervals: RepeatedTimeInterval) (and not operator fun MyDate.plus(timeInterval: TimeInterval) which is used for today + YEAR).
Note that with this code it isn't legal to have e.g. YEAR * 2 * 2; that would require RepeatedTimeInterval.times(Int) which again could be a member or an extension.
What I don't understand is how the multiplication is actually happening since RepeatedInterval is just an empty class.Could someone please help my understand this?
Well, the RepeatedTimeInterval class is indeed "an empty class", but notice that it has an extension function TimeInterval.times(number: Int) which makes it support the operation TimeInterval * Int, for example: YEAR * 2
I came accross this program while doing the Kotlin Koans: Operators overloading task, here's my solution:
import TimeInterval.*
data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int)
// Supported intervals that might be added to dates:
enum class TimeInterval { DAY, WEEK, YEAR }
class MultipleTimeInterval(val timeInterval: TimeInterval, val amont : Int)
operator fun TimeInterval.times(amont: Int) = MultipleTimeInterval (this, amont)
operator fun MyDate.plus(timeInterval: TimeInterval): MyDate = addTimeIntervals(timeInterval, 1)
operator fun MyDate.plus(multi: MultipleTimeInterval): MyDate = addTimeIntervals(multi.timeInterval, multi.amont)
fun task1(today: MyDate): MyDate {
return today + YEAR + WEEK
}
fun task2(today: MyDate): MyDate {
return today + YEAR * 2 + WEEK * 3 + DAY * 5
}
The utility function MyDate.addTimeIntervals() is:
import java.util.Calendar
fun MyDate.addTimeIntervals(timeInterval: TimeInterval, amount: Int): MyDate {
val c = Calendar.getInstance()
c.set(year + if (timeInterval == TimeInterval.YEAR) amount else 0, month, dayOfMonth)
var timeInMillis = c.timeInMillis
val millisecondsInADay = 24 * 60 * 60 * 1000L
timeInMillis += amount * when (timeInterval) {
TimeInterval.DAY -> millisecondsInADay
TimeInterval.WEEK -> 7 * millisecondsInADay
TimeInterval.YEAR -> 0L
}
val result = Calendar.getInstance()
result.timeInMillis = timeInMillis
return MyDate(result.get(Calendar.YEAR), result.get(Calendar.MONTH), result.get(Calendar.DATE))
}

Sum a subset of of numbers in a list

Is there a way in Kotlin for doing the sum() operation on a filtered list of numbers, without actually filtering out the elements first?
I'm looking for something like this:
val nums = listOf<Long>(-2, -1, 1, 2, 3, 4)
val sum = nums.sum(it > 0)
You can make use of Iterable<T>.sumBy:
/**
* Returns the sum of all values produced by [selector] function applied to each element in the collection.
*/
public inline fun <T> Iterable<T>.sumBy(selector: (T) -> Int): Int {
var sum: Int = 0
for (element in this) {
sum += selector(element)
}
return sum
}
You can pass a function to it where the function transforms negative value to 0. So, it sums up all values in the list which is greater than 0 since adding 0 makes no effect to the result.
val nums = listOf<Long>(-2, -1, 1, 2, 3, 4)
val sum = nums.sumBy { if (it > 0) it.toInt() else 0 }
println(sum) //10
If you require a Long value back, you have to write an extension for Long just like Iterable<T>.sumByDouble.
inline fun <T> Iterable<T>.sumByLong(selector: (T) -> Long): Long {
var sum: Long = 0
for (element in this) {
sum += selector(element)
}
return sum
}
Then, the toInt() conversion can be taken away.
nums.sumByLong { if (it > 0) it else 0 }
As suggested by #Ruckus T-Boom, if (it > 0) it else 0 can be simplified using Long.coerceAtLeast() which returns the value itself or the given minimum value:
nums.sumByLong { it.coerceAtLeast(0) }
sumBy and sumByDouble are Deprecated from kotlin 1.5 . You can check those link.
Use sumOf to get sum on a List or Array
sumOf
Returns the sum of all values produced by selector function applied to each element in the collection or Array.
Example:
data class Order(
val id : String,
val price : Double
)
val orderList = ......
val sum = orderList.sumOf { it.price }
data class Product(val name: String, val quantity: Int) {
}
fun main(args: Array<String>) {
val productList = listOf(
Product("A", 100),
Product("B", 200),
Product("C", 300)
)
val totalPriceInList1: Int = productList.map { it.quantity }.sum()
println("sum(): " + totalPriceInList1)
val totalPriceInList2: Int = productList.sumBy { it.quantity }
println("sumBy(): " + totalPriceInList2)
}
this is the result of our code
sum(): 600
sumBy(): 600