How do I test a functionality with multiple inputs/expected outputs?
Here is a really simple example:
scenario "Can add two numbers", {
given "Two numbers", {
num1 = 2
num2 = 3
}
when "I trigger add.", {
result = add(num1,num2)
}
then "The result should be correct.", {
result.shouldBe 5
}
}
I want to test this with multiple values, say add(4,8).shouldBe 12, ....
Whats the best practice to do this? In other BDD frameworks I have seen table like structures to implement this, but cannot find something like that in EasyB. Should I create multiple scenarios to cover this (appending (1), (2) to the scenario name), or should I put the inputs and expected outputs into an array, and check this for equality?
If I use the latter approach, how do I get meaningfull failures?
Use the where/example clause
http://code.google.com/p/easyb/wiki/ChangesInEasyb098
package org.easyb.where
/*
Example tests a map at the story level
*/
numberArray = [12, 8, 20, 199]
where "we are using sample data at a global level", [number:numberArray]
before "Before we start running the examples", {
given "an initial value for counters", {
println "initial"
whenCount = 0
thenCount = 0
numberTotal = 0
}
}
scenario "Number is #number and multiplier is #multiplier and total is #{number * multiplier}", {
when "we multiply #number by #multiplier", {
whenCount ++
num = number * multiplier
}
then "our calculation (#num) should equal #{number * multiplier}", {
num.shouldBeGreaterThan 0
numberTotal += num
thenCount ++
}
where "Multipliers should be", {
multiplier = [1,2,3]
}
}
after "should be true after running example data", {
then "we should have set totals", {
whenCount.shouldBe 12
thenCount.shouldBe 12
num = 0
numberArray.each { n ->
num = num + (n + (2*n) + (3*n))
}
num.shouldBe numberTotal
}
}
Related
I can't figure out how to solve the following problem: there is a number n. Output the numbers to the console in order separated by a space, but so that the next digit in the iteration is output as many times as it is a digit, and at the same time so that there are no more than n digits in the output. Сan anyone suggest the correct algorithm?
example: have n = 7, need print (1 2 2 3 3 3 4) in kotlin
what i try:
var n = 7
var count = 1
var i = 1
for (count in 1..n) {
for (i in 1..count) {
print(count)
}
}
}
var n = 11
var count = 1
var i = 1
var size = 0
// loop# for naming a loop in kotlin and inside another loop we can break or continue from outer loop
loop# for (count in 1..n) {
for (i in 1..count) {
print(count)
size++
if (size == n){
break#loop
}
}
}
You can use "#" for naming loops and if you want to break from that loop, you can use this syntax in kotlin. It worked for me.
For kotlin labeled break you can look at this reference: link
var count = 1
var n = 7
for(count in 1..n) {
print(count.toString().repeat(count))
}
count.toString() converts an integer to a string, .repeat() function repeats count times the string.
In case you need to add a space between each number, you can add the following:
print(" ")
Using generateSequence and Collections functions:
val n = 7
println(generateSequence(1) {it + 1}
.flatMap{e -> List(e){e}}
.take(n)
.joinToString(" "))
Your example is correct, You have to put a space between the printing
you can follow the code from this link
Kotlin lang code snippet
or the following code snippet
fun main() {
var n = 7
var count = 1
var i = 1
for (count in 1..n) {
for (i in 1..count) {
print(count)
print(' ')
}
}
}
For completeness, here's another approach where you write your own sequence function which produces individual values on demand (instead of creating intermediate lists)
sequence {
var digit = 1
while (true) {
for (i in 1..digit) yield(digit)
digit++
}
}.take(7)
.joinToString(" ")
.run(::print)
Not a big deal in this situation, but good to know!
On the Android Studio emulator The user is required to enter a maximum of 10 numbers. When I put in the number 1 the output shows 0 instead of 1 (this is for the min number; the max works perfectly fine) Can anyone please assist me in this problem. I tried using minOf() and max() nothing worked Below is a snippet of my source code:
val arrX = Array(10) { 0 }
.
.
.
.
findMinAndMaxButton.setOnClickListener {
fun getMin(arrX: Array<Int>): Int {
var min = Int.MAX_VALUE
for (i in arrX) {
min = min.coerceAtMost(i)
}
return min
}
fun getMax(arrX: Array<Int>): Int {
var max = Int.MIN_VALUE
for (i in arrX) {
max = max.coerceAtLeast(i)
}
return max
}
output.text = "The Min is "+ getMin(arrX) + " and the Max is " + getMax(arrX)
}
}
}
Is there anything that can be done to get this work?
You're initialising arrX to a bunch of zeroes, and 0.coerceAtMost(someLargerNumber) will always stick at 0.
Without seeing how you set the user's numbers it's hard to say what you need to do - but since you said the user enters a maximum of 10 numbers, at a guess there are some gaps in your array, i.e. indices that are still set to 0. If so, they're going to be counted in your min calculation.
You should probably use null as your default value instead - that way you can just ignore those in your calculations:
val items = arrayOfNulls<Int?>(10)
// this results in null, because there are no values - handle that however you like
println(items.filterNotNull().minOrNull())
>> null
// set values on some of the indices
(3..5).forEach { items[it] = it }
// now this prints 3, because that's the smallest of the numbers that -do- exist
println(items.filterNotNull().minOrNull())
>> 3
I'm kind of stuck, I don't know how to make the second loop to start 1 position above the first loop in Kotlin.
I have an array (named myArray) with 10 elements, I need to Write a Kotlin program that prints the number that has the most consecutive repeated number in the array and also prints the number of times it appears in the sequence.
The program must parse the array from left to right so that if two numbers meet the condition, the one that appears first from left to right will be printed.
Longest: 3
Number: 8
fun main() {
val myArray: IntArray = intArrayOf(1,2,2,4,5,6,7,8,8,8)
for((index , value) in myArray.withIndex()){
var inx = index + 1
var count = 0
var longest = 0
var number = 0
for((inx,element) in myArray.withIndex()) {
if(value == element ){
count+=
}
}
if(longest < count){
longest = count
number = value
}
}
}
I'm against just dropping answers, but it is quite late for me, so I'll leave this answer here and edit it tomorrow with more info on how each part works. I hope that maybe in the meanwhile it will help you to gain some idea to where you might be going wrong.
val results = mutableMapOf<Int, Int>()
(0..myArray.size - 2).forEach { index ->
val current = myArray[index]
if (current == myArray[index + 1]) {
results[current] = (results[current] ?: 1) + 1
}
}
val (max, occurrences) = results.maxByOrNull { it.value } ?: run { println("No multiple occurrences"); return }
println("Most common consecutive number $max, with $occurrences occurrences")
Alternatively if the intArray would be a list, or if we allowed to change it to a list myArray.toList(), you could replace the whole forEach loop with a zipWithNext. But I'm pretty sure that this is a HW question, so I doubt this is the expected way of solving it.
myList.zipWithNext { a, b ->
if (a == b) results[a] = (results[a] ?: 1) + 1
}
All the letters of the English alphabet are divided into vowels and consonants.
A word is considered euphonious if it doesn't have three or more vowels or consonants in a row.
My goal is to create euphonious words from the discordant ones and output the minimum number of characters needed to create a euphonious word from a given word.
Examples:
Input:
schedule
Output:
1
Input:
biiiiig
Output:
2
Code
fun main() {
val word = readLine()!!.toMutableList()
checkWord(word)
}
fun isVowel(c: Char): Boolean {
val vowels = listOf('a', 'e', 'i', 'o', 'u', 'y')
return c in vowels
}
fun checkWord(word: MutableList<Char>){
var counter = 0
for (number in 0 .. word.size - 2) {
if (isVowel(word[number]) && isVowel(word[number + 1]) && isVowel(word[number + 2])) {
counter++
word.add(number + 2, 'b')
// println(word)
}
if (!isVowel(word[number]) && !isVowel(word[number + 1]) && !isVowel(word[number + 2])) {
counter++
word.add(number + 2, 'a')
// println(word)
}
}
println(counter)
}
My code is working for those examples but not for a case like eeeeeeeeeeeeeeeee where the output is supposed to be 8 but my counter is 6.
Since the list is growing as you iterate, your for loop never reaches the end of the list. Your code can be fixed by replacing
for (number in 0 .. word.size - 2) {
with
var number = -1
while (++number < word.size - 1) {
so it checks the current list size on each iteration.
I want to point out however that it is unnecessary to use a MutableList and keep enlarging it since you don't use the "fixed" euphonious list afterwards. It is also unnecessary to repeatedly search neighbors on each iteration. You can just count as you go.
fun checkWord (word: String) {
var count = 0
var currentTypeCount = 0
var lastTypeVowel = true
for (c in word) {
if (isVowel(c) == lastTypeVowel) {
if (++currentTypeCount == 3) {
count++
currentTypeCount = 1
}
} else {
lastTypeVowel = !lastTypeVowel
currentTypeCount = 1
}
}
println(count)
}
Let's analyze the modifications of your word:
eebeeeeeeeeeeeeeee
eebeebeeeeeeeeeeeee
eebeebeebeeeeeeeeeee
eebeebeebeebeeeeeeeee
eebeebeebeebeebeeeeeee
eebeebeebeebeebeebeeeee
eebeebeebeebeebeebeebeee
eebeebeebeebeebeebeebeebe
Your last 2 modification take place on the letters with index, which is bigger than your word's original length. That happens because for loop iterations number is dependent on your word's original length.
I recommend you to use while loop, as its condition is always recalculated and word.size will be updated there
var i = 0
while (i + 2 < word.size) {
// the same logic
i++
}
val listNumbers = generateSequence(1) { it + 1 }
val listNumber1to100 = listNumbers.takeWhile { it < 100 }
val secNum:Unit = listNumber1to100.forEach {it}
println(listNumber1to100.asSequence().filter { it%(listNumber1to100.forEach { it })!=0 }.toList())
I have an error in reminder sign!
This is Error: None of the following functions can be called with the arguments supplied
In your first approach, the error appears in this line:
it%(listNumber1to100.forEach { it })
A Byte, Double, Float, Int, Long or Short is prefered right after the % operator, however, forEach is a function which the return type is Unit.
In your second approach, you have the correct expression in isPrime(Int). Here are some suggestions for you:
listNumber1to100 is excluding 100 in your code, if you want to include 100 in listNumber1to100, the lambda you pass to takeWhile should be changed like this:
val listNumber1to100 = listNumbers.takeWhile { it <= 100 }
listNumber1to100.asSequence() is redundant here since listNumber1too100 is itself a TakeWhileSequence which implements Sequence.
isPrime(Int) is a bit confusing since it is check for isComposite and it does not work for every input it takes(it works for 1 to 99 only). I will rewrite it in this way:
fun isPrime(num: Int): Boolean = if (num <= 1) false else !(2..num/2).any { num % it == 0 }
Since prime number must be positive and 1 is a special case(neither a prime nor composite number), it just return false if the input is smaller or equal to 1. If not, it checks if the input is divisible by a range of number from 2 to (input/2). The range ends before (input/2) is because if it is true for num % (num/2) == 0, it is also true for num % 2 == 0, vise versa. Finally, I add a ! operator before that because a prime number should not be divisible by any of those numbers.
Finally, you can filter a list by isPrime(Int) like this:
println(listNumber1to100.filter(::isPrime).toList())
PS. It is just for reference and there must be a better implementation than this.
To answer your question about it, it represents the only lambda parameter inside a lambda expression. It is always used for function literal which has only one parameter.
The error is because the expression: listNumber1to100.forEach { it } - is not a number, it is a Unit (ref).
The compiler try to match the modulo operator to the given function signatures, e.g.: mod(Byte) / mod(Int) / mod(Long) - etc.
val listNumbers = generateSequence(1) { it + 1 }
val listNumber1to100 = listNumbers.takeWhile { it < 100 }
fun isPrime(num: Int): Boolean = listNumber1to100.asSequence().any { num%it==0 && it!=num && it!=1 }
println(listNumber1to100.asSequence().filter { !isPrime(it)}.toList())
I found this solution and worked
But why can I have a non-number here in the right side of reminder