From 5ae6b3215f182d38f5cfe1babeb9b59efbdec108 Mon Sep 17 00:00:00 2001 From: Maxim Kachinkin Date: Wed, 14 May 2025 18:43:23 +0300 Subject: [PATCH 1/2] 1st part of the HW --- .../otus/homework/flowcats/CatsViewModel.kt | 17 ++++++++++++----- .../otus/homework/flowcats/MainActivity.kt | 19 +++++++++++++++++-- .../java/otus/homework/flowcats/Result.kt | 6 ++++++ 3 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 flowcats/src/main/java/otus/homework/flowcats/Result.kt diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt index ec7cc1ea..796a841b 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt @@ -1,7 +1,10 @@ package otus.homework.flowcats -import androidx.lifecycle.* +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewModelScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -10,14 +13,18 @@ class CatsViewModel( private val catsRepository: CatsRepository ) : ViewModel() { - private val _catsLiveData = MutableLiveData() - val catsLiveData: LiveData = _catsLiveData + val cats = MutableStateFlow(Result.Success(Fact("", 0))) init { viewModelScope.launch { withContext(Dispatchers.IO) { - catsRepository.listenForCatFacts().collect { - _catsLiveData.value = it + try { + catsRepository.listenForCatFacts() + .collect { + cats.value = Result.Success(it) + } + } catch (t: Throwable) { + cats.value = Result.Error } } } diff --git a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt index edea434b..392c2789 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt @@ -2,7 +2,11 @@ package otus.homework.flowcats import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.widget.Toast import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch class MainActivity : AppCompatActivity() { @@ -14,8 +18,19 @@ class MainActivity : AppCompatActivity() { val view = layoutInflater.inflate(R.layout.activity_main, null) as CatsView setContentView(view) - catsViewModel.catsLiveData.observe(this){ - view.populate(it) + lifecycleScope.launch { + catsViewModel.cats.collect { + when (it) { + Result.Error -> { + Toast.makeText(this@MainActivity, "Error", Toast.LENGTH_SHORT).show() + } + is Result.Success<*> -> { + if (it.res is Fact) { + view.populate(it.res) + } + } + } + } } } } \ No newline at end of file diff --git a/flowcats/src/main/java/otus/homework/flowcats/Result.kt b/flowcats/src/main/java/otus/homework/flowcats/Result.kt new file mode 100644 index 00000000..a0a0e03d --- /dev/null +++ b/flowcats/src/main/java/otus/homework/flowcats/Result.kt @@ -0,0 +1,6 @@ +package otus.homework.flowcats + +sealed class Result { + data class Success(val res: T): Result() + data object Error: Result() +} \ No newline at end of file From 653402dfa5ec6902ff6849b2b50b26ba038cffa8 Mon Sep 17 00:00:00 2001 From: Maxim Kachinkin Date: Wed, 14 May 2025 19:45:47 +0300 Subject: [PATCH 2/2] 2nd part of the HW --- .../otus/homework/flow/SampleInteractor.kt | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/operators/src/main/java/otus/homework/flow/SampleInteractor.kt b/operators/src/main/java/otus/homework/flow/SampleInteractor.kt index 1993c064..e0904abd 100644 --- a/operators/src/main/java/otus/homework/flow/SampleInteractor.kt +++ b/operators/src/main/java/otus/homework/flow/SampleInteractor.kt @@ -18,7 +18,12 @@ class SampleInteractor( * 6) возвращает результат */ fun task1(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .map { it * 5 } + .filter { it > 20 } + .filter { it % 2 != 0 } + .map { "$it won" } + .take(3) } /** @@ -29,7 +34,19 @@ class SampleInteractor( * Если число не делится на 3,5,15 - эмитим само число */ fun task2(): Flow { - return flowOf() + return flow { + sampleRepository.produceNumbers().collect { num -> + val results = when { + num % 15 == 0 -> listOf("$num", "FizzBuzz") + num % 3 == 0 -> listOf("$num", "Fizz") + num % 5 == 0 -> listOf("$num", "Buzz") + else -> listOf("$num") + } + for (item in results) { + emit(item) + } + } + } } /** @@ -38,7 +55,18 @@ class SampleInteractor( * Если айтемы в одно из флоу кончились то результирующий флоу также должен закончится */ fun task3(): Flow> { - return flowOf() + return flow { + val colors = mutableListOf() + val forms = mutableListOf() + + sampleRepository.produceColors().collect { colors.add(it) } + sampleRepository.produceForms().collect { forms.add(it) } + + val size = minOf(colors.size, forms.size) + for (i in 0 until size) { + emit(colors[i] to forms[i]) + } + } } /** @@ -48,6 +76,11 @@ class SampleInteractor( * При любом исходе, будь то выброс исключения или успешная отработка функции вызовите метод dotsRepository.completed() */ fun task4(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .catch { cause: Throwable -> + if (cause is IllegalArgumentException) emit(-1) + else throw cause + } + .onCompletion { sampleRepository.completed() } } } \ No newline at end of file