Access ArrayList outside nested If else block in Scala - scala

I have following code :-
var ArrayStop = new ArrayList[imeistoppage]()
val listings = rddStopCalculate.zipWithIndex().map(p => {
if (p._2 == 0) {
imei = p._1.imei
lat = p._1.latitude
long = p._1.longitude
gpsdt = p._1.gpsdt
} else if (p._2 > 0 && p._2 != lastindex) {
if (p._1.imei.equals(imei) && p._1.latitude == lat && p._1.longitude == long) {
flag += 1
newgpsdt = p._1.gpsdt
} else {
if (flag > 0) {
timeDiff = newgpsdt.getTime() - gpsdt.getTime()
if (timeDiff > 60000) {
ArrayStop.add(imeistoppage(p._1.imei, lat, long, timeDiff))
}
flag = 0
}
imei = p._1.imei
lat = p._1.latitude
long = p._1.longitude
gpsdt = p._1.gpsdt
}
} else {
if (p._1.imei.equals(imei) && p._1.latitude == lat && p._1.longitude == long) {
flag += 1
newgpsdt = p._1.gpsdt
}
if (flag > 0) {
timeDiff = newgpsdt.getTime() - gpsdt.getTime()
if (timeDiff > 60000) {
ArrayStop.add(imeistoppage(p._1.imei, lat, long, timeDiff))
}
flag = 0
}
}
ArrayStop
}).collect()
val returnList = listings(listings.length - 1)
val tempCollection = returnList.asScala
val tempRDD = sc.parallelize(tempCollection)
tempRDD.saveToCassandra("db", "table", SomeColumns("imei", "lat", "long", "duration"))
As we can see in above code I'm actually adding data to ArrayStop for specific IF condition only and I want this to be accessed outside this rdd loop but I was unable to do so So I created a variable "listings" to store data which is actually taking all the rows whereas I want only those entries which are added in ArrayStop. So what is the best way to bring any array outside nested If-else block. This is different from this issue
Scala spark, listbuffer is empty
Thanks,

Related

How to Convert JS Password Strength Meter to Swift

I'm trying to convert this javascript password score function to swift, so I can use the same logic on mobile as we do on web. Here is the JS fiddle with the code to test:
function scorePassword(pass) {
var score = 0;
if (!pass)
return score;
// award every unique letter until 5 repetitions
var letters = new Object();
for (var i=0; i<pass.length; i++) {
letters[pass[i]] = (letters[pass[i]] || 0) + 1;
score += 5.0 / letters[pass[i]];
}
// bonus points for mixing it up
var variations = {
digits: /\d/.test(pass),
lower: /[a-z]/.test(pass),
upper: /[A-Z]/.test(pass),
nonWords: /\W/.test(pass),
}
variationCount = 0;
for (var check in variations) {
variationCount += (variations[check] == true) ? 1 : 0;
}
score += (variationCount - 1) * 10;
return parseInt(score);
}
function checkPassStrength(pass) {
var score = scorePassword(pass);
if (score > 80)
return "Strong";
if (score > 60)
return "Good";
if (score >= 30)
return "Weak";
return "";
}
I'm having an issue in converting this part:
var letters = new Object();
for (var i=0; i<pass.length; i++) {
letters[pass[i]] = (letters[pass[i]] || 0) + 1;
score += 5.0 / letters[pass[i]];
}
I've tried to create a dictionary to store the character as key and then increment the value with each occurrences of that key, but it's not working as expected.
let string = "Testing22!"
var score = 0
var dictionary = [String.Element: Int]()
for x in string {
let value = dictionary[x] ?? 0
dictionary[x] = value + 1
score += 5 / value
}
print(dictionary) //["s": 1, "T": 1, "g": 1, "2": 2, "n": 1, "i": 1, "!": 1, "t": 1, "e": 1]
print(score)
I'm also not sure of the most efficient way to handle the regex checks for the bonus points section.
I'd port it over to swift like this, I'm sure there are some improvements to be made, but thats a quick conversion:
func scorePassword(_ inputString: String?) -> Double {
var score: Double = 0
guard let string = inputString, !string.isEmpty else { return score }
// award every unique letter until 5 repetitions
let countedSet = NSCountedSet()
for x in string {
countedSet.add(x)
score += 5.0 / Double(countedSet.count(for: x))
}
// bonus points for mixing it up
let variations = [
"^(?=.*[0-9]).*$",
"^(?=.*[a-z]).*$",
"^(?=.*[A-Z]).*$",
"^(?=.*\\W).*$"
]
var variationCount: Double = 0
for check in variations {
print(string.testRegex(check))
variationCount += string.testRegex(check) ? 1 : 0
}
score += (variationCount - 1) * 10
return floor(score)
}
func checkPassStrength(_ inputString: String?) -> String {
let score = scorePassword(inputString)
if score > 80 {
return "Strong"
} else if score > 60 {
return "Good"
} else if score > 30 {
return "Weak"
}
return ""
}
extension String {
func testRegex(_ regex: String) -> Bool {
let test = NSPredicate(format: "SELF MATCHES %#", regex)
return test.evaluate(with: self)
}
}
You can run js code inside Swift and get the result from it, so you can share code between platforms.
let jsSource = """
function scorePassword(pass) {
var score = 0;
if (!pass)
return score;
// award every unique letter until 5 repetitions
var letters = new Object();
for (var i=0; i<pass.length; i++) {
letters[pass[i]] = (letters[pass[i]] || 0) + 1;
score += 5.0 / letters[pass[i]];
}
// bonus points for mixing it up
var variations = {
digits: /d/.test(pass),
lower: /[a-z]/.test(pass),
upper: /[A-Z]/.test(pass),
nonWords: /W/.test(pass),
}
variationCount = 0;
for (var check in variations) {
variationCount += (variations[check] == true) ? 1 : 0;
}
score += (variationCount - 1) * 10;
return parseInt(score);
}
function checkPassStrength(pass) {
var score = scorePassword(pass);
if (score > 80)
return "Strong";
if (score > 60)
return "Good";
if (score >= 30)
return "Weak";
return "";
}
"""
let context = JSContext()
context?.evaluateScript(jsSource)
let testFunction = context?.objectForKeyedSubscript("scorePassword")
let result = testFunction?.call(withArguments: ["1234"])
print("js result : " , result )
Note; I edited the part "digits: /\d/.test(pass)" to "digits: /d/.test(pass)"

How to claculate adjacent data with spark/scala

I hava a RDD,the RDD type is Tuple2(value,timestamp),value is 1 or 0 , timestamp is a sequential, and a variable limitTime=4. When I map the RDD, if the value is 1 the output value from current timestamp to (timestamp +limitTime) is 1 ,else current value is 0, I call it is period. But there is a special case,when the value is 1 and its timestamp is in period,then it is ignored, the current value of output is 0
input : (0,0),(1,1),(0,3),(0,5),(0,7),(0,8),(0,10),(1,12),(0,14),(0,15)
expected output :(0,0),(1,1),(1,3),(1,5),(0,7),(0,8),(0,10),(1,12),(1,14),(1,15)
special input2: (0,0),(1,1),(0,3),(1,5),(0,7),(1,8),(0,10),(1,12),(0,14),(0,15)
expected output2:(0,0),(1,1),(1,3),(1,5),(0,7),(1,8),(1,10),(1,12),(0,14),(0,15)
this is my try:
var limitTime=4
var startTime= -limitTime
val rdd=sc.parallelize(List((0,0),(1,1),(0,3),(1,5),(0,7),(1,8),(0,10),(1,12),(0,14),(0,15)),4)
val results=rdd.mapPartitions(parIter => {
var resultIter = new ArrayBuffer[Tuple2[Int,Int]]()
while (parIter.hasNext) {
val iter = parIter.next()
if(iter._1==1){
if(iter._2<=startTime+limitTime&&iter._2!=0&&iter._2>=startTime){
resultIter.append(iter)
}else{
resultIter.append(iter)
startTime=iter._2
}
}else{
if(iter._2<=startTime+limitTime&&iter._2!=0&&iter._2>=startTime){
resultIter.append((1,iter._2))
}else{
resultIter.append(iter)
}
}
}
resultIter.toIterator
})
results.collect().foreach(println)
it's so inefficient,how can I get the same result without array?
Following code should work for both of your cases.
var limitTime=3
var first = true
var previousValue = 0
val rdd=sc.parallelize(List((0,0),(1,1),(0,3),(0,5),(0,7),(0,8),(0,10),(1,12),(0,14),(0,15)), 4)
val tempResult = rdd.collect.map(pair => {
if(first){
first = false
previousValue = pair._1
(pair._1, pair._2)
}
else {
if ((pair._1 == 1 || previousValue == 1) && limitTime > 0) {
limitTime -= 1
previousValue = 1
(1, pair._2)
}
else {
if (limitTime == 0) limitTime = 3
previousValue = pair._1
(pair._1, pair._2)
}
}
})
tempResult.foreach(print)
If it doesn't please let me know

How to define count without using var

I have this simple function that return some Status:
def getStatus : String =
{
//...
}
And i want to wait until this return specific status but still count this number of calls before exit:
def wait =
{
var count = 0
while (getStatus != "smeStatus" && count < 10) {
// some code here
count++
}
}
How can i avoid of using var ?
You can use a recursive method that takes the count-so-far and returns it + 1:
def waitUntilDone(countSoFar: Int): Int = {
if (getStatus != "smeStatus" && countSoFar < 10) {
// some code here
waitUntilDone(countSoFar + 1)
} else {
countSoFar
}
}
// invoke it starting with 0:
val count = waitUntilDone(0)
def status = ""
def waiting: Unit = {
def check(count: Int): Unit = {
if(count < 10 && status != "smeStatus") {
// do something
check(count + 1)
}
}
check(0)
}

Get the date ranges excluding the stoppage timings

Here is my scala case class DateRange:
case class DateRange(startDT: DateTime, endDT: DateTime)
The sample input data (Joda):
val dt1 = DateTime.parse("2016-01-04T03:00:00.000Z") // dt1 will always the range start date time
val dt2 = DateTime.parse("2016-01-05T04:00:00.000Z") // dt2 will always the range end date time
val dr = DateRange(dt1, dt2) // container to hold the date ranges
val st = LocalTime.parse("13:00:00") // st will always the stoppage start time
val et = LocalTime.parse("02:00:00") // et will always the stoppage end time
I am trying to get the result as List[DateRange] excluding the stoppage timing intervals. The Date ranges and time ranges maybe anything.
Desired output for the above input data:
List(DateRange(2016-01-04T03:00:00.000Z,2016-01-04T13:00:00.000Z),DateRange(2016-01-05T02:00:00.000Z,2016-01-05T04:00:00.000Z))
I tried like this:
val result = if (st.isBefore(et)) {
if (dr.startDT.isBefore(dr.endDT) && st.isAfter(dr.startDT.toLocalTime)) {
DateRange(dr.startDT.withTime(st), dr.startDT.withTime(et))
} else if (dr.startDT.isBefore(dr.endDT) && st.isBefore(dr.startDT.toLocalTime)) {
DateRange(dr.endDT.withTime(st), dr.endDT.withTime(et))
} else {
DateRange(dr.startDT.withTime(st), dr.startDT.withTime(et))
}
}
else {
if (dr.startDT.isBefore(dr.endDT) && et.isBefore(dr.endDT.toLocalTime) && st.isBefore(dr.endDT.toLocalTime)) {
DateRange(dr.startDT.withTime(st), dr.endDT.withTime(23, 59, 59, 999))
} else if (dr.startDT.isBefore(dr.endDT) && et.isBefore(dr.endDT.toLocalTime) && st.isAfter(dr.endDT.toLocalTime)) {
DateRange(dr.startDT, dr.endDT.withTime(et))
} else if (dr.startDT.isBefore(dr.endDT) && et.isBefore(dr.endDT.toLocalTime) && st.isAfter(dr.endDT.toLocalTime)) {
DateRange(dr.startDT, dr.endDT.withTime(et))
} else {
DateRange(dr.startDT.withTime(st), dr.endDT.withTime(et))
}
Try This,
object Splitter extends App {
val shiftStartDate = DateTime.parse("2016-01-04T06:00:00.000")
val shiftEndDate = DateTime.parse("2016-01-04T16:00:00.000")
val st = LocalTime.parse("23:00:00")
val et = LocalTime.parse("08:00:00")
val stoppageStartDate = shiftStartDate.toLocalDate.toDateTime(st)
val StoppageEndDate = if(st.isBefore(et)){
shiftStartDate.toLocalDate.toDateTime(et)
}else{
shiftStartDate.toLocalDate.toDateTime(et).plusDays(1)
}
val result = if ((stoppageStartDate.isAfter(shiftStartDate) || stoppageStartDate.isEqual(shiftStartDate)) &&
(StoppageEndDate.isBefore(shiftEndDate) || StoppageEndDate.isEqual(shiftEndDate))) {
List(DateRange(shiftStartDate, stoppageStartDate), DateRange(StoppageEndDate, shiftEndDate))
} else if ((stoppageStartDate.isAfter(shiftStartDate) || stoppageStartDate.isEqual(shiftStartDate)) &&
StoppageEndDate.isAfter(shiftEndDate) && stoppageStartDate.isBefore(shiftEndDate)) {
List(DateRange(shiftStartDate, stoppageStartDate))
}
else if (stoppageStartDate.isBefore(shiftStartDate) && (StoppageEndDate.isBefore(shiftEndDate) ||
StoppageEndDate.isEqual(shiftEndDate)) && StoppageEndDate.isAfter(shiftStartDate)) {
List(DateRange(StoppageEndDate, shiftEndDate))
} else if (stoppageStartDate.isBefore(shiftStartDate) && StoppageEndDate.isAfter(shiftEndDate)) {
Nil
} else {
List(DateRange(shiftStartDate, shiftEndDate))
}
println(">>>> " + result.result.filterNot(x=>x.startTS==x.endTS))
}

Connect-Four Game in Scala

I have to make a connect-four game using scala. I have attached the code but everytime the game runs and gets to row 3 it just continues to change the second rows entry instead of going to the next row. Any help would be appreciated. I found this code on another thread on here and couldn't figure out how to get it to work:
// makes the board
val table = Array.fill(9,8)('-')
var i = 0;
while(i < 8){
table(8)(i) = (i+'0').toChar
i = i+1;
}
// prints starting board
def printBoard(table: Array[Array[Char]]) {
table.foreach( x => println(x.mkString(" ")))
}
//player 1 moves
def playerMove1(){
val move = readInt
var currentRow1 = 7
while (currentRow1 >= 0)
if (table(currentRow1)(move) != ('-')) {
currentRow1 = (currentRow1-1)
table(currentRow1)(move) = ('X')
return (player2)}
} else {
table(currentRow1)(move) = ('X')
return (player2)
}
}
//player 2 moves
def playerMove2(){
val move = readInt
var currentRow2 = 7
while (currentRow2 >= 0)
if (table(currentRow2)(move) != ('-')) {
currentRow2 = (currentRow2-1)
table(currentRow2)(move) = ('O')
return (player1)}
} else {
table(currentRow2)(move) = ('O')
return (player1)
}
}
//player 1
def player1(){
printBoard(table)
println("Player 1 it is your turn. Choose a column 0-7")
playerMove1()
}
//player 2
def player2(){
printBoard(table)
println("Player 2 it is your turn. Choose a column 0-7")
playerMove2()
}
for (turn <- 1 to 32){
player1
player2
}
I've tried to make your code readable and compiling and also tried to fix some logic.
However, I've never worked with Scala so this is just a first sketch where you might want to continue ...
Some functions can be merged and the currentRow needed a fix. See here:
object ConnectFour{
val table = Array.fill(9,8)('-')
val currentRow = Array.fill(8)(8)
def main(args: Array[String]) {
var i = 0;
while(i < 8) {
table(8)(i) = (i+'0').toChar
i = i+1;
}
player(1)
}
def printBoard(table: Array[Array[Char]]) {
table.foreach( x => println(x.mkString(" ")))
}
def player(playerNr : Int){
printBoard(table)
println("Player " + playerNr + " it is your turn. Choose a column 0-7")
var column = readAndVerifyInt
var nextUser = 1 : Int
var symbol = 'O' : Char
if(playerNr == 1) {
symbol = 'X'
nextUser = 2
}
var curR = currentRow(column)
while (curR >= 0) {
if (table(curR)(column) != ('-')) {
curR = curR-1
currentRow(column) = curR
}
table(curR)(column) = symbol
player(nextUser)
}
}
def readAndVerifyInt() : Int = {
var column = readInt
if (column >= 0 && column <= 7) {
return column
} else {
println(" > Please try again")
return readAndVerifyInt
}
}
}