Get the date ranges excluding the stoppage timings - scala

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

Related

The method '+' was called on null. Receiver: null Tried calling: +(123)

I get this error and I don't know why. I basically just check the operator and make calculations based on that.
Thank you for your help.
Function:
void calculate() {
setState(() {
int num1int = int.tryParse(_num1);
int num2int = int.tryParse(_num2);
int result = 0;
if (_operator == "+") {
result = num1int + num2int;
}
else if (_operator == "-") {
result = num1int - num2int;
}
else if (_operator == "*") {
result = num1int * num2int;
}
else if (_operator == "/") {
result = num1int ~/ num2int;
}
});
}
if "int.tryParse" can not convert it into integer, it will be returning "null". So your code does: null + null. You can add a check for num1int and num2int if it is null before calcultion.
please change your code to
if (_operator == "+") {
result = num1int??0 + num2int??0;
}
else if (_operator == "-") {
result = num1int??0 - num2int??0;
}
else if (_operator == "*") {
result = num1int??1 * num2int??1;
}
else if (_operator == "/") {
result = num1int??1 ~/ num2int??1;
}

Access ArrayList outside nested If else block in 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,

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

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