protected int xMethod (Integer a, Integer b) {
if (a<b)
return 1
else if (a>b)
return 2
else
return 3
}
I wonder if there is some way of rewriting above method differently in groovy? as now is very Java style.
It seems that the function just needs to return 3 different values depending on whether a is less than, equal to, or greater than b. There is already an operator in Groovy that does this:
a <=> b
The return values are -1, 0 and 1. Perhaps the best thing to do is refactor the code to use this operator instead of xMethod, if that is possible.
Of course, if the precise values 1, 2 and 3 are important and not just 3 distinct values then you can't do this.
Just to expand on Mark's answer:
protected int xMethod (Integer a, Integer b) {
switch ( a <=> b ) {
case -1: 1; break
case 1: 2; break
case 0: 3; break
}
}
However, you have to question whether this method has any value. If the caller can be changed to accept -1, 0, 1 then the method has no reason to exist.
How about:
return (a <=> b) + 2
If you remove the two occurrences of Integer from the signature, you can call the method with any parameters for which < is defined.
E.g.
assert x.xMethod(1, 2)==1
assert x.xMethod("2", "1")==2
assert x.xMethod(2.0, 2.0)==3
Related
Let's say I have a following list of library's versions:
List myList = ["4.11", "4.12", "4.13", "5.1"]
I need to check if the first element of the list is equal to or greater than "4.11".
I do it this way:
#compateTo() returns 0 if the caller string equals to the argument string
#compateTo() returns > 0 if the caller string is greater than the argument string
if (myList[0].compareTo("4.11") >= 0) {
println("equal or greater than 4.11")
} else {
println("less than 4.11")
}
However, let's consider this case:
List myList = ["4.9"]
Comparing two strings character by character it gets to 9 compared to 1 and since 9 is greater than 1 it returns equal or greater than 4.11, which is incorrect.
What would be the best way to fix it? I considered this:
def strToDecimal = Double.parseDouble(myList[0])
to get a decimal number and compare two decimal numbers 4.9 and 4.11 but the problem is the same.
I cannot use anything that would require an import statement.
If you're using Java >= 9, I'd go with the Version class:
// List myList = ["4.11", "4.12", "4.13", "5.1"]
List myList = ["4.9"]
if (java.lang.module.ModuleDescriptor.Version.parse(myList[0]).compareTo(java.lang.module.ModuleDescriptor.Version.parse("4.11")) >= 0) {
println("equal or greater than 4.11")
} else {
println("less than 4.11")
}
If your Java version is <= 9, then you may checkout this question. There are some ideas on how to solve your problem.
def pos_neg(a, b, negative):
if negative:
return (a < 0 and b < 0)
else:
return ((a < 0 == b > 0) or (a > 0 == b < 0))
so basically I tried some basic problems.
I just started out and went to https://codingbat.com/prob/p162058 to try it and don't understand why if I were to replace the '==' with 'and' it would work? Thanks.
Oh, I got it now, thanks guys. :D
(this python community is fire!!!)
Since you're learning, you might be interested in seeing that this is an equivalent function.
basically it does a bit wise & and returns true if the result is < 0
else a bit wise exclusive or and returns true if the result is < 0
def pos_neg(a , b, negative):
if negative:
return (a & b) < 0 # both sign bits set (i.e. neg), return true
else:
return (a ^ b) < 0 # different signs, return true
In both cases, it is the sign bit of the result that is of concern. If the bit is set then the value will be negative (hence the comparison to < 0)
and is a logical operator and returns true only when both the expressions we are using it on are true.
== is used for comparisons and returns true when both expressions are equal; they don't need to be true.
To give you an example False == False will return True but False and False will return False.
This "==" means equals to, belonging to Python Comparison Operators, used to compare two values.
and language keyword "and" it is for Python Logical Operators used to combine conditional statements.
You should check out this, it may solve others doubts you have.
W3Schools
All your relational operator usages (i.e. a < 0, b < 0, etc.) result to a boolean value and thus these are known as boolean expressions.
When you put a < 0, think of it like a test of: "is a less than 0, true or false?".
So, if both a and b are negative (i.e. less than zero), their expressions will return true.
So on the line return a < 0 and b < 0, replacing and with == is like saying return true == true. Without the change it'd be return true and true.
Note: This does not mean == is the same as and. == checks for equality of the left-hand side to the right-hand side (e.g. 1 == 1) and gives a true or false value depending on the result of equality. and checks for if the left-hand side results to a true statement and if the right-hand side results to a true statement in order to result to a true expression.
I was wondering if there is a simpler or shorter way to write repetitive conditions like x == 1 && y == 1 && z == 1?
When it is (exactly) repeated code, you should consider to extract the statement into a method and give a meaningfull name, which you know from the context where it is used. This makes the requirement (reading the code) easier to understand, at the point where it is used. And it makes it also easier to spot the it is always the same condition.
if (conditionName(x, y, z)) {
}
fun boolean conditionName(int x, int y, int z) {
return x == 1 && y == 1 && z == 1;
}
I cannot think of a shorter statement for the condition, but a method extraction will improve your code readability, which should be your overall goal.
You could consider using predicates using all. For example:
listOf(x, y, z).all {it == 1}
This will return true when x==1, y==1, and z==1.
If the goal is to shorten what you want, there's not much legroom as your boolean expression is already very concise. Some of the other answers have illustrated how to make what you want more readable, however.
You can make a convenience function for this kind of repeated code (or if you just need it to be more readable, or safer to edit):
fun <T> T.allEqual(vararg items: T) = items.all { it == this }
// or you could make the receiver the first parameter instead, this is just
// more explicit about which item is the value being compared against
1.allEqual(x, y, z)
But no, there isn't any other shorthand built into the language as far as I'm aware - conditions like x == 1 chained with boolean operators are about as simple as it can get! If you want to check multiple things without repeating yourself, any and all make that easy, while being flexible for all kinds of situations, and allowing the user to put together the functionality they need with those more general functions.
If you specifically want a version of all that does a simple comparison to a single value, and doesn't require creating an iterable like listOf, you have to write your own with those tools (which is basically what I've done). It's up to you if you think it's worth it!
If it makes sense you could hold those variables in a class
data class XYZ(
val x: Int,
val y: Int,
val z: Int)
And compare your instance with XYZ(1, 1, 1);
Or if it's just those three variables, you could write
if (Triple(x, y, z) == Triple(1, 1, 1))
val x = 1
val y = 1
var z = 1
println("$x$y$z" == "111") // prints 'true'
z = 2
println("$x$y$z" == "111") // prints 'false'
This question already has answers here:
Why does my recursive function return None?
(4 answers)
Closed 3 years ago.
I am trying to implement Euclid's algorithm for computing the greatest common divisor using recursion. Below is the code for the same.
def euclid(a,b):
if a>b:
r=a%b
if (r == 0):
return b
else:
a=b
b=r
euclid(a,b)
print(euclid(20,4)) # Returns 4
print(euclid(20,8)) # Returns None
For the first data set, I get the correct result. But for euclid(20,8) I get a return of None.
While checking in the debugger, I did see the return value of b become 4 but then for some reason, my code jumps to euclid(a,b) and returns None.
The major takeaway here would be to understand why the code does not return 4 but jumps to the euclid(a,b) and return None.
Please refrain from giving alternative code solutions but you are very much encouraged to point out the reason for the current behaviour of the code.
The reason for that code to return None at some point is that in your control flow you eventually end up in a situation where there is no return statement, e.g. for a <= b in your first if or when r != 0 in your second if. The default behavior of Python in that case is to return None, as you seems to have discovered the hard way.
def euclid(a,b):
if a>b:
r=a%b
if (r == 0):
return b
else: # <--- no `return` in this branch!
a=b
b=r
euclid(a,b)
# else: # <--- no `return` in this branch!
# ...
Here is an updated version of your code, that addresses that and also a number of other issues:
the name of the function should be meaningful: Euclid is kind of popular and there is a bunch of things named after him, better specify that you actually want to compute the greatest common divisor (GCD)
the first if is not really needed, as it is taken care of by the subsequent code: computing r and the recursive call will take care of swapping a and b if a < b, and if a == b then r == 0, so you b is being returned directly
a = b and b = r are useless, do not use them, just have your recursive call use b and r directly
the second if can be written more clearly in one line
def gcd_euclid_recursive(a, b):
r = a % b
return gcd_euclid_recursive(b, r) if r else b
gcd_euclid_recursive(120, 72)
# 24
gcd_euclid_recursive(64, 120)
# 8
You don't actually return anything in the else path so it just assumes you know best and returns None for you.
The only reason you get 4 for print(euclid(20,4)) is because 4 is a factor of 20 so never uses the else path. Instead it returns b immediately. For anything else, the thing returned from the first recursive call to euclid() will always be None (even if a lower call to that function returns something, you throw it away when returning from the first call).
You need return euclid(a,b) rather than just euclid(a,b).
As an aside (this isn't necessary to answer your specific question but it goes a long way toward improving the implementation of the code), I'm not a big fan of the if something then return else … construct since the else is totally superfluous (if it didn't return, the else bit is automatic).
Additionally, you don't need to assign variables when you can just change what gets passed to the next recursive level.
Taking both those into account (and simplifying quite a bit), you can do something like:
def euclid(a, b):
if b == 0: return a
return euclid(b, a % b)
Your code has an indentation error and one path is missing in your code(r!=0). It should be
def euclid(a,b):
if a>=b:
r=a%b
if (r == 0):
return b
return euclid(b, r)
else:
return euclid(b, a)
Lets say that there are two variable, the value of the variable is taken from the users. That is:
a=0
b=1
c=a-b
For some cases i need the variable c to be always positive, is there is any method in Groovy to do this?
Couple of options, depending on want behaviour you actually want when c is negative:
c = Math.abs(c) // -1 will become 1
c = Math.max(0,c) // -1 will become 0
// or it's an error condition
if( c < 0 ){
tellUserToStopMessingAroundAndEnterTheCorrectValues()
return
}