From df5676a8c9322f27c7323b545ddcd8b3cfca1390 Mon Sep 17 00:00:00 2001 From: YURY TILMAN Date: Wed, 22 Apr 2026 20:11:56 +0300 Subject: [PATCH 1/2] First task implement --- .../otus/homework/flowcats/CatsRepository.kt | 9 ++++++-- .../otus/homework/flowcats/CatsViewModel.kt | 20 +++++++++--------- .../otus/homework/flowcats/MainActivity.kt | 21 ++++++++++++++++--- .../java/otus/homework/flowcats/Result.kt | 7 +++++++ 4 files changed, 42 insertions(+), 15 deletions(-) create mode 100644 flowcats/src/main/java/otus/homework/flowcats/Result.kt diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt index 10fcb77d..acc9b9db 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt @@ -2,6 +2,7 @@ package otus.homework.flowcats import kotlinx.coroutines.delay import kotlinx.coroutines.flow.flow +import java.lang.Exception class CatsRepository( private val catsService: CatsService, @@ -10,8 +11,12 @@ class CatsRepository( fun listenForCatFacts() = flow { while (true) { - val latestNews = catsService.getCatFact() - emit(latestNews) + try { + val latestNews = catsService.getCatFact() + emit(Result.Success(latestNews)) + } catch (e: Exception) { + emit(Result.Error(e.message ?: "Unknown error")) + } delay(refreshIntervalMs) } } diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt index 0d8ba8a7..553c308b 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt @@ -1,24 +1,24 @@ package otus.homework.flowcats -import androidx.lifecycle.* -import kotlinx.coroutines.Dispatchers +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext class CatsViewModel( private val catsRepository: CatsRepository ) : ViewModel() { - private val _catsLiveData = MutableLiveData() - val catsLiveData: LiveData = _catsLiveData + private val _catsFlow = MutableStateFlow>(Result.Loading) + val catsFlow = _catsFlow.asStateFlow() init { viewModelScope.launch { - withContext(Dispatchers.IO) { - catsRepository.listenForCatFacts().collect { - _catsLiveData.value = it - } + catsRepository.listenForCatFacts().collect { + _catsFlow.value = it } } } @@ -26,6 +26,6 @@ class CatsViewModel( class CatsViewModelFactory(private val catsRepository: CatsRepository) : ViewModelProvider.NewInstanceFactory() { - override fun create(modelClass: Class): T = + override fun create(modelClass: Class): T = CatsViewModel(catsRepository) as T } \ No newline at end of file diff --git a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt index edea434b..6e6b8765 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt @@ -1,8 +1,11 @@ package otus.homework.flowcats -import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.widget.Toast import androidx.activity.viewModels +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.flow.collect class MainActivity : AppCompatActivity() { @@ -14,8 +17,20 @@ class MainActivity : AppCompatActivity() { val view = layoutInflater.inflate(R.layout.activity_main, null) as CatsView setContentView(view) - catsViewModel.catsLiveData.observe(this){ - view.populate(it) + lifecycleScope.launchWhenStarted { + catsViewModel.catsFlow.collect { result -> + when (result) { + is Result.Success -> view.populate(result.data) + is Result.Error -> Toast.makeText( + this@MainActivity, + result.message, + Toast.LENGTH_LONG + ).show() + + Result.Loading -> { /* Handle loading state if needed */ + } + } + } } } } \ 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..d92c37c9 --- /dev/null +++ b/flowcats/src/main/java/otus/homework/flowcats/Result.kt @@ -0,0 +1,7 @@ +package otus.homework.flowcats + +sealed class Result { + object Loading : Result() + data class Success(val data: T) : Result() + data class Error(val message: String) : Result() +} \ No newline at end of file From 4dbb58039b4d47df669ed3255a0a3574fcf79272 Mon Sep 17 00:00:00 2001 From: YURY TILMAN Date: Wed, 22 Apr 2026 20:16:11 +0300 Subject: [PATCH 2/2] Second task implement --- .../otus/homework/flow/SampleInteractor.kt | 43 +++++++++++++++++-- 1 file changed, 39 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..f90a66d3 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,24 @@ class SampleInteractor( * Если число не делится на 3,5,15 - эмитим само число */ fun task2(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .transform { value -> + when { + value % 15 == 0 -> { + emit(value.toString()) + emit("FizzBuzz") + } + value % 5 == 0 -> { + emit(value.toString()) + emit("Buzz") + } + value % 3 == 0 -> { + emit(value.toString()) + emit("Fizz") + } + else -> emit(value.toString()) + } + } } /** @@ -38,7 +60,10 @@ class SampleInteractor( * Если айтемы в одно из флоу кончились то результирующий флоу также должен закончится */ fun task3(): Flow> { - return flowOf() + return sampleRepository.produceColors() + .zip(sampleRepository.produceForms()) { color, form -> + color to form + } } /** @@ -48,6 +73,16 @@ class SampleInteractor( * При любом исходе, будь то выброс исключения или успешная отработка функции вызовите метод dotsRepository.completed() */ fun task4(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .catch { e -> + if (e is IllegalArgumentException) { + emit(-1) + } else { + throw e + } + } + .onCompletion { + sampleRepository.completed() + } } } \ No newline at end of file