How do I make an increaser for several variables? - scala

I have a class with several variables containing Integers and I want a method which increases one of them by a certain amount depending on the call.
case class Bank {
private var depo = 0
private var loan = 0
def deposit(amount: Int): Boolean = {
if(amount>0) {
depo += amount
true
} else false
}
def withdraw(amount: Int): Boolean = {
if(amount > 0 && amount <= balance) {
depo -= amount
true
} else false
}
def balance_=(b:Int) = {
if(b >= 0) {
if(b < depo) withdraw(depo-b) else deposit(b-depo)
} else false
}
def balance = depo
}
When I want to increase deposits, I just call
myBank.balance += 10
but when I now want to increase loan, I have to write an additional method, right?
Is there a possibility to write a method like
increaser(varToIncrease, amount)
Is that possible or even useful? Or do I have to write an "increaser"-method for every single var?

See if this is what you are looking for based on your additional comments:
case class Bank {
private var depo = 0
private var loans = 0
def deposit(amount: Int): Boolean = addTo(amount, depo += amount)
def loan(amount: Int): Boolean = addTo(amount, loans += amount)
private def addTo(amount:Int, func: => Unit):Boolean = {
if(amount > 0) {
func
true
}
else
false
}
def withdraw(amount: Int): Boolean = {
if(amount > 0 && amount <= balance) {
depo -= amount
true
} else false
}
def balance_=(b:Int) = {
if(b >= 0) {
if(b < depo) withdraw(depo-b) else deposit(b-depo)
} else false
}
def balance = depo
def loanAmount = loans
}
object BankTest{
def main(args: Array[String]) {
val b = new Bank
println("Starting amounts, " + b.balance + ", " + b.loanAmount)
b.deposit(10)
println(b.balance)
b.deposit(-1)
println(b.balance)
b.loan(100)
println(b.loanAmount)
b.loan(-50)
println(b.loanAmount)
}
}
I created two public functions to increase balance and loaned amount respectively. Then, I created an interval addTo function to handle the business logic of performing an operation to increase one of those vars.

You cannot increase the integer parameter inside another method. If you want to create an increaser method as you wanted, you have to pass in an immutable object into the method.

Related

How to buffer emission with custom weither function

I need functionality like monix.Observable.bufferTimedAndCounted but with custom "weither". I found bufferTimedWithPressure operator which allow use item's weith:
val subj = PublishSubject[String]()
subj
.bufferTimedWithPressure(1.seconds, 5, _ => 3)
.subscribe(s => {
println(s)
Future.successful(Ack.Continue)
})
for (i <- 1 to 60) {
Thread.sleep(100)
subj.onNext(i.toString)
}
But emission happens every specified duration. I need behavior like bufferTimedAndCounted, so emission happens when buffer full. How to achive that?
I copied BufferTimedObservable from monix sources and slightly change it, add weight function (Note - i'm not tested it in all cases):
import java.util.concurrent.TimeUnit
import monix.execution.Ack.{Continue, Stop}
import monix.execution.cancelables.{CompositeCancelable, MultiAssignCancelable}
import monix.execution.{Ack, Cancelable}
import monix.reactive.Observable
import monix.reactive.observers.Subscriber
import scala.collection.mutable.ListBuffer
import scala.concurrent.Future
import scala.concurrent.duration.{Duration, FiniteDuration, MILLISECONDS}
/**
* Copied from monix sources, adopted to size instead count
*
*/
final class BufferTimedWithWeigthObservable[+A](source: Observable[A], timespan: FiniteDuration, maxSize: Int, sizeOf: A => Int)
extends Observable[Seq[A]] {
require(timespan > Duration.Zero, "timespan must be strictly positive")
require(maxSize >= 0, "maxSize must be positive")
def unsafeSubscribeFn(out: Subscriber[Seq[A]]): Cancelable = {
val periodicTask = MultiAssignCancelable()
val connection = source.unsafeSubscribeFn(new Subscriber[A] with Runnable {
self =>
implicit val scheduler = out.scheduler
private[this] val timespanMillis = timespan.toMillis
// MUST BE synchronized by `self`
private[this] var ack: Future[Ack] = Continue
// MUST BE synchronized by `self`
private[this] var buffer = ListBuffer.empty[A]
// MUST BE synchronized by `self`
private[this] var currentSize = 0
private[this] var sizeOfLast = 0
private[this] var expiresAt = scheduler.clockMonotonic(MILLISECONDS) + timespanMillis
locally {
// Scheduling the first tick, in the constructor
periodicTask := out.scheduler.scheduleOnce(timespanMillis, TimeUnit.MILLISECONDS, self)
}
// Runs periodically, every `timespan`
def run(): Unit = self.synchronized {
val now = scheduler.clockMonotonic(MILLISECONDS)
// Do we still have time remaining?
if (now < expiresAt) {
// If we still have time remaining, it's either a scheduler
// problem, or we rushed to signaling the bundle upon reaching
// the maximum size in onNext. So we sleep some more.
val remaining = expiresAt - now
periodicTask := scheduler.scheduleOnce(remaining, TimeUnit.MILLISECONDS, self)
} else if (buffer != null) {
// The timespan has passed since the last signal so we need
// to send the current bundle
sendNextAndReset(now, byPeriod = true).syncOnContinue(
// Schedule the next tick, but only after we are done
// sending the bundle
run())
}
}
// Must be synchronized by `self`
private def sendNextAndReset(now: Long, byPeriod: Boolean = false): Future[Ack] = {
val prepare = if (byPeriod) buffer else buffer.dropRight(1)
// Reset
if (byPeriod) {
buffer = ListBuffer.empty[A]
currentSize = 0
sizeOfLast = 0
} else {
buffer = buffer.takeRight(1)
currentSize = sizeOfLast
}
// Setting the time of the next scheduled tick
expiresAt = now + timespanMillis
ack = ack.syncTryFlatten.syncFlatMap {
case Continue => out.onNext(prepare)
case Stop => Stop
}
ack
}
def onNext(elem: A): Future[Ack] = self.synchronized {
val now = scheduler.clockMonotonic(MILLISECONDS)
buffer.append(elem)
sizeOfLast = sizeOf(elem)
currentSize = currentSize + sizeOfLast
// 9 and 9 true
//10 and 9
if (expiresAt <= now || (maxSize > 0 && maxSize < currentSize)) {
sendNextAndReset(now)
}
else {
Continue
}
}
def onError(ex: Throwable): Unit = self.synchronized {
periodicTask.cancel()
ack = Stop
buffer = null
out.onError(ex)
}
def onComplete(): Unit = self.synchronized {
periodicTask.cancel()
if (buffer.nonEmpty) {
val bundleToSend = buffer.toList
// In case the last onNext isn't finished, then
// we need to apply back-pressure, otherwise this
// onNext will break the contract.
ack.syncOnContinue {
out.onNext(bundleToSend)
out.onComplete()
}
} else {
// We can just stream directly
out.onComplete()
}
// GC relief
buffer = null
// Ensuring that nothing else happens
ack = Stop
}
})
CompositeCancelable(connection, periodicTask)
}
}
How use it:
object MonixImplicits {
implicit class RichObservable[+A](source: Observable[A]) {
def bufferTimedAndSized(timespan: FiniteDuration, maxSize: Int, sizeOf: A => Int): Observable[Seq[A]] = {
new BufferTimedWithWeigthObservable(source, timespan, maxSize, sizeOf)
}
}
}
import MonixImplicits._
someObservable.bufferTimedAndSized(1.seconds, 5, item => item.size)

Will values in function generate every time?

object isValidUuid {
val sample = "f40473b8-9924-2a9a-bd82-7432191f2a75"
val len = sample.length
val dashIndices = sample.indices.filter(sample(_) == '-')
def apply(string: String) = {
string.length == len && dashIndices.forall(string(_) == '-')
}
}
def isValidUuid(string: String) = {
//f40473b8-9924-2a9a-bd82-7432191f2a75
val sample = "f40473b8-9924-2a9a-bd82-7432191f2a75"
val len = sample.length
val dashIndices = sample.indices.filter(sample(_) == '-')
string.length == len && dashIndices.forall(string(_) == '-')
}
Did the object and function isValidUuid do exactly the same thing,
or object will be faster,because function calculate len and dashIndices every time?
This scala code:
object O {
val i = 1
def foo = {
i
}
def bar = {
val x = 1
x
}
}
Compiles to this java:
public class _$$anon$1$O$ {
private final int i;
public int i() {
return this.i;
}
public int foo() {
return this.i();
}
public int bar() {
final int x = 1;
return x;
}
{
this.i = 1;
}
}
// lazy object initialization omitted
As you can see, all values inside the function are transpiled into local variables, while values inside the object are class fields and they are initialized only once (when object is initialized). I omitted object initialization code for clarity.
Check my scala-to-java tool, it helps to understand how scala works in such cases.
You can easy test this, adding sleep to your lenght calculation
object isValidUuidObj {
val sample = "f40473b8-9924-2a9a-bd82-7432191f2a75"
val len = {
Thread.sleep(1000)
sample.length
}
val dashIndices = sample.indices.filter(sample(_) == '-')
def apply(string: String) = {
string.length == len && dashIndices.forall(string(_) == '-')
}
}
def isValidUuid(string: String) = {
//f40473b8-9924-2a9a-bd82-7432191f2a75
val sample = "f40473b8-9924-2a9a-bd82-7432191f2a75"
val len = {
Thread.sleep(1000)
sample.length
}
val dashIndices = sample.indices.filter(sample(_) == '-')
string.length == len && dashIndices.forall(string(_) == '-')
}
Yes, object will be faster, but I don't think that in your case this difference is important.
You'd better keep all constants in object (magic numbers/strings are always bad idea), while using object for calculations is not a clean solution.

Call the neighbor actors in the game of life using scala akka actor model

I'm just beginner in scala but experienced in Java and C++, now I want to use akka actor model to implement the parallel Conway's Game of Life. My thought is create a 50*50 grid, each cell is an actor, and passing messages among actors to update. Here is the way I create the actors:
class World(row: Int, col: Int, step: Int) extends Actor {
val random = new Random() //generate the alive or dead cell for the game
val cellgrid = new World(row, col, step)
def receive = {
case Start => {
for(gridrow <- 0 until row) {
for(gridcol <- 0 until col) {
context.actorOf(Props(new Grid(random.nextBoolean, gridrow, gridcol, row, col, step)))
}
}
for (gridrow <- 0 until row) {
for (gridcol <- 0 until col) {
sender ! Compare()
}
}
}
case Done(gridrow, gridcol, alive) => {
for(gridrow <- 0 until row) {
for(gridcol <- 0 until col) {
if(alive) print("* ")
else print(" ")
}
print("\n")
}
sender ! Stop
}
case Stop => {context.stop(self); println("Stopped the actor system!")}
case _ => context.stop(self)
}
}
But that causes a problem. Since I create so many Grid classes, I'm having trouble call the neighbor actors. Here is the Grid class:
class Grid(var life: Boolean, gridrow: Int, gridcol: Int, row: Int, col: Int, step: Int) extends Actor {
val alive = life
var numNeighbors = 0
var currentStep = 0
val desiredSteps = step
val count = Array(0,0)
val countsuround = Array(0,0)
for (neighbourX <- gridrow - 1 to gridrow + 1) {
if (neighbourX >= 0 && neighbourX < col) {
for (neighbourY <- gridcol - 1 to gridcol + 1) {
if (neighbourY >= 0 && neighbourY < row && (neighbourX != row && neighbourY != col))
numNeighbors = numNeighbors + 1
}
}
}
def receive = {
case Compare() => {
for (neighbourX <- gridrow - 1 to gridrow + 1) {
if (neighbourX >= 0 && neighbourX < col) {
for (neighbourY <- gridcol - 1 to gridcol + 1) {
if (neighbourY >= 0 && neighbourY < row && (neighbourX != row && neighbourY != col))
sender ! Record(life, currentStep) //Here I need to pass messages to my neighbors
}
}
}
}
case Record(alive,step) => {
if(alive == true){
count(step%2) += 1
}
countsuround(step%2) += 1
self ! Check()
}
case Check() => {
if(countsuround(currentStep%2) == numNeighbors) {
if(count(currentStep%2) ==3 ||life == true && count(currentStep%2) == 2)
life = true
else
life = false
count(currentStep%2) =0; countsuround(currentStep%2) = count(currentStep%2)
currentStep += 1
if(desiredSteps <= currentStep + 1)
sender ! Stop
else {
sender ! Done(gridrow, gridcol, alive)
//context.stop(self)
}
}
}
}
}
Please take a look at the Compare case in the receive function, at the end of that, I need to send messages Record to my neighbors, but I can't find a proper way to talk, I don't have any index of neighbors (like (neighborX, neighborY).Record(life, currentStep)). Please help me, I've stuck here for several weeks. Thanks!!!
Here is a full working example with some comments.
import akka.actor._
import scala.concurrent.duration._
object GameOfLife extends App {
val system = ActorSystem("game-of-life")
implicit val ec = system.dispatcher // implicit ExecutionContext for scheduler
val Width = 20
val Height = 20
// create view so we can send results to
val view = system.actorOf(Props(classOf[View], Width, Height), "view")
// create map of cells, key is coordinate, a tuple (Int, Int)
val cells = (for { i <- 0 until Width; j <- 0 until Height } yield {
val cellRef = system.actorOf(Props[Cell], s"cell_$i-$j") // correct usage of Props, see docs for details
((i,j), cellRef)
}).toMap
// we need some helpers to work with grid
val neighbours = (x:Int, y:Int) => Neighbours(
for (i <- x - 1 to x + 1; j <- y - 1 to y + 1; if ((i,j) != (x,y))) yield {
cells( ( (i + Width) % Width, (j + Height) % Height) )
}
)
for { i <- 0 until Width; j <- 0 until Height } { // notice that this loop doesn't have yield, so it is foreach loop
cells((i,j)) ! neighbours(i,j) // send cell its' neighbours
}
// now we need to synchronously update all cells,
// this is the main reason why suggested model (one actor - one cell) is probably not the most adequate
for { i <- 0 until Width; j <- 0 until Height } {
cells((i,j)) ! SetState(alive = util.Random.nextBoolean, x = i, y = j)
}
// for simplicity I assume that update will take less then update time
val refreshTime = 100.millis
system.scheduler.schedule(1.second, refreshTime) {
view ! Run
for { i <- 0 until Width; j <- 0 until Height } {
cells((i,j)) ! Run
}
}
}
class View(w:Int, h:Int) extends Actor {
var actorStates: Map[(Int,Int), Boolean] = Map()
def receive:Receive = {
case Run => actorStates = Map.empty
case UpdateView(alive, x, y) =>
actorStates = actorStates + (((x,y), alive))
if (actorStates.size == w * h) {
for { j <- 0 until h } {
for(i <- 0 until w) {
if(actorStates((i,j))) {
print("x ")
} else {
print(". ")
}
}
println()
}
}
}
}
class Cell extends Actor {
var neighbours:Seq[ActorRef] = Seq()
var neighbourStates: Map[ActorRef, Boolean] = Map() // Map.empty[Map[ActorRef, Boolean]] is better
var alive:Boolean = false
var previousState:Boolean = false
var x:Int = 0
var y:Int = 0
def receive : Receive = {
case Run =>
neighbourStates = Map.empty
previousState = alive
neighbours.foreach(_ ! QueryState)
case SetState(alive,x,y) =>
this.alive = alive
this.x = x
this.y = y
case Neighbours(xs) =>
neighbours = xs
case QueryState =>
sender ! NeighbourState(alive = previousState)
case NeighbourState(alive) =>
neighbourStates = neighbourStates + ((sender, alive))
// this is tricky when all senders has send you their states it doesn't mean that you can mutate your own,
// they could still may request your internal state, will use hackish previousState
if (neighbourStates.size == 8) { // total of 8 neighbours sent their states, we are complete with update
val aliveMembers = neighbourStates.values.filter(identity).size
aliveMembers match {
case n if n < 2 => this.alive = false
case 3 => this.alive = true
case n if n > 3 => this.alive = false;
case _ => // 2, state doesn't change
}
context.actorSelection("/user/view") ! UpdateView(this.alive, x, y)
}
}
}
case class SetState(alive:Boolean, x:Int, y:Int)
case class Neighbours(xs:Seq[ActorRef])
case object QueryState
case object Run
case class NeighbourState(alive:Boolean)
case class UpdateView (alive:Boolean, x:Int, y:Int)

Scala Count Lines in a file VERY FAST

Count lines in a file (With BufferedInputStream) in Scala.
object CountLinesScala {
def main(args: Array[String]) {
val c = countLines("C:/.../Motifs/mrr569.fasta")
println(c)
}
def countLines(filename: String): Int = {
val is = new BufferedInputStream(new FileInputStream(filename))
try {
val c = Array.ofDim[Byte](1024)
var count = 0
var readChars = 0
var empty = true
while ((readChars = is.read(c)) != -1) {
empty = false
for (i <- 0 until readChars if c(i) == '\n') {
count=count +1
}
}
if ((count == 0 && !empty)) 1 else count
} finally {
is.close()
}
}
}
its not working, Why ?
i click run but there is no reaction, and no Errors !
You code is not working because the type of an assignation is Unit and you are comparing Unit to an Int (-1) which can never be equal, therefore your while loop never exits.
More specifically, this expression has type Unit
(readChars = is.read(c))
if you want to fix your version of the program you could define an internal function doRead
def doRead: Int = {
readChars = is.read(c)
readChars
}
and use that in your while loop
while (doRead != -1) {
empty = false
for (i <- 0 until readChars if c(i) == '\n') {
count=count +1
}
}
the final code for countLine would look like
def countLines(filename: String): Int = {
val is = new BufferedInputStream(new FileInputStream(filename))
try {
val c = Array.ofDim[Byte](1024)
var count = 0
var readChars = 0
var empty = true
def doRead: Int = {
readChars = is.read(c)
readChars
}
while (doRead!= -1) {
empty = false
for (i <- 0 until readChars if c(i) == '\n') {
count=count +1
}
}
if ((count == 0 && !empty)) 1 else count
} finally {
is.close()
}
}
However I advise you not to write Scala code like this. As was answered by brian, the most idiomatic way to write this would be to use the scala standard library and write
scala.io.Source.fromFile("C:/.../Motifs/mrr569.fasta").getLines.size
Then your original program would become
import scala.io.Source
object CountLinesScala {
def main(args: Array[String]) {
val c = Source.fromFile("C:/.../Motifs/mrr569.fasta").getLines().size
println(c)
}
}
The standard library handles this nicely.
scala.io.Source.fromFile("C:/.../Motifs/mrr569.fasta").getLines.size

What is the performance penalty to using lazy val in scala, but INSIDE a def

I know inside a class using lazy val uses some type of double lock pattern. But what about inside a function definition? Does it use the same pattern?
For example:
class Sample {
def computation(): Something = {}
def fn(compute: Boolean, default: Something): Something = {
lazy val c = computation()
if (compute) c*c else default
}
}
Yes it uses the same pattern. See your Scala-code:
class Sample {
def computation(): Int = 100
def fn(compute: Boolean, default: Int): Int = {
lazy val c = computation()
if (compute) c*c else default
}
}
compiled with scalac and decompiled with jad:
public class Sample implements ScalaObject
{
public int computation()
{
return 100;
}
public int fn(boolean compute, int default)
{
VolatileIntRef bitmap$0$1 = new VolatileIntRef(0);
IntRef c$lzy$1 = new IntRef(0);
return compute ? c$1(c$lzy$1, bitmap$0$1) * c$1(c$lzy$1, bitmap$0$1) : default;
}
private final int c$1(IntRef intref, VolatileIntRef volatileintref)
{
if((volatileintref.elem & 1) == 0)
synchronized(this)
{
if((volatileintref.elem & 1) == 0)
{
intref.elem = computation();
volatileintref.elem = volatileintref.elem | 1;
}
BoxedUnit _tmp = BoxedUnit.UNIT;
}
return intref.elem;
}
public Sample()
{
}
}