how to convert image (.jpg) to array in scala and how to count the green pixel in the same array using scala - scala

import java.io.File
import javax.imageio.ImageIO
import java.awt.image.BufferedImage
val img = ImageIO.read(newFile("Filename.jpg"))
val w = img.getWidth
val h = img.getHeight
for (x <- 0 until w)
for (y <- 0 until h)
img.getRGB(x,y)
ImageIO.write(img,"jpg",new File("test.jpg"))
How to convert img to byte array and count the green pixels in the same.

You can count the green pixel by comparing RGB value of each pixel with RGB value of Green color.
Example:
...
val w = img.getWidth
val h = img.getHeight
val green = Color.GREEN
var ctrGreen = 0
var ctrTotal = 0
for (x <- 0 until w)
for (y <- 0 until h) {
val c = new Color(img.getRGB(x, y))
if (isEqual(c, green)) {
ctrGreen += 1
}
ctrTotal += 1;
}
println("Green pixel count: " + ctrGreen)
println("Total pixel count: " + ctrTotal)
}
def isEqual(c1: Color, c2: Color): Boolean = {
c1.getRed == c2.getRed && c1.getBlue == c2.getBlue && c1.getGreen == c2.getGreen
}
But sometime it is hard to find the exact match for color's RGB value (i.e. in case of green it is (0,255,0) ). So you can also check whether a pixel belongs to a color range or not. Example:
....
val lightGreen = new Color(0,255,0)
val darkGreen = new Color(0,100,0)
var ctrGreen = 0
var ctrTotal = 0
for (x <- 0 until w)
for (y <- 0 until h) {
val c = new Color(img.getRGB(x, y))
if (isBetween(c, lightGreen,darkGreen)) {
ctrGreen += 1
}
ctrTotal += 1;
}
println("Green pixel count: " + ctrGreen)
println("Total pixel count: " + ctrTotal)
}
def isBetween(c: Color, c1: Color, c2: Color): Boolean = {
c.getRed >= c1.getRed && c.getRed <= c2.getRed && c.getBlue >= c1.getBlue && c.getBlue <= c2.getBlue && c.getGreen <= c1.getGreen && c.getGreen >= c2.getGreen
}

Related

How to match multiple condition in if else

I have 3 variables like below, and I want the result as first priority is return x, if x is blank then return y, if x and y both blank then return z.
below is my code, but this is not working.
val x = "1"
val y = "2"
val z = "3"
val result = {
var res = "
if (x == "") y else x
else if (y == "") z
}
For result First priority is to x and if x = "" then y, if y also "" then return z
Please help
You are assigning Integer value to variables & Checking empty string if condition. Comparing values of types Int and String using `==' will always yield false
Please check below code.
// For variables of type string.
if(x != "") x else if (y != "") y else z
scala> val x = 1
x: Int = 1
scala> val y = 2
y: Int = 2
scala> val z = 3
z: Int = 3
scala> if(x != "") x else if (y != "") y else z // This will give result if variables are type string. but if it is int type checking this way give you wrong values.
<console>:30: warning: comparing values of types Int and String using `!=' will always yield true
if(x != "") x else if (y != "") y else z
^
<console>:30: warning: comparing values of types Int and String using `!=' will always yield true
if(x != "") x else if (y != "") y else z
^
res8: Int = 1
scala> if (!x.isNaN) x else if(!y.isNaN) y else z // Check this way

Combine multiple sequential entries in Scala/Spark

I have an array of numbers separated by comma as shown:
a:{108,109,110,112,114,115,116,118}
I need the output something like this:
a:{108-110, 112, 114-116, 118}
I am trying to group the continuous numbers with "-" in between.
For example, 108,109,110 are continuous numbers, so I get 108-110. 112 is separate entry; 114,115,116 again represents a sequence, so I get 114-116. 118 is separate and treated as such.
I am doing this in Spark. I wrote the following code:
import scala.collection.mutable.ArrayBuffer
def Sample(x:String):ArrayBuffer[String]={
val x1 = x.split(",")
var a:Int = 0
var present=""
var next:Int = 0
var yrTemp = ""
var yrAr= ArrayBuffer[String]()
var che:Int = 0
var storeV = ""
var p:Int = 0
var q:Int = 0
var count:Int = 1
while(a < x1.length)
{
yrTemp = x1(a)
if(x1.length == 1)
{
yrAr+=x1(a)
}
else
if(a < x1.length - 1)
{
present = x1(a)
if(che == 0)
{
storeV = present
}
p = x1(a).toInt
q = x1(a+1).toInt
if(p == q)
{
yrTemp = yrTemp
che = 1
}
else
if(p != q)
{
yrTemp = storeV + "-" + present
che = 0
yrAr+=yrTemp
}
}
else
if(a == x1.length-1)
{
present = x1(a)
yrTemp = present
che = 0
yrAr+=yrTemp
}
a = a+1
}
yrAr
}
val SampleUDF = udf(Sample(_:String))
I am getting the output as follows:
a:{108-108, 109-109, 110-110, 112, 114-114, 115-115, 116-116, 118}
I am not able to figure out where I am going wrong. Can you please help me in correcting this. TIA.
Here's another way:
def rangeToString(a: Int, b: Int) = if (a == b) s"$a" else s"$a-$b"
def reduce(xs: Seq[Int], min: Int, max: Int, ranges: Seq[String]): Seq[String] = xs match {
case y +: ys if (y - max <= 1) => reduce(ys, min, y, ranges)
case y +: ys => reduce(ys, y, y, ranges :+ rangeToString(min, max))
case Seq() => ranges :+ rangeToString(min, max)
}
def output(xs: Array[Int]) = reduce(xs, xs.head, xs.head, Vector())//.toArray
Which you can test:
println(output(Array(108,109,110,112,114,115,116,118)))
// Vector(108-110, 112, 114-116, 118)
Basically this is a tail recursive function - i.e. you take your "variables" as the input, then it calls itself with updated "variables" on each loop. So here xs is your array, min and max are integers used to keep track of the lowest and highest numbers so far, and ranges is the output sequence of Strings that gets added to when required.
The first pattern (y being the first element, and ys being the rest of the sequence - because that's how the +: extractor works) is matched if there's at least one element (ys can be an empty list) and it follows on from the previous maximum.
The second is if it doesn't follow on, and needs to reset the minimum and add the completed range to the output.
The third case is where we've got to the end of the input and just output the result, rather than calling the loop again.
Internet karma points to anyone who can work out how to eliminate the duplication of ranges :+ rangeToString(min, max)!
here is a solution :
def combineConsecutive(s: String): Seq[String] = {
val ints: List[Int] = s.split(',').map(_.toInt).toList.reverse
ints
.drop(1)
.foldLeft(List(List(ints.head)))((acc, e) => if ((acc.head.head - e) <= 1)
(e :: acc.head) :: acc.tail
else
List(e) :: acc)
.map(group => if (group.size > 1) group.min + "-" + group.max else group.head.toString)
}
val in = "108,109,110,112,114,115,116,118"
val result = combineConsecutive(in)
println(result) // List(108-110, 112, 114-116, 118)
}
This solution partly uses code from this question: Grouping list items by comparing them with their neighbors

Extract coefficients from binomial expression entered as a string in Scala

I am trying to write a program that can find the roots of a quadratic equation using Scala. The input should be a quadratic equation in the form ax^2+bx+c (e.g: 5x^2+2x+3) as a string.
I managed to code the calculation of the roots but am having trouble extracting the coefficients from the input. Here's the code I wrote for extracting the coefficients so far:
def getCoef(poly: String) = {
var aT: String = ""
var bT: String = ""
var cT: String = ""
var x: Int = 2
for (i <- poly.length - 1 to 0) {
val t: String = poly(i).toString
if (x == 2) {
if (t forall Character.isDigit) aT = aT + t(i)
else if (t == "^") {i = i + 1; x = 1}
}
else if (x == 1) {
if (t forall Character.isDigit) bT = bT + t(i)
else if (t == "+" || t == "-") x = 0
}
else if (x == 0) {
if (t forall Character.isDigit) cT = cT + t(i)
}
val a: Int = aT.toInt
val b: Int = bT.toInt
val c: Int = cT.toInt
(a, b, c)
}
}
Simple solution with regex:
def getCoef(poly: String) = {
val polyPattern = """(\d+)x\^2\+(\d+)x\+(\d+)""".r
val matcher = polyPattern.findFirstMatchIn(poly).get
(matcher.group(1).toInt, matcher.group(2).toInt, matcher.group(3).toInt)
}
Does not handle all cases (e.g.: minus) and just throws an error if the input does not match the pattern, but it should get you going.

How do you memoization with cases in Scala?

What is the best way to convert this code which uses memoization into proper Scala using cases and functional programming?
def uniquePathsMemoization(n:Int, m:Int, row:Int, col:Int, seen:Array[Array[Int]]):Int = {
if (row == m && col == n) 1
if (row > m || col > n) 0
if (seen(row+1)(col) == -1) seen(row+1)(col) = uniquePathsMemoization(n, m, row + 1, col, seen)
if (seen(row)(col + 1) == -1 ) seen(row)(col) = uniquePathsMemoization(n,m, row, col + 1, seen)
seen(row+1)(col) + seen(row)(col + 1)
}
This is a modified version of your code that uses match and case
def uniquePathsMemoization(n:Int, m:Int, row:Int, col:Int, seen:Array[Array[Int]]):Int = (row,col) match{
case (row,col) if row == m && col == n =>
1
case (row,col) if row > m || col > n =>
0
case (row,col) =>
if (seen(row+1)(col) == -1) seen(row+1)(col) = uniquePathsMemoization(n, m, row + 1, col, seen)
if (seen(row)(col + 1) == -1 ) seen(row)(col) = uniquePathsMemoization(n,m, row, col + 1, seen)
seen(row+1)(col) + seen(row)(col + 1)
}
It is not easy to convert this code to a pure functional version, due to the state stored in the seen array. But this state can be hidden for the rest of the application, using a function decorator:
def uniquePathsMemoizationGenerator( maxRows: Int, maxCols:Int ) : (Int,Int,Int,Int) => Int = {
def uniquePathsMemoization(n:Int, m:Int, row:Int, col:Int, seen:Array[Array[Int]]):Int = (row,col) match{
case (row,col) if row == m && col == n =>
1
case (row,col) if row > m || col > n =>
0
case (row,col) =>
if (seen(row+1)(col) == -1) seen(row+1)(col) = uniquePathsMemoization(n, m, row + 1, col, seen)
if (seen(row)(col + 1) == -1 ) seen(row)(col) = uniquePathsMemoization(n,m, row, col + 1, seen)
seen(row+1)(col) + seen(row)(col + 1)
}
val seen = Array.fill(maxRows,maxCols)(-1)
uniquePathsMemoization(_,_,_,_,seen)
}
val maxRows = ???
val maxCols = ???
val uniquePaths = uniquePathsMemoizationGenerator( maxRows, maxCols )
// Use uniquePaths from this point, instead of uniquePathsMemoization

Scala Branch And Bound Motif Search

Below code searches for a motif (of length 8) in a sequence(String) and, as the result, it has to give back sequence with the best score. The problem is, although the code produces no errors, there is no output at all (probably infinite cycle, I observe blank console).
I am gonna give all my code online and if that is required. In order to reproduce the problem, just pass a number (between 0 and 3 - you can give 4 sequence, so you must choose 1 of them 0 is the first , 1 is the second etc) as args(0) (e.g. "0"), expected output should look something like "Motif = ctgatgta"
import scala.util.control._
object BranchAndBound {
var seq: Array[String] = new Array[String](20)
var startPos: Array[Int] = new Array[Int](20)
var pickup: Array[String] = new Array[String](20)
var bestMotif: Array[Int] = new Array[Int](20)
var ScoreMatrix = Array.ofDim[Int](5, 20)
var i: Int = _
var j: Int = _
var lmer: Int = _
var t: Int = _
def main(args: Array[String]) {
var t1: Long = 0
var t2: Long = 0
t1 = 0
t2 = 0
t1 = System.currentTimeMillis()
val seq0 = Array(
Array(
" >5 regulatory reagions with 69 bp",
" cctgatagacgctatctggctatccaggtacttaggtcctctgtgcgaatctatgcgtttccaaccat",
" agtactggtgtacatttgatccatacgtacaccggcaacctgaaacaaacgctcagaaccagaagtgc",
" aaacgttagtgcaccctctttcttcgtggctctggccaacgagggctgatgtataagacgaaaatttt",
" agcctccgatgtaagtcatagctgtaactattacctgccacccctattacatcttacgtccatataca",
" ctgttatacaacgcgtcatggcggggtatgcgttttggtcgtcgtacgctcgatcgttaccgtacggc"),
Array(
" 2 columns mutants",
" cctgatagacgctatctggctatccaggtacttaggtcctctgtgcgaatctatgcgtttccaaccat",
" agtactggtgtacatttgatccatacgtacaccggcaacctgaaacaaacgctcagaaccagaagtgc",
" aaacgttagtgcaccctctttcttcgtggctctggccaacgagggctgatgtataagacgaaaattttt",
" agcctccgatgtaagtcatagctgtaactattacctgccacccctattacatcttacgtccatataca",
" ctgttatacaacgcgtcatggcggggtatgcgttttggtcgtcgtacgctcgatcgttaccgtacggc"),
Array(
" 2 columns mutants",
" cctgatagacgctatctggctatccaggtacttaggtcctctgtgcgaatctatgcgtttccaaccat",
" agtactggtgtacatttgatccatacgtacaccggcaacctgaaacaaacgctcagaaccagaagtgc",
" aaacgttagtgcaccctctttcttcgtggctctggccaacgagggctgatgtataagacgaaaattttt",
" agcctccgatgtaagtcatagctgtaactattacctgccacccctattacatcttacgtccatataca",
" ctgttatacaacgcgtcatggcggggtatgcgttttggtcgtcgtacgctcgatcgttaccgtacggc"),
Array(
" 2 columns mutants",
" cctgatagacgctatctggctatccaggtacttaggtcctctgtgcgaatctatgcgtttccaaccat",
" agtactggtgtacatttgatccatacgtacaccggcaacctgaaacaaacgctcagaaccagaagtgc",
" aaacgttagtgcaccctctttcttcgtggctctggccaacgagggctgatgtataagacgaaaattttt",
" agcctccgatgtaagtcatagctgtaactattacctgccacccctattacatcttacgtccatataca",
" ctgttatacaacgcgtcatggcggggtatgcgttttggtcgtcgtacgctcgatcgttaccgtacggc"))
var k: Int = 0
var m: Int = 0
var n: Int = 0
var bestScore: Int = 0
var optScore: Int = 0
var get: Int = 0
var ok1: Boolean = false
var ok3: Boolean = false
ok1 = false
ok3 = false
j = 1
lmer = 8
m = 1
t = 5
n = 69
optScore = 0
bestScore = 0
k = java.lang.Integer.parseInt(args(0))
j = 1
while (j <= t) {
seq(j) = new String()
i = 0
while (i < n) {
seq(j) += seq0(k)(j).charAt(i)
i += 1
}
j += 1
}
j = 1
while (j <= t) {
newPickup(1, j)
j += 1
}
j = 0
bestScore = 0
i = 1
val whilebreaker = new Breaks
whilebreaker.breakable {
while (i > 0) {
if (i < t) {
if (startPos(1) == (n - lmer)) whilebreaker.break
val sc = Score()
optScore = sc + (t - i) * lmer
if (optScore < bestScore) {
ok1 = false
j = i
val whilebreak1 = new Breaks
whilebreak1.breakable {
while (j >= 1) {
if (startPos(j) < n - lmer) {
ok1 = true
newPickup(0, j)
whilebreak1.break
} else {
ok1 = true
newPickup(1, j)
val whilebreak2 = new Breaks
whilebreak2.breakable {
while (startPos(i - 1) == (n - lmer)) {
newPickup(1, i - 1)
i -= 1
if (i == 0) whilebreak2.break
}
}
if (i > 1) {
newPickup(0, i - 1)
i -= 1
}
whilebreak1.break
}
}
}
if (ok1 == false) i = 0
} else {
newPickup(1, i + 1)
i += 1
}
} else {
get = Score()
if (get > bestScore) {
bestScore = get
m = 1
while (m <= t) {
bestMotif(m) = startPos(m)
m += 1
}
}
ok3 = false
j = t
val whilebreak3 = new Breaks
whilebreak3.breakable {
while (j >= 1) {
if (startPos(j) < n - lmer) {
ok3 = true
newPickup(0, j)
whilebreak3.break
} else {
ok3 = true
newPickup(1, j)
val whilebreak4 = new Breaks
whilebreak4.breakable {
while (startPos(i - 1) == (n - lmer)) {
newPickup(1, i - 1)
i -= 1
if (i == 0) whilebreak4.break
}
}
if (i > 1) {
newPickup(0, i - 1)
i -= 1
}
whilebreak3.break
}
}
}
if (ok3 == false) i = 0
}
}
}
println("Motiv: " + Consensus())
// println()
j = 1
while (j <= t) {
t2 = System.currentTimeMillis()
j += 1
}
println("time= " + (t2 - t1) + " ms")
}
def Score(): Int = {
var j: Int = 0
var k: Int = 0
var m: Int = 0
var max: Int = 0
var sum: Int = 0
sum = 0
max = 0
m = 1
while (m <= lmer) {
k = 1
while (k <= 4) {
ScoreMatrix(k)(m) = 0
k += 1
}
m += 1
}
m = 1
while (m <= lmer) {
k = 1
while (k <= i) pickup(k).charAt(m) match {
case 'a' => ScoreMatrix(1)(m) += 1
case 'c' => ScoreMatrix(2)(m) += 1
case 'g' => ScoreMatrix(3)(m) += 1
case 't' => ScoreMatrix(4)(m) += 1
}
m += 1
}
j = 1
while (j <= lmer) {
max = 0
m = 1
while (m <= 4) {
if (ScoreMatrix(m)(j) > max) {
max = ScoreMatrix(m)(j)
}
m += 1
}
sum += max
j += 1
}
sum
}
def Consensus(): String = {
var i: Int = 0
var j: Int = 0
var k: Int = 0
var m: Int = 0
var max: Int = 0
var imax: Int = 0
var str: String = null
i = 1
while (i <= t) {
pickup(i) = " " +
seq(i).substring(bestMotif(i), bestMotif(i) + lmer)
i += 1
}
m = 1
while (m <= lmer) {
k = 1
while (k <= 4) {
ScoreMatrix(k)(m) = 0
k += 1
}
m += 1
}
m = 1
while (m <= lmer) {
k = 1
while (k <= t) pickup(k).charAt(m) match {
case 'a' => ScoreMatrix(1)(m) += 1
case 'c' => ScoreMatrix(2)(m) += 1
case 'g' => ScoreMatrix(3)(m) += 1
case 't' => ScoreMatrix(4)(m) += 1
}
m += 1
}
str = ""
imax = 0
j = 1
while (j <= lmer) {
max = 0
i = 1
while (i <= 4) {
if (ScoreMatrix(i)(j) > max) {
max = ScoreMatrix(i)(j)
imax = i
}
i += 1
}
imax match {
case 1 => str += 'a'
case 2 => str += 'c'
case 3 => str += 'g'
case 4 => str += 't'
}
j += 1
}
str
}
def newPickup(one: Int, h: Int) {
if (one == 1) startPos(h) = 1 else startPos(h) += 1
pickup(h) = " " + seq(h).substring(startPos(h), startPos(h) + lmer)
}
}
and thanks, i hope someone gonna find my failure.
Your current implementation 'hangs' on this loop:
while (k <= i) pickup(k).charAt(m) match {
case 'a' => ScoreMatrix(1)(m) += 1
case 'c' => ScoreMatrix(2)(m) += 1
case 'g' => ScoreMatrix(3)(m) += 1
case 't' => ScoreMatrix(4)(m) += 1
}
As it stands, the exit condition is never fulfilled because the relation between k and i never changes. Either increment k or decrement i.
It looks like programming is not the key aspect of this work, but increased modularity should help contain complexity.
Also, I wonder about the choice of using Scala. There're many areas in this algorithm that would benefit of a more functional approach. In this translation, using Scala in an imperative way gets cumbersome. If you have the opportunity, I'd recommend you to explore a more functional approach to solve this problem.
A tip: The intellij debugger didn't have issues with this code.