diff --git a/assignments/03/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/DataAnalysis.kt b/assignments/03/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/DataAnalysis.kt index 3416c333..8bf0a97a 100644 --- a/assignments/03/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/DataAnalysis.kt +++ b/assignments/03/src/main/kotlin/io/rybalkinsd/kotlinbootcamp/DataAnalysis.kt @@ -1,5 +1,9 @@ package io.rybalkinsd.kotlinbootcamp +import java.util.Random + +fun LongRange.random() = Random().nextInt((endInclusive.toInt() + 1) - start.toInt()) + start + class RawProfile(val rawData: String) enum class DataSource { @@ -8,92 +12,133 @@ enum class DataSource { LINKEDIN } -sealed class Profile( - var id: Long, - var firstName: String? = null, - var lastName: String? = null, - var age: Int? = null, - var dataSource: DataSource -) - -/** - * Task #1 - * Declare classes for all data sources - */ -class FacebookProfile(id: Long) : Profile(dataSource = DataSource.FACEBOOK, id = id) - -/** - * Task #2 - * Find the average age for each datasource (for profiles that has age) - * - * TODO - */ -val avgAge: Map = emptyMap() - -/** - * Task #3 - * Group all user ids together with all profiles of this user. - * We can assume users equality by : firstName & lastName & age - * - * TODO - */ -val groupedProfiles: Map> = emptyMap() - /** * Here are Raw profiles to analyse */ val rawProfiles = listOf( - RawProfile(""" - fisrtName=alice, + RawProfile(""" + firstName=alice, age=16, source=facebook """.trimIndent() - ), - RawProfile(""" - fisrtName=Dent, + ), + RawProfile(""" + firstName=Dent, lastName=kent, age=88, source=linkedin """.trimIndent() - ), - RawProfile(""" - fisrtName=alla, + ), + RawProfile(""" + firstName=alla, lastName=OloOlooLoasla, source=vk """.trimIndent() - ), - RawProfile(""" - fisrtName=bella, + ), + RawProfile(""" + firstName=bella, age=36, source=vk """.trimIndent() - ), - RawProfile(""" - fisrtName=angel, + ), + RawProfile(""" + firstName=angel, age=I will not tell you =), source=facebook """.trimIndent() - ), - - RawProfile( - """ + ), + RawProfile( + """ lastName=carol, - source=vk + source=vk, age=49, """.trimIndent() - ), - RawProfile(""" - fisrtName=bob, + ), + RawProfile(""" + firstName=bob, lastName=John, age=47, source=linkedin """.trimIndent() - ), - RawProfile(""" + ), + RawProfile(""" lastName=kent, - fisrtName=dent, + firstName=dent, age=88, source=facebook """.trimIndent() - ) + ), + RawProfile(""" + firstName=Dent, + lastName=kent, + age=88, + source=vk + """.trimIndent() + ), + RawProfile(""" + source=linkedin + """.trimIndent() + ) ) + +sealed class Profile( + var id: Long, + var firstName: String? = null, + var lastName: String? = null, + var age: Int? = null, + var dataSource: DataSource +) { + override fun toString(): String { + return "Profile(id=$id, firstName=$firstName, lastName=$lastName, age=$age, dataSource=$dataSource)" + } +} + +/** + * Returns a list containing Profiles from RawProfile's data + */ +fun rawProfilesParse(source: List): List = source.map { + var t = when (it.rawData.substringAfter("source=").substringBefore(",").toUpperCase()) { + "LINKEDIN" -> LinkedInProfile((0L..100000L).random()) + "VK" -> VKProfile((0L..100000L).random()) + "FACEBOOK" -> FacebookProfile((0L..100000L).random()) + else -> throw Exception("Error in profile source") + } + if (it.rawData.contains("firstName")) t.firstName = it.rawData.substringAfter("firstName=").substringBefore(",").capitalize() + if (it.rawData.contains("lastName")) t.lastName = it.rawData.substringAfter("lastName=").substringBefore(",").capitalize() + try { + if (it.rawData.contains("age")) t.age = it.rawData.substringAfter("age=").substringBefore(",").toInt() + } catch (e: Exception) {} + t +} + +val profiles = rawProfilesParse(rawProfiles) +/** + * Task #1 + * Declare classes for all data sources + */ +class FacebookProfile(id: Long) : Profile(dataSource = DataSource.FACEBOOK, id = id) +class VKProfile(id: Long) : Profile(dataSource = DataSource.VK, id = id) +class LinkedInProfile(id: Long) : Profile(dataSource = DataSource.LINKEDIN, id = id) +/** + * Task #2 + * Find the average age for each datasource (for profiles that has age) + * + * In case when no age in all profiles - result is NaN + */ +val avgAge: Map = avg(profiles) + +fun avg(src: List): Map = src.groupBy({ it.dataSource }, { it.age ?: 0 }).map { + it.key to (it.value.filter { it != 0 }.sum().toDouble() / it.value.filter { it != 0 }.size) + }.toMap() + +/** + * Task #3 + * Group all user ids together with all profiles of this user. + * We can assume users equality by : firstName & lastName & age + * + * + */ +val groupedProfiles: Map> = groupProfiles(profiles) + +fun groupProfiles(src: List): Map> = src.groupBy { + it.age.toString() + it.lastName + it.firstName }.values.associateBy { (0L..1000000L).random() } \ No newline at end of file diff --git a/assignments/03/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/DataAnalysisTest.kt b/assignments/03/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/DataAnalysisTest.kt index 82961d30..8ad743cd 100644 --- a/assignments/03/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/DataAnalysisTest.kt +++ b/assignments/03/src/test/kotlin/io/rybalkinsd/kotlinbootcamp/DataAnalysisTest.kt @@ -1,13 +1,14 @@ package io.rybalkinsd.kotlinbootcamp +import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertTrue import org.junit.Test - class DataAnalysisTest { @Test fun `check avg age`() { + assertEquals(52.0, avgAge[DataSource.FACEBOOK]) assertTrue(avgAge.isNotEmpty()) }