I want to implement a Repeat Until in Scala.
The commented code will throw a StackOverflowException.
But the code now run in main method works.
But I don't know why and what's the difference between these two snippets.
object REPEAT{
class REPEAT(command: => Unit){
def UNTIL(cond: => Boolean):Unit = {
command
if(!cond) UNTIL(cond)
}
}
def REPEAT(command: => Unit): REPEAT = {
new REPEAT(command)
}
def main(args: Array[String]) {
/* this code work well */
var i = 0
REPEAT { i+= 1; println(i)} UNTIL (i == 100)
/*
// something wrong in this code.
var i = 0
new REPEAT {
i += 1; println(i)
} UNTIL (i == 100)
*/
}
}
ps: I found the wrong code just change the var i to 1 but don't change it anymore.
The wrong code's output:
1
Exception in thread "main" java.lang.StackOverflowError at
REPEAT$$anon$1$$anonfun$$lessinit$greater$1.apply$mcV$sp(REPEAT.scala:15)
at REPEAT$REPEAT.UNTIL(REPEAT.scala:4)
That's the problem:
new REPEAT {
i += 1; println(i)
} UNTIL (i == 100)
is equivalent to:
new REPEAT() {
i += 1; println(i)
} UNTIL (i == 100)
So you're actually creating new instance of REPEAT class with command = (), and i += 1; println(i) in constructor - so i++ repeated only once and () repeated infinitely.
The right way to call it:
new REPEAT({
i += 1; println(i)
}) UNTIL (i == 100)
The reason why is you don't have to specify single parameter with Unit type explicitly in scala:
scala> class Aaaa(a: Unit)
defined class Aaaa
scala> new Aaaa //parenthesis is not required for 'new'
res10: Aaaa = Aaaa#17de44d4
scala> def aaaa(a: Unit) = 5
aaaa: (a: Unit)Int
scala> aaaa()
res13: Int = 5
Related
In this foobar coding question, you're supposed to return the minimum number of steps to get from the given String to the number 1. For example, with the parameter "15", the method would return 4. With the parameter 4, the method would return 2.
I've found the solution in python and was trying to convert to Java, but the Java code does not pass half of the secret tests(I do not know what[enter image description here] the test cases are) while the python code passes the tests. This is the python code:`
def solution(n):
n=int(n)
res = 0
while(n!=1):
if(n%2==0):
n=n/2
elif((n==3) or ((n+1)&n) > ((n-1)&(n-2))):
n-=1
else:
n+=1
res+=1
return res
` code passes are the cases. My question was trying to figure out what I'm doing wrong in my Java code. This is the Java code:
public static int solution(String x) {
int counter = 0;
int number = Integer.parseInt(x);
while(number != 1) {
if(number%2 == 0) {
number = number/2;
}
//else if(number == 3 || number%4 == 1) {
else if((number == 3) || ((number +1)&number) > ((number-1)&(number-2))) {
number-=1;
}
else {
number+=1;
}
counter+=1;
}
return counter;
}
`.
This question already has answers here:
Ternary Operator
(4 answers)
Closed 2 years ago.
(comparison > 0 ? n : m).subtract(comparison > 0 ? m : n);
I'm trying to figure out what this inline conditional statement means and how to convert it into a regular if statement. The .subtract is just a method that will subtract the second () from the first().
I think that the first (comparison > 0 ? n : m) is the same as if(comparison > 0) { m = n; }
not sure how that works with the subtract function. The code runs correctly but I'm trying to fix the warning to not use inline conditionals.
Thank you!
The ternary ?: operator is what is used here.
a ? b : c means
if (a) {
b;
} else {
c;
}
So (comparison > 0 ? n : m).subtract(comparison > 0 ? m : n); means.
if (comparsion > 0) {
n.subtract(m);
} else {
m.subtract(n);
}
In this case n and m must be objects that have a subtract method as follows which prints:
result = -3 when comparison = -5
result = 3 when comparison = 5
public class TernaryDemo {
public static void main(String[] args) {
for (int comparison : new int[] { -5, 5 }) {
MyClass n = new MyClass(10);
MyClass m = new MyClass(7);
MyClass result = (comparison > 0 ? n : m)
.subtract(comparison > 0 ? m : n);
System.out.println("result = " + result
+ " when comparison = " + comparison);
}
}
}
class MyClass {
int v;
public MyClass(int v) {
this.v = v;
}
public MyClass subtract(MyClass cls) {
return new MyClass(this.v - cls.v);
}
public String toString() {
return v + "";
}
}
This is stuff you can test yourself.
However, it translates to:
Subtractable sub, sub2; // This is how I am going to call the class that has the subtract method
if(comparison > 0)
sub = n;
else
sub = m;
// You could put these in the same if statement, but this is closer to what actually happens.
if(comparison > 0)
sub2 = m;
else
sub2 = n;
sub.subtract(sub2);
I have found a solution to my problem here Create new column with function in Spark Dataframe
But i am having difficulty in converting the below code to Java since it's in Scala
import org.apache.spark.sql.functions._
val myDF = sqlContext.parquetFile("hdfs:/to/my/file.parquet")
val coder: (Int => String) = (arg: Int) => {if (arg < 100) "little" else "big"}
val sqlfunc = udf(coder)
myDF.withColumn("Code", sqlfunc(col("Amt")))
Can someone provide me the Java equivalent code for this?. I am stuck in converting below 2 lines
val coder: (Int => String) = (arg: Int) => {if (arg < 100) "little" else "big"}
val sqlfunc = udf(coder)
Thanks,
Create your User Defined Function:
public class CodeUdf implements UDF1<Integer, String>{
#Override
public String call(Integer integer) throws Exception {
if(integer < 100)
return "little";
else
return"big";
}
}
Tell Spark about it
sqlContext.udf().register("Code", new CodeUdf(), DataTypes.IntegerType);
Use it in a select.
df.selectExpr("value", "Code(value)").show();
import org.apache.spark.sql.functions._
val myDF = sqlContext.parquetFile("hdfs:/to/my/file.parquet")
//val coder: (Int => String) = (arg: Int) => {if (arg < 100) "little" else "big"}
//val sqlfunc = udf(coder)
myDF.selectExpr("Code", "case when Amt < 100 'little' else 'big' end ")
I have a problem... it's basically that my code is ugly and I don't like it. I was wondering if there was a way to simplify it (I use java 8)
I have these "code blocks" that follow this pattern, I have about 5 or 6 of them within a method so this method looks very repetitive and ugly.
The loops are all the same, just the code varies inside.
Is there any way to simplify this?
CODE BLOCK EXAMPLE
String id = null;
for (int i=0; i< NUM_CHECKS; i++) {
// BEGIN VARIABLE CODE
id = getPrice();
if (id != null) break;
// END VARIABLE CODE
// sleep between checks
if (i < NUM_CHECKS -1) Thread.sleep(DELAY);
}
EXAMPLE
String id = null;
for (int i=0; i< NUM_CHECKS; i++) {
// BEGIN VARIABLE CODE
id = getPrice();
if (id != null) break;
// END VARIABLE CODE
// sleep between checks
if (i < NUM_CHECKS -1) Thread.sleep(DELAY);
}
for (int i=0; i< NUM_CHECKS; i++) {
// BEGIN VARIABLE CODE
x=x*2;
if (x>25) break;
// END VARIABLE CODE
// sleep between checks
if (i < NUM_CHECKS -1) Thread.sleep(DELAY);
} etc... a couple more blocks
How about coding an abstraction to contain all the boilerplate?
class MyLoop
{
private int numChecks;
private int delay;
public MyLoop(int numChecks, int delay) {...}
public void loopAndSleep(MyTask task)
throws InterruptedException
{
// Update: It is important to set properly the order of the looping conditions,
// to stop invoking hasEnded() as soon as i<numChecks==false (Thaks to Simon Eismann).
for (int i=0; i<numChecks && !task.hasEnded(); i++)
{
if (i < numChecks -1)
{
Thread.sleep(DELAY);
}
}
}
}
interface MyTask
{
public boolean hasEnded();
}
So, you can replace each one of your 5-6 places in your program by:
new MyLoop(NUM_CHECKS, DELAY).loopAndSleep(new MyTask(){...});
By properly extending MyTask you can give them specific status variables.
If you want to try some operation until the return value is available, you may do the following (Java-8 way):
public static <T> Optional<T> retryWithDelay(int numberOfChecks, int delay,
Supplier<Optional<T>> supplier) throws InterruptedException {
for(int i=0; i<numberOfChecks; i++) {
if(i > 0)
Thread.sleep(DELAY);
Optional<T> result = supplier.get();
if(result.isPresent()) return result;
}
}
And use it like this:
String id = retryWithDelay(NUM_CHECKS, DELAY, () -> Optional.ofNullable(getPrice()))
.orElse(null);
Or if you don't like optionals for some reason, you can stick with null:
public static <T> T retryWithDelay(int numberOfChecks, int delay,
Supplier<T> supplier) throws InterruptedException {
for (int i = 0; i < numberOfChecks; i++) {
if (i > 0)
Thread.sleep(delay);
T result = supplier.get();
if (result != null)
return result;
}
return null;
}
And use it like this:
String id = retryWithDelay(NUM_CHECKS, DELAY, () -> getPrice());
Or using method reference:
String id = retryWithDelay(NUM_CHECKS, DELAY, this::getPrice);
Note that the second example with x = 2*x is more difficult as it has some mutable state. It can be solved in dirty way like this:
AtomicInteger x = new AtomicInteger(1);
Integer result = retryWithDelay(NUM_CHECKS, DELAY, () -> {
int val = x.get()*2;
x.set(val);
return val > 25 ? val : null;
});
However I hope this version was just for illustration, not the real code.
There's also somewhat more sophisticated approach which probably abuses the API, but allows more flexibility. You can create an IntStream of increasing numbers, but they are available with given delay:
public static IntStream delayedStream(int numberOfChecks, int delay) {
return IntStream.range(0, numberOfChecks)
.peek(x -> {
if(x > 0) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
// ignore
}
}
});
}
So the first problem can be solved now as:
String id = delayedStream(NUM_CHECKS, DELAY)
.mapToObj(x -> getPrice())
.filter(Objects::nonNull)
.findFirst().orElse(null);
And the second can be solved like this (assuming initial x value is 1):
int x = delayedStream(NUM_CHECKS, DELAY)
.map(idx -> 1 << (idx+1))
.filter(val -> val > 25)
.findFirst().orElse(-1);
The structure you provide is called a "polling loop" and you are correct, it is poor programming style, as are all the replies that contain the same polling loop.
It would be far better to use events.
Look in the "getPrice()" function, get to wherever that return value is being changed, and create an event when the change happens. Then in your code write a handler and in the handler do all the stuff that currently happens after your polling loop succeeds.
You can use recursion to make to loop reusable, but this would only make sense if you use the loop a lot.
public void loopWithDelay(int numberOfChecks, int delay, Runnable r) {
if (numberOfChecks != 0) {
r.run();
loopWithDelay(numberOfChecks - 1, delay, r);
Thread.sleep(DELAY);
}
}
The actual call would look something like this:
loopWithDelay(5, 1000, new Runnable() {
#Override
public void run() {
//Variable code goes here
}
});
On a general note, are you sure you want to wait DELAY seconds after an action or have the action occur every DELAY seconds?
EDIT:
I am dumb, no need for recursion, this works aswell:
public void loopWithDelay(int numberOfChecks, int delay, Runnable r) {
for (int i = 0; i < numberOfChecks; i++) {
r.run();
if (i != numberOfChecks -1)
Thread.sleep(DELAY);
}
}
Below I have a rough implementation of testing a list lambda functions on an integer in Python. I know Java currently doesn't support closures or lambdas (yet), but I'm curious, is this remotely possible in Java?
pos = [lambda x : x > 0, "pos"]
even = [lambda x : x % 2 == 0, "even"]
small = [lambda x : x < 100, "small"]
def pass_test(x, tests):
if (len(tests) == 0): return []
else:
if (tests[0][0](x)): return [tests[0][1]] + pass_test(x, tests[1:])
else: return pass_test(x, tests[1:])
Yes, it is possible, along the lines of:
interface Predicate<A> {
boolean eval(A argument);
}
Predicate<Integer> gt0 = new Predicate<Integer>() {
boolean eval(Integer arg) {
return arg > 0;
}
};
You see, this is a bit verbose, but it does the job.
In your case, python function could be mapped to Java like this:
public interface Function {
String do(int x);
}
// ...
Function pos = new Function(){
public String do(int x) {
return (x > 0) ? "pos" : "";
}
}
Function even = new Function(){
public String do(int x) {
return (x % 2 == 0) ? "even" : "";
}
}
Function small = new Function(){
public String do(int x) {
return (x < 100) ? "small" : "";
}
}
// ...
As you see, you'd need a lot more code to do the same simple thing in Java.