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

Asked By: sasha199568

||

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

Answered By: sasha199568
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.