Coursera scala assignment objects : week 3 descendingByRetweet - scala

I am trying to figure out whats wrong in my solution for the coursera Scala course , 3rd assignment. I have figured out everything else , other than the method to convert a TweetSet into a descending tweetList.
Here are the main methods : mostRetweeted for Non-Empty Set.
def mostRetweeted: Tweet = {
val mostRetweetedLeft = left.mostRetweeted
val mostRetweetedRight = right.mostRetweeted
if(mostRetweetedLeft != null && mostRetweetedRight!=null)
if(elem.retweets > mostRetweetedRight.retweets && elem.retweets > mostRetweetedLeft.retweets)
return elem
else if(elem.retweets > mostRetweetedRight.retweets && elem.retweets < mostRetweetedLeft.retweets)
return mostRetweetedLeft
else
return mostRetweetedRight
else if(mostRetweetedLeft == null && mostRetweetedRight!=null)
if(elem.retweets > mostRetweetedRight.retweets)
return elem
else
return mostRetweetedRight
else if(mostRetweetedLeft != null && mostRetweetedRight==null)
if(elem.retweets > mostRetweetedLeft.retweets)
return elem
else
return mostRetweetedLeft
else
return elem
}
mostRetweeted for empty Set
def mostRetweeted: Tweet = null
And finally this method , uses an accumulator to form the list by using the above methods to calculate the most retweeted tweet.
def descendingByRetweet: TweetList = {
def descendingByRetweet(tweetSet: TweetSet, tweetList : TweetList):TweetList = {
val mostTweeted:Tweet = tweetSet.mostRetweeted
// empty set returns null for mostRetweeted method
if(mostTweeted == null)
return tweetList
else {
descendingByRetweet(tweetSet.remove(mostTweeted),tweetList.add(mostTweeted))
}
}
descendingByRetweet(this,Nil)
}
As you might have noticed I added an add method to TweetList
For Nil
def add(tweet: Tweet): TweetList = new Cons(tweet,Nil)
For Cons
def add(tweet: Tweet): TweetList = new Cons(head,tail add tweet)
I have also tried some online solutions , but those did not work either.
https://coderwall.com/p/_akojq/scala-week-3
Just like my solution , this gives an "Almost" descending list , but the list is not perfectly descending. Anyways I have spent the entire day and have passed the assignment, so am moving on to the next week.

Your code for descendingByRetweet looks correct thought it could be written shorter. I think your problem could be in the mostRetweeted method. In this part of the code:
if(elem.retweets > mostRetweetedRight.retweets && elem.retweets > mostRetweetedLeft.retweets)
return elem
else if(elem.retweets > mostRetweetedRight.retweets && elem.retweets < mostRetweetedLeft.retweets)
return mostRetweetedLeft
else
return mostRetweetedRight
Consider the case where, for example, elem.retweets = 5, mostRetweetedRight.retweets = 0 and mostRetweetedLeft.retweets = 5. The return value would be mostRetweetedRight which obviously is incorrect. You should add >= and <= to one of the if statements depending on your desired outcome.

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")
//...
}
}

JS timeout causes eval exception

For some reason, one of my JS files is triggering an unsafe-eval Content Security Policy violation on my site. I thought this odd because there is no eval() anywhere in the file. The error happens on the following line:
setTimeout(callSpecific(), (lengthMF * (number.length + 2)));
The only thing I can see here is the arithmetic on the RHS that sets the timeout value. So, I tried:
setTimeout(callSpecific(), (parseInt(lengthMF) * (parseInt(number.length) + 2)));
Same thing. The variables themselves are not even strings - they are defined as:
var lengthMF = 150;
var number = ""; // yes, this is a string but number.length is not!
Why is this triggering a CSP violation? I have other setTimeout()s on the page and this seems to be the only problematic one. The weird thing is replacing the arithmetic expression temporarily with a constant (e.g. 50) does not cause the issue to go away.
If it's necessary, callSpecific() looks something like this:
function callSpecific() {
if (number == 0) {
operatorRing();
} else if (number.length == 2 && number.charAt(1) == 0) {
playReorder();
} else if (number.length == 3) {
//
} else if (number.length <7 || number.length > 11) {
//
} else if (number.length == 11 && (number.charAt(4) == 1 || number.charAt(4) == 0)) {
//
}
}

Swift on array.sort - Expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions

I am downgrading Swift code from Xcode 8.3.1 to Xcode 7.3.1.
The Swift compiler of Xcode 7.3.1 raises
Expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions
while pointing on line zeroParameterAndPaths.sort {. The code was ok in Xcode 8.3.1.
What's wrong and how to fix it?
class NewConnectingSegmentZeroParameterAndPath {
let step : Int; // 0 = main, 1 = first outline, 2 = second outline
let parameter : CGFloat;
init(step: Int, parameter: CGFloat) {
self.step = step;
self.parameter = parameter;
}
}
var zeroParameterAndPaths : [NewConnectingSegmentZeroParameterAndPath] = [];
// ... some zeroParameterAndPaths .appendContentsOf calls
zeroParameterAndPaths.sort {
return $0.parameter < $1.parameter
|| ($0.parameter == $1.parameter
&& ($0.step == 1 || ($0.step == 0 && $1.step == 2))
)
};
You have two choices. One is simply to do what the error message suggests, i.e. pulling the complex bool apart into separate pieces:
zeroParameterAndPaths.sort {
let bless = ($0.parameter < $1.parameter)
let beq = ($0.parameter == $1.parameter)
let band = ($0.step == 0 && $1.step == 2)
let bor = ($0.step == 1 || band)
let beqandbor = (beq && bor)
return (bless || beqandbor)
};
The other is to provide an explicit in line giving the param types and result type:
zeroParameterAndPaths.sort {
(a:NewConnectingSegmentZeroParameterAndPath, b:NewConnectingSegmentZeroParameterAndPath) -> Bool in
return a.parameter < b.parameter
|| (a.parameter == b.parameter
&& (a.step == 1 || (a.step == 0 && b.step == 2))
)
};
You could also make your class a little bit more helpful and make it implement the condition. The compiler is much less likely to get confused in a function body than in a closure:
class NewConnectingSegmentZeroParameterAndPath {
let step : Int; // 0 = main, 1 = first outline, 2 = second outline
let parameter : CGFloat;
init(step: Int, parameter: CGFloat) {
self.step = step;
self.parameter = parameter;
}
func orderedBefore(_ other: NewConnectingSegmentZeroParameterAndPath) -> Bool
{
return parameter < other.parameter
|| parameter == other.parameter
&& (step == 1 || step == 0 && other.step == 2)
}
}
var zeroParameterAndPaths : [NewConnectingSegmentZeroParameterAndPath] = [];
// ... some zeroParameterAndPaths .appendContentsOf calls
zeroParameterAndPaths.sort { $0.orderedBefore($1) }
Apart from the issue of the type inference engine not being able to quickly resolve such complex bool expressions, such expressions are really hard to follow. I suggest you break it down into something simpler, like so:
zeroParameterAndPaths.sort {
if $0.parameter != $1.parameter { return $0.parameter < $1.parameter ]
if $0.step == 1 { return true }
if $0.step == 0 && $1.step == 2 { return true }
return false
};
There's my attempt at it. I'm not even sure if it's correct, the original expression is pretty hard to follow.

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")
}

"undefined" in Coffeescript

b
if b?
transforms to
b;
if (typeof b !== "undefined" && b !== null)
If I set b = [], I get if (b != null) {
Where is undefined? It's problem to catch undefined in array (after unique).
When I did
a = [1,1,2,2,3,3,4,444,4,4,4]
a.unique()
I can get something like this:
a = [1,2,3,4,444,undefined]
And I can't catch this, because in case a?[key] - I got only check for != null
What I must do?
I don't see the problem. undefined == null is true in JavaScript and undefined != null is false so if(b != null) covers the b === undefined case. Something like this:
a = [ undefined ]
if(a[0]?)
console.log('if')
else
console.log('else')
will produce else on the console as expected, so will this:
a = undefined
if(a?[0])
console.log('if')
else
console.log('else')