Skip to content

Commit

Permalink
Merge pull request #16 from jetbrains-academy/refactor-old-school
Browse files Browse the repository at this point in the history
Refactor the old school project
  • Loading branch information
nbirillo authored Sep 9, 2023
2 parents cdf8aad + 425649c commit 281508c
Show file tree
Hide file tree
Showing 22 changed files with 243 additions and 56 deletions.
1 change: 1 addition & 0 deletions course-info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ summary: |-
programming_language: Kotlin
content:
- duckShopServer
- oldSchoolServer
environment_settings:
jvm_language_level: JDK_17
2 changes: 1 addition & 1 deletion oldSchoolFrontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"axios": "^0.27.2",
"common-types": "file:common/build/libs/common-types",
"common-types": "file:/Users/anastasia.birillo/IdeaProjects/kotlin-onboarding-part3/common/build/dist",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "^2.1.3",
Expand Down
3 changes: 2 additions & 1 deletion oldSchoolServer/lesson-info.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
type: framework
custom_name: Old school
content:
- oldSchoolServerIntroduction
- oldSchoolServerIntroduction
- oldSchoolServerFinishGame
is_template_based: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.jetbrains.kotlin.course.old.school

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class OldSchoolApplication

@Suppress("SpreadOperator")
fun main(args: Array<String>) {
runApplication<OldSchoolApplication>(*args)
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.jetbrains.kotlin.course.old.school.functions

import org.springframework.web.bind.annotation.*

// We can not use a typealias here because the Spring framework can not parse it
class Characters : ArrayList<String>()
class Body (
val names: Characters,
val color: String
)

@RestController
@RequestMapping("/api/functions/")
class GameFunctionsResource(val service: GameFunctionsService) {
@CrossOrigin
@GetMapping("/colors")
fun getAllPossibleColors(): List<String> = service.getAllPossibleColors()

@CrossOrigin
@PostMapping("/find")
fun findPhoto(@RequestBody body: Body): String? = with(service) {
body.names.findPhoto(body.color)?.name?.lowercase()
}

@CrossOrigin
@PostMapping("/groupByByColor")
fun groupByPhotosByColor(@RequestBody names: List<String>): List<String> = with(service) {
names.groupPhotosByColor().map { it.name }
}

@CrossOrigin
@PostMapping("/groupByPhotosByHairAndHat")
fun groupByPhotosByHairAndHat(@RequestBody names: List<String>): List<String> = with(service) {
names.groupPhotosByHairAndHat().map { it.name }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.jetbrains.kotlin.course.old.school.functions

import org.jetbrains.kotlin.course.old.school.photo.Accessory
import org.jetbrains.kotlin.course.old.school.photo.Color
import org.jetbrains.kotlin.course.old.school.photo.PhotoCharacter
import org.springframework.stereotype.Service

@Service
class GameFunctionsService {
fun getAllPossibleColors() = Color.entries.map { it.name.lowercase() }

private fun String.toColor() = Color.valueOf(replaceFirstChar { it.titlecase() })

private fun Iterable<String>.toPhotoCharacters() =
map { name -> PhotoCharacter.valueOf(name.replaceFirstChar { it.titlecase() }) }

fun Iterable<String>.findPhoto(colorStr: String): PhotoCharacter? {
val color = colorStr.toColor()
return toPhotoCharacters().find { it.backgroundColor == color }
}

fun Iterable<String>.groupPhotosByColor() = toPhotoCharacters()
.groupBy { it.backgroundColor }.map { it.value }.flatten()

fun Iterable<String>.groupPhotosByHairAndHat() = toPhotoCharacters()
.groupBy { it.hairType }
.mapValues { it.value.groupBy { character ->
character.accessories?.contains(Accessory.Hat) ?: false
}
}.values.flatMap { it.values }
.flatten()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.jetbrains.kotlin.course.old.school.mode

import old.school.JsPhoto
import org.springframework.web.bind.annotation.CrossOrigin
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/mode/")
class CardResource(val service: GameModeService) {
@CrossOrigin
@GetMapping("/list")
fun generateListOfCharacters(): List<JsPhoto> = service.generateListOfCharacters().map { JsPhoto(it.name) }

@CrossOrigin
@GetMapping("/set")
fun generateSetOfCharacters(): List<JsPhoto> = service.generateSetOfCharacters().map { JsPhoto(it.name) }

@CrossOrigin
@GetMapping("/map")
fun generateMapOfCharacters(): List<JsPhoto> = service.generateMapOfCharacters().map { JsPhoto(it.key.name, it.value) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.jetbrains.kotlin.course.old.school.mode

import org.jetbrains.kotlin.course.old.school.photo.PhotoCharacter
import org.springframework.stereotype.Service

@Service
class GameModeService {
companion object {
const val MAX_NUMBER_OF_PHOTOS = 12
}
private fun generateRandomCharacter() = PhotoCharacter.entries.random()

fun generateListOfCharacters() = List(MAX_NUMBER_OF_PHOTOS) { generateRandomCharacter() }

// It is better to move common code into a separated function
private fun getRandomCharacters() = PhotoCharacter.entries.shuffled().take(MAX_NUMBER_OF_PHOTOS)

fun generateSetOfCharacters() = getRandomCharacters().toSet()

fun generateMapOfCharacters() = getRandomCharacters().associateWith { it.name }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.jetbrains.kotlin.course.old.school.photo

enum class PhotoCharacter(
val backgroundColor: Color,
val hairType: HairType,
val accessories: List<Accessory>? = null
) {
Olivia(Color.Purple, HairType.Dark),
Emily(Color.White, HairType.Dark, listOf(Accessory.Earrings, Accessory.Watch)),
Emma(Color.Yellow, HairType.Light),
Charlotte(Color.Pink, HairType.Dark, listOf(Accessory.Earrings, Accessory.Watch)),
Diana(Color.Orange, HairType.Light, listOf(Accessory.Earrings, Accessory.Watch)),
Alice(Color.Green, HairType.Light),
Helena(Color.Green, HairType.Light, listOf(Accessory.Pen)),
Evie(Color.Purple, HairType.Light, listOf(Accessory.Pen)),

Henry(Color.Pink, HairType.Dark, listOf(Accessory.Glasses)),
Daniel(Color.Purple, HairType.Dark, listOf(Accessory.Hat)),
Noah(Color.Blue, HairType.Dark, listOf(Accessory.Glasses, Accessory.Hat)),
David(Color.Gray, HairType.Dark, listOf(Accessory.Glasses, Accessory.Hat)),
Leo(Color.Purple, HairType.Dark, listOf(Accessory.Glasses, Accessory.Hat)),
Jamie(Color.Gray, HairType.Light, listOf(Accessory.Glasses)),
Larry(Color.Orange, HairType.Light, listOf(Accessory.Glasses)),
Thomas(Color.White, HairType.Light, listOf(Accessory.Hat)),
Oliver(Color.Blue, HairType.Light, listOf(Accessory.Hat)),
Edward(Color.White, HairType.Dark, listOf(Accessory.Glasses, Accessory.Hat))
;
}

enum class HairType {
Dark,
Light
;
}

enum class Color {
White,
Blue,
Orange,
Yellow,
Pink,
Purple,
Green,
Gray
;
}

enum class Accessory {
Glasses,
Earrings,
Watch,
Pen,
Hat
;
}
28 changes: 28 additions & 0 deletions oldSchoolServer/oldSchoolServerFinishGame/task-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
type: edu
files:
- name: test/Tests.kt
visible: false
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/OldSchoolApplication.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/photo/PhotoCharacter.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/mode/GameModeService.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/mode/GameModeResource.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/functions/GameFunctionsService.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/functions/GameFunctionsResource.kt
visible: true
- name: test/HairTypeTestClass.kt
visible: false
- name: test/ColorTestClass.kt
visible: false
- name: test/AccessoryTestClass.kt
visible: false
- name: test/GameModeServiceTestClass.kt
visible: false
- name: test/PhotoCharacterTestClass.kt
visible: false
- name: test/GameFunctionsServiceTestClass.kt
visible: false
10 changes: 10 additions & 0 deletions oldSchoolServer/oldSchoolServerFinishGame/task.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Tasks:

+ Add enum class: HairType, Color, Accessory
+ Implement generateRandomCharacter + generateListOfCharacters
+ Implement generateSetOfCharacters
+ Implement generateMapOfCharacters
+ Implement getAllPossibleColors
+ Implement toColor, toPhotoCharacters, findPhoto
+ Implement groupPhotosByColor
+ Implement groupPhotosByHairAndHat
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import org.springframework.stereotype.Service

@Service
class GameFunctionsService {
fun getAllPossibleColors() = Color.values().map { it.name.lowercase() }
fun getAllPossibleColors() = Color.entries.map { it.name.lowercase() }

private fun String.toColor() = Color.valueOf(replaceFirstChar { it.titlecase() })

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,14 @@ class GameModeService {
companion object {
const val MAX_NUMBER_OF_PHOTOS = 12
}
private fun generateRandomCharacter() = PhotoCharacter.values().random()
private fun generateRandomCharacter() = PhotoCharacter.entries.random()

fun generateListOfCharacters() = List(MAX_NUMBER_OF_PHOTOS) { generateRandomCharacter() }

fun generateSetOfCharacters(): Set<PhotoCharacter> {
val characters = mutableSetOf<PhotoCharacter>()
do {
characters.add(generateRandomCharacter())
} while (characters.size < MAX_NUMBER_OF_PHOTOS)
return characters
}
// It is better to move common code into a separated function
private fun getRandomCharacters() = PhotoCharacter.entries.shuffled().take(MAX_NUMBER_OF_PHOTOS)

fun generateMapOfCharacters(): Map<PhotoCharacter, String> {
val characters = mutableMapOf<PhotoCharacter, String>()
do {
val character = generateRandomCharacter()
characters.putIfAbsent(character, character.name)
} while (characters.size < MAX_NUMBER_OF_PHOTOS)
return characters
}
fun generateSetOfCharacters() = getRandomCharacters().toSet()

fun generateMapOfCharacters() = getRandomCharacters().associateWith { it.name }
}
41 changes: 14 additions & 27 deletions oldSchoolServer/oldSchoolServerIntroduction/task-info.yaml
Original file line number Diff line number Diff line change
@@ -1,28 +1,15 @@
type: edu
type: theory
custom_name: Old School - Introduction
files:
- name: test/Tests.kt
visible: false
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/OldSchoolApplication.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/photo/PhotoCharacter.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/mode/GameModeService.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/mode/GameModeResource.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/functions/GameFunctionsService.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/functions/GameFunctionsResource.kt
visible: true
- name: test/HairTypeTestClass.kt
visible: false
- name: test/ColorTestClass.kt
visible: false
- name: test/AccessoryTestClass.kt
visible: false
- name: test/GameModeServiceTestClass.kt
visible: false
- name: test/PhotoCharacterTestClass.kt
visible: false
- name: test/GameFunctionsServiceTestClass.kt
visible: false
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/OldSchoolApplication.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/photo/PhotoCharacter.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/mode/GameModeService.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/mode/GameModeResource.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/functions/GameFunctionsService.kt
visible: true
- name: src/main/kotlin/org/jetbrains/kotlin/course/old/school/functions/GameFunctionsResource.kt
visible: true
10 changes: 0 additions & 10 deletions oldSchoolServer/oldSchoolServerIntroduction/task.md
Original file line number Diff line number Diff line change
@@ -1,10 +0,0 @@
Tasks:

+ Add enum class: HairType, Color, Accessory
+ Implement generateRandomCharacter + generateListOfCharacters
+ Implement generateSetOfCharacters
+ Implement generateMapOfCharacters
+ Implement getAllPossibleColors
+ Implement toColor, toPhotoCharacters, findPhoto
+ Implement groupPhotosByColor
+ Implement groupPhotosByHairAndHat

0 comments on commit 281508c

Please sign in to comment.