Converting Python code to Kotlin
Question:
I found code to generate n distinct colors. I took the code and made a class out of it
import colorsys
import itertools
from fractions import Fraction
class DistinctColorsGenerator:
def __init__(self):
self._bias = lambda x: (math.sqrt(x / 3) / Fraction(2, 3) + Fraction(1, 3)) / Fraction(6, 5)
self._gen_rgb = lambda x : colorsys.hsv_to_rgb(*x)
self._flatten = itertools.chain.from_iterable
self._hsvs = lambda: self._flatten(map(self._hsv, self._fracs()))
self._rgbs = lambda: map(self._gen_rgb, self._hsvs())
self._gen_colors = lambda: map(self._gen_color, self._rgbs())
def generate(self, number):
return list(itertools.islice(self._gen_colors(), number))
def _zenos_dichotomy(self):
for k in itertools.count():
yield Fraction(1, 2 ** k)
def _fracs(self):
yield 0
for k in self._zenos_dichotomy():
i = k.denominator
for j in range(1, i, 2):
yield Fraction(j, i)
def _hsv(self, h):
for s in [Fraction(6, 10)]:
for v in [Fraction(8, 10), Fraction(5, 10)]:
yield (h, s, v)
def _gen_color(self, x):
uint8tuple = map(lambda y: int(y * 255), x)
return list(uint8tuple)
I want to convert this to Kotlin, and the problem is that most of my Kotlin experience (as well as Python) is writing ordinary boring code. Whereas it looks like this one solves the problem by generating an infinite sequence and evaluating it lazily. I can just look at the Python code, understand what is going on and write a simple and boring code. But before doing that I wanted to ask here whether someone could show how a similar thing can be implemented in Kotlin
Answers:
I read some documentation (as was suggested in the comments) and this is what I came up with (just in case someone will find that useful)
class DistinctColorsGenerator {
fun generate(number: Int): List<ColorRgb> = generateRgbs.take(number).toList()
private val genHsvs = buildSequence {
fractions.forEach { createHsvColors(it).forEach { yield(it) } }
}
private val generateRgbs = buildSequence {
genHsvs.forEach { yield(it.toRgb()) }
}
private val zenosDichotomy = buildSequence {
var d = 1
while (true) {
yield(Fraction(1, d))
d *= 2
}
}
private val fractions = buildSequence {
yield(Fraction(0, 1))
zenosDichotomy.forEach {
val i = it.denominator.toInt()
for (j in 1 until i step 2) {
yield(Fraction(j, i))
}
}
}
private fun createHsvColors(h: Fraction<Int>) = buildSequence {
listOf(Fraction(6, 10)).forEach { s ->
listOf(Fraction(8, 10), Fraction(5, 10)).forEach { v ->
yield(ColorHsv(h, s, v))
}
}
}
}
Classes ColorRgb
, ColorHsv
, Fraction
are just data classes. ColorHsv.toRgb()
I took from here
I found code to generate n distinct colors. I took the code and made a class out of it
import colorsys
import itertools
from fractions import Fraction
class DistinctColorsGenerator:
def __init__(self):
self._bias = lambda x: (math.sqrt(x / 3) / Fraction(2, 3) + Fraction(1, 3)) / Fraction(6, 5)
self._gen_rgb = lambda x : colorsys.hsv_to_rgb(*x)
self._flatten = itertools.chain.from_iterable
self._hsvs = lambda: self._flatten(map(self._hsv, self._fracs()))
self._rgbs = lambda: map(self._gen_rgb, self._hsvs())
self._gen_colors = lambda: map(self._gen_color, self._rgbs())
def generate(self, number):
return list(itertools.islice(self._gen_colors(), number))
def _zenos_dichotomy(self):
for k in itertools.count():
yield Fraction(1, 2 ** k)
def _fracs(self):
yield 0
for k in self._zenos_dichotomy():
i = k.denominator
for j in range(1, i, 2):
yield Fraction(j, i)
def _hsv(self, h):
for s in [Fraction(6, 10)]:
for v in [Fraction(8, 10), Fraction(5, 10)]:
yield (h, s, v)
def _gen_color(self, x):
uint8tuple = map(lambda y: int(y * 255), x)
return list(uint8tuple)
I want to convert this to Kotlin, and the problem is that most of my Kotlin experience (as well as Python) is writing ordinary boring code. Whereas it looks like this one solves the problem by generating an infinite sequence and evaluating it lazily. I can just look at the Python code, understand what is going on and write a simple and boring code. But before doing that I wanted to ask here whether someone could show how a similar thing can be implemented in Kotlin
I read some documentation (as was suggested in the comments) and this is what I came up with (just in case someone will find that useful)
class DistinctColorsGenerator {
fun generate(number: Int): List<ColorRgb> = generateRgbs.take(number).toList()
private val genHsvs = buildSequence {
fractions.forEach { createHsvColors(it).forEach { yield(it) } }
}
private val generateRgbs = buildSequence {
genHsvs.forEach { yield(it.toRgb()) }
}
private val zenosDichotomy = buildSequence {
var d = 1
while (true) {
yield(Fraction(1, d))
d *= 2
}
}
private val fractions = buildSequence {
yield(Fraction(0, 1))
zenosDichotomy.forEach {
val i = it.denominator.toInt()
for (j in 1 until i step 2) {
yield(Fraction(j, i))
}
}
}
private fun createHsvColors(h: Fraction<Int>) = buildSequence {
listOf(Fraction(6, 10)).forEach { s ->
listOf(Fraction(8, 10), Fraction(5, 10)).forEach { v ->
yield(ColorHsv(h, s, v))
}
}
}
}
Classes ColorRgb
, ColorHsv
, Fraction
are just data classes. ColorHsv.toRgb()
I took from here