Exceptions with if else statement in Scala - scala

if ( option != "AB" || option != "BC"|| option != "CD") {
try {
var option = dbutils.widgets.get("option")
}
catch {
case e: Exception => println("The option shoud be following AB, BC or CD " + option)
}
}
I am trying to use exception in scala
However, the widget value is not throwing an exception when I use the value such as
"XY" or any other value than AB, BC or CD.
Please can someone let me know what I am doing wrong here. Thank you

If AB,BC & CD are the valid values, then your predicate should look like this:
if(option == "AB" || option == "BC" || option == "CD")
Also, you can use the require function to enforce the predicate and throw an exception if the input doesn't match:
def getWidget(option: String) = try {
require(option == "AB" || option == "BC"|| option == "CD", s"The option shoud be following AB, BC or CD instead got $option")
dbutils.widgets.get("option")
} catch { case e: Exception => println(e) }

Related

Type checking on user input Scala Spark

I'm trying to do a type checking on an input that the user insert, but I don't know ho to do.
My code is:
for(iteration<- 0 to 19) {
print(movieRecommended(iteration))
var personalRate = scala.io.StdIn.readDouble()
if(Try(personalRate.toInt).isSuccess){
while((personalRate > 5 || personalRate < 1) || personalRate % 0.5 != 0) {
println("Error: respect the parameters")
print(movieRecommended(iteration))
personalRate = scala.io.StdIn.readDouble()
}
}
else println("Error")
ratingArr(iteration) = personalRate
}
But when I try to give a string input like "a" I receive this error:
Exception in thread "main" java.lang.NumberFormatException: For input string: "a"
at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)
at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.base/java.lang.Double.parseDouble(Double.java:549)
at scala.collection.immutable.StringLike.toDouble(StringLike.scala:321)
at scala.collection.immutable.StringLike.toDouble$(StringLike.scala:321)
at scala.collection.immutable.StringOps.toDouble(StringOps.scala:33)
at scala.io.StdIn.readDouble(StdIn.scala:167)
at scala.io.StdIn.readDouble$(StdIn.scala:162)
at scala.io.StdIn$.readDouble(StdIn.scala:241)
at CollaborativeFilteringUserBasedALS$.$anonfun$askUserInput$1(CollaborativeFilteringUserBasedALS.scala:192)
at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:158)
at CollaborativeFilteringUserBasedALS$.askUserInput(CollaborativeFilteringUserBasedALS.scala:189)
at CollaborativeFilteringUserBasedALS$.topRated(CollaborativeFilteringUserBasedALS.scala:133)
at CollaborativeFilteringUserBasedALS$.main(CollaborativeFilteringUserBasedALS.scala:284)
at CollaborativeFilteringUserBasedALS.main(CollaborativeFilteringUserBasedALS.scala)
Someone can explain me what I'm doing wrong?
You can read the input as a string using scala.io.StdIn.readLine() then try to parse it to Int and use pattern matching to handle case for valid int and for error.
Something like this :
for (iteration <- 0 to 19) {
var personalRate = scala.io.StdIn.readLine()
Try(personalRate.toInt).toOption match {
case Some(rate) => {
println(rate)
// your logic for int
}
case _ => println("Error")
//...
}
}

Why is my dataweave map code not working?

I'm trying to convert some code from mule 3 to mule 4 so I'm using dataweave 2. I keep getting errors from this code
keySets: if(payload.autoQuote !=null) payload.autoQuote map (autoQuote) -> {
(if(payload.autoQuote.personalAuto.vehicles != null) autoQuote.personalAuto.vehicles map ((vehicles,indexOfvehicle) ->{
keySet: {
key: if(vehicles.usage != null) vehicles.usage else 'DNF' ,
keySequence: "TAUTO_USE_TYPE" ++ '_' ++ indexOfvehicle
}
} else {}))
} else {}
On the first line I'm getting
mismatched input '->' expecting 'else'
on the second line I'm getting
- missing EOF at 'payload'
and
- no viable alternative at input '('
on the first two '('
I believe keySets is a list and not a object, you should be using [] and not {} in your else statements. I edited some of the braces, and it is compiling fine for me, though not sure if it will work as expected for you.
keySets: if(payload.autoQuote !=null) (payload.autoQuote map (autoQuote) -> {
(if(payload.autoQuote.personalAuto.vehicles != null)
autoQuote.personalAuto.vehicles map ((vehicles,indexOfvehicle) -> {
keySet: {
key: if(vehicles.usage != null) vehicles.usage else 'DNF',
keySequence: "TAUTO_USE_TYPE" ++ '_' ++ indexOfvehicle
}
}) else [])
}) else []
Give it a try and let me know if it worked.
This doesn't give me errors, though I'm not sure if it makes sense:
%dw 2.0
output application/json
---
{
keySets: if(payload.autoQuote !=null) (payload.autoQuote) map(autoQuote, i) -> {
( if(payload.autoQuote.personalAuto.vehicles != null) (autoQuote.personalAuto.vehicles) map (vehicles,indexOfvehicle) ->{
keySet: {
key: if(vehicles.usage != null) vehicles.usage else 'DNF' ,
keySequence: "TAUTO_USE_TYPE" ++ '_' ++ indexOfvehicle
}
} else {})
} else {}
}
You should give an example of the input and the expected output.
Also I'm not sure why you don't use the autoQuoteparameter of the map inside of the map instead of payload.autoQuote...
Turns out I had the parentheses wrong. The first else was in the parentheeses after the map. It should look like this. Don't know if it works but it at least compiles.
keySets: if(payload.autoQuote !=null) payload.autoQuote map (autoQuote) -> {
(if(payload.autoQuote.personalAuto.vehicles != null) autoQuote.personalAuto.vehicles map ((vehicles,indexOfvehicle) ->{
keySet: {
key: if(vehicles.usage != null) vehicles.usage else 'DNF' ,
keySequence: "TAUTO_USE_TYPE" ++ '_' ++ indexOfvehicle
}
}) else {})
} else {}

Cannot convert value of type 'String' to expected argument type 'Bool'

I am trying to write a function that will return true if the String str starts with a vowel. the following code will compile fine
func beginsWithVowel(str: String) -> Bool {
if(str.characters.count == 0){
return false
} else if(str.characters[str.startIndex] == "a"){
return true
}
return false
}
beginsWithVowel(str: "apple")
the problem is when I compare the first character to more than one character, for example
else if(str.characters[str.startIndex] == "a" || "e" || "i")
then I get the error 'Cannot convert the value of type 'String' to expected argument type 'Bool''
I've been fiddling with the code but no luck so far, any help would be appreciated. Thank you.
Swift cannot infer the logic you are trying to make. The logic to Swift becomes something like this:
if(str.characters[str.startIndex] == "a" || "e" || "i")
is equivalent to if(<Boolean expression> || "e" || "i")
is equivalent to if(<Boolean expression> || <String expression> || String expression)
An alternative solution can be:
if(["a", "b", "c"].contains(str.characters[str.startIndex])){
You should write it like this:
else if(str.characters[str.startIndex] == "a" || str.characters[str.startIndex] == "e" || str.characters[str.startIndex] == "i")
You get the error, because the compiler tries to convert both "e" and "i" to type Bool.
Instead of using if else switch will be more efficient:
func beginsWithVowel(str: String) -> Bool {
guard str.characters.count > 0 else {
return false
}
switch str.characters[str.startIndex]{
case "a","e","i","o","u":
return true
default:
return false
}
}
When you perform "a" || "e" || "i" you are comparing between the strings. Use this code:
if(str.characters[str.startIndex] == "a"
|| str.characters[str.startIndex] == "e"
|| str.characters[str.startIndex] == "i") {
// Your Code...
}
The boolean OR operator || expects boolean expressions.
So you would have to write EXPR == "a" || EXPR == "e" || EXPR == "i" where EXPR is the expression to get the first character.
However there is an easier solution (code is Swift 4)
func beginsWithVowel(str: String) -> Bool {
return "aeiou".contains(String(str.prefix(1)))
}
It considers also the empty string case.

Are "&&" and "," the same in Swift?

As the title says, I just came across a case where if && (AND) and , give the same result in Swift. I tested the code below:
let a = 5
let b = 6
if a<6, b>0 {
print("should be true")
}
if a<6, b<0 {
print("should be false")
}
if a>6, b>0 {
print("should be false")
}
if a>6, b<0 {
print("should be false")
}
It only logs:
should be true
So, the behavior of , is just like &&, am I correct?
They can be used in similar situations but that does not mean they are exactly the same.
Consider:
if (a && b) || c
you cannot write
if (a, b) || c
even a && b || c is different from a, b || c.
if a, b is something like
if a {
if b {
...
}
}
Both expressions have to be evaluated to true but they are still two separate expressions. We shouldn't imagine && there.
Why do we need the , operator?
The operator is needed to combine optional binding with boolean conditions, e.g.
if let a = a, a.isValid() {
becuase && wouldn't help us in such situations.
They're different in that a comma will take the lowest precedence possible. i.e everything else will be executed before the commas are checked.
// (true || false) && false
if true || false, false {
print("I will never be executed")
}
// true || (false && false)
if true || false && false {
print("I am always executed")
}

How does Swift handle if statements?

If I have the statement:
if object != nil && object.property == 2 {
//do something
}
does the if statement break as soon as it finds out object = nil?
Yes
When you concatenate a list of conditions C[0]...C[n] with the AND && operator, the runtime evaluates in order each condition and if a C[i] condition is found false, then the evaluation of the whole expression does end and it is judged false.
let c0 = true
let c1 = false
let c2 = true
if c0 && c1 && c2 {
print("Hello world")
}
In this case only c0 and c1 will be evaluated and the whole expression will be interpreted as false.
You can test it yourself in Playground.
c0 || c1 || c2
Symmetrically if you define an expression as the OR || concatenation of several clauses, then the whole expression is interpreted as true (and the evaluation of the clauses does stop) as soon as the first true condition gets found.
Yes is the answer.
Simple to try - see below - however note that as written your test won't work - a non-optional cannot be nil, and so you will have to unwrap it to test .property.
struct MyObj {
var property: Int
}
var object: MyObj? = nil
if object != nil && object!.property == 2 {
print("Not nil")
} else {
print("Nil") // Prints - would have crashed if test fully evaluated
}
object = MyObj(property: 2)
if object != nil && object!.property == 2 {
print("Not nil") // Prints
} else {
print("Nil")
}