Skip to content

Commit 1d65b39

Browse files
committed
add exercise 9
1 parent 0874bac commit 1d65b39

File tree

8 files changed

+377
-0
lines changed

8 files changed

+377
-0
lines changed

.idea/runConfigurations/Run_All_tests_in_Execise_9.xml

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
882 KB
Loading
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package exercise9
2+
3+
/**
4+
* Interface for interacting with employee data.
5+
*/
6+
interface EmployeeApi {
7+
8+
/**
9+
* Finds and returns the employee with the highest salary.
10+
* @return The employee with the highest salary, or null if the list of employees is empty.
11+
*/
12+
fun findHighestPaidEmployee(): Employee?
13+
14+
/**
15+
* Retrieves the list of employees working in a specific department.
16+
* @param department The department for which to retrieve employees.
17+
* @return A list of employees working in the specified department.
18+
*/
19+
fun getEmployeesByDepartment(department: Department): List<Employee>
20+
21+
/**
22+
* Retrieves the list of employees with salaries within a specified range.
23+
* @param salaryRange The salary in the range.
24+
* @return A list of employees with salaries within the specified range.
25+
*/
26+
fun getEmployeesBySalaryRange(salaryRange: IntRange): List<Employee>
27+
28+
/**
29+
* Calculates and returns the average salary for a given department.
30+
* @param department The department for which to calculate the average salary.
31+
* @return The average salary for the specified department.
32+
*/
33+
fun calculateAverageSalaryByDepartment(department: Department): Double
34+
35+
/**
36+
* Finds and returns the most common skill across all employees.
37+
* @return the most common skills.
38+
*/
39+
fun findMostCommonSkill(): String
40+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package exercise9
2+
3+
import common.FileReader
4+
5+
fun parseEmployees(employeesCSVLines: List<String>): List<Employee> {
6+
TODO("Implement parsing of employees")
7+
}
8+
9+
fun newEmployeeApi(employees: List<Employee>): EmployeeApi {
10+
TODO("Instantiate EmployeeApi")
11+
}
12+
13+
fun main() {
14+
val employeesCSVLines = FileReader.readFileInResources("exercise9/employees.csv")
15+
val employees = parseEmployees(employeesCSVLines)
16+
17+
val employeeApi : EmployeeApi = newEmployeeApi(employees)
18+
}

src/main/kotlin/exercise9/README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
## Employee Portal Task
2+
3+
An entry CSV file [employees.csv](src/main/resources/exercise9/employees.csv) contains the list of employees with the following columns:
4+
5+
- Employee ID - the id of an employee
6+
- Name - name of an employee
7+
- Department - department in which employee works
8+
- Salary - salary of an employee
9+
- Skills - skill sets of an employee
10+
11+
### Task 1: Create entity classes.
12+
#### Points: 10
13+
14+
In [exercise9/models.kt](models.kt) file create the following classes:
15+
16+
- Create `Department` **data** class which has `departmentName: String` as a primary constructor property.
17+
- Create `EmployeeID` **inline value** class which has `id: String` as a primary constructor property.
18+
- Create `Employee` **data** class which has only a primary constructor with following properties:
19+
20+
- `employeeID` of type `EmployeeID`
21+
- `name` of type `String`
22+
- `department` of type `Department`
23+
- `salary` of type `Int`
24+
- `skills` of type `List<String>`
25+
26+
### Task 2: Parse the entry CSV file [employees.csv](src/main/resources/exercise9/employees.csv)
27+
#### Points: 10
28+
29+
Implement `exercise9.EmployeesRunnerKt.parseEmployees` function to parse the entry CSV file [employees.csv](src/main/resources/exercise9/employees.csv).
30+
As a result `exercise9.EmployeesRunnerKt.parseEmployees` function should return the list of employees (`List<Employee>`) listed in CSV file
31+
with their corresponding ids, names, departments, salaries and skills.
32+
33+
Columns in CSV file are split by comma character (`,`), and skills in skills colum are split by pipe character (`|`).
34+
35+
### Task 3: Create class `EmployeesPortal` and implement functions of `EmployeesApi` interface
36+
#### Total points: 40
37+
38+
### Task 3.1
39+
#### Points: 4
40+
Create class `EmployeesPortal` which has primary constructor with a `employees: List<Employee>` parameter.
41+
Class `EmployeesPortal` should implement `EmployeesApi` interface.
42+
To complete tasks Task 3.2 - Task 3.6, implement overridden `EmployeesApi` interface methods
43+
in the `EmployeesPortal` class.
44+
***Note***: Leverage Kotlin APIs on Collections such as `map`, `filter`, `flatmap`, etc to implement your solution.
45+
Implementing the solutions by not using these APIs will be accepted, but it will result in points deduction penalty.
46+
47+
### Task 3.2 Implement `EmployeeApi.getEmployeesByDepartment` function
48+
#### Points: 4
49+
50+
`exercise9.EmployeeApi.getEmployeesByDepartment` function should return all employees that
51+
work for the provided `Department`.
52+
53+
### Task 3.3 Implement `EmployeeApi.findHighestPaidEmployee` function
54+
#### Points: 8
55+
56+
`exercise9.EmployeeApi.findHighestPaidEmployee` function should return the employee with the highest salary.
57+
58+
59+
### Task 3.4 Implement `EmployeeApi.getEmployeesBySalaryRange` function
60+
#### Points: 8
61+
62+
`exercise9.EmployeeApi.getEmployeesBySalaryRange` function should return all employees that have salary withing provided salary range.
63+
64+
65+
### Task 3.5 Implement `EmployeeApi.calculateAverageSalaryByDepartment` function
66+
#### Points: 8
67+
68+
`exercise9.EmployeeApi.calculateAverageSalaryByDepartment` should return an average salary in the department.
69+
Average salary can be calculated by dividing total department's salary expense with the number of employees in the department.
70+
71+
72+
### Task 3.5 Implement `EmployeeApi.findMostCommonSkills` function
73+
#### Points: 8
74+
75+
`exercise9.EmployeeApi.findMostCommonSkills` should most common skill employees have.
76+
The Most common skill is the skill mentioned the most times in the [employees.csv](src/main/resources/exercise9/employees.csv) file.
77+
78+
## Verifying results
79+
To verify the correctness of the implementation, run the `Exercise 9/Run All Tests` run configuration from a drop-down menu
80+
![Run tests via Exercise9/Run All Tests run config.](doc/verify-implementation-by-running-tests.png)

src/main/kotlin/exercise9/models.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package exercise9
2+
3+
// TODO Implement Department entity from Task 1
4+
class Department
5+
6+
// TODO Implement EmployeeID entity from Task 1
7+
8+
// TODO Implement Employee entity from Task 1
9+
class Employee
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
Employee ID,Name,Department,Salary,Skills
2+
1,Kevin Johnson,HR,61851,Recruitment
3+
2,Amy Doe,Finance,58802,Financial Planning
4+
3,Kevin Rodriguez,Engineering,66029,Kotlin
5+
4,Amy Rodriguez,Engineering,62689,Java|Kotlin|Python
6+
5,Michael Johnson,Engineering,50740,Java|Python
7+
6,Kevin Adams,Engineering,80489,Kotlin|Java|Python
8+
7,Chris Wilson,Engineering,67981,Kotlin
9+
8,Amy Wang,Finance,70468,Financial Planning|Financial Reporting
10+
9,Chris Wang,Engineering,78657,Python|Java
11+
10,Amy Adams,HR,58847,Employee Relations|Performance Management|Training
12+
11,Sarah Wilson,HR,49281,Employee Relations
13+
12,John Wang,Engineering,60760,Python|Kotlin|Java
14+
13,Kevin Doe,Finance,65261,Financial Analysis
15+
14,Jane Johnson,HR,53340,Employee Relations
16+
15,Jane Davis,Finance,70197,Financial Reporting|Accounting|Investment Analysis
17+
16,Emily Wang,HR,58991,Training|Performance Management
18+
17,Alice Wilson,HR,54518,Performance Management
19+
18,Jane Lee,HR,54147,Performance Management|Recruitment
20+
19,David Taylor,HR,53150,Performance Management
21+
20,Alice Adams,Engineering,75188,Kotlin|Java
22+
21,David Wilson,Engineering,69053,Java
23+
22,Amy Taylor,Marketing,48566,Marketing Strategy|Content Writing
24+
23,Emily Smith,HR,48250,Training|Performance Management|Employee Relations
25+
24,Alice Lee,Finance,70400,Financial Planning
26+
25,Alice Rodriguez,HR,51001,Performance Management|Employee Relations
27+
26,Jane Rodriguez,HR,54553,Recruitment|Training
28+
27,Jane Brown,Marketing,56116,Content Writing|Marketing Strategy
29+
28,Emily Adams,Finance,67834,Financial Planning|Accounting|Investment Analysis
30+
29,Kevin Smith,HR,54821,Training|Recruitment|Employee Relations
31+
30,Amy Smith,Engineering,59064,Java|Python|Kotlin
32+
31,Chris Adams,HR,55017,Recruitment|Performance Management|Training
33+
32,Emily Wilson,Engineering,63142,Python
34+
33,Chris Rodriguez,Engineering,62649,Kotlin|Java
35+
34,Chris Taylor,Marketing,58124,Content Writing|Marketing Strategy
36+
35,David Smith,Engineering,63081,Kotlin|Python
37+
36,Alice Doe,Engineering,57117,Java|Kotlin|Python
38+
37,John Que,HR,58916,Employee Relations|Performance Management
39+
38,Kevin Lee,Engineering,72762,Java|Kotlin
40+
39,Alice Brown,Marketing,47119,Marketing Strategy
41+
40,Emily Doe,HR,61906,Performance Management|Employee Relations|Recruitment
42+
41,John Smith,Marketing,57781,Marketing Strategy|Content Writing
43+
42,Alice Smith,Engineering,77688,Python
44+
43,Jane Doe,Marketing,59216,Content Writing|Marketing Strategy
45+
44,Amy Wilson,Engineering,70026,Python|Kotlin
46+
45,Chris Doe,Marketing,45788,Content Writing|Marketing Strategy
47+
46,Jane Towns,HR,51963,Recruitment|Employee Relations|Training
48+
47,Sarah Lee,HR,54220,Recruitment
49+
48,David Doe,Engineering,69196,Python|Java
50+
49,Michael Lee,Engineering,65183,Kotlin
51+
50,Kevin Taylor,Marketing,57251,Marketing Strategy
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package exercise9
2+
3+
import common.FileReader
4+
import org.junit.jupiter.api.Test
5+
import kotlin.test.assertEquals
6+
7+
class EmployeeApiTest {
8+
private val employees = parseEmployees(FileReader.readFileInResources("exercise9/employees.csv"))
9+
private val employeeApi = newEmployeeApi(employees)
10+
11+
@Test
12+
fun `test - find employee with the highest salary`() {
13+
assertEquals("Kevin Adams", employeeApi.findHighestPaidEmployee()?.name)
14+
}
15+
16+
@Test
17+
fun `test - find employees by department`() {
18+
val departments = employees
19+
.map { it.department }
20+
.distinct()
21+
22+
departments.forEach { department ->
23+
val actualEmployees = employeeApi.getEmployeesByDepartment(department)
24+
.sortedBy { it.name }
25+
.map { it.name }
26+
27+
assertEquals(DEPARTMENT_TO_EMPLOYEE[department.name], actualEmployees)
28+
}
29+
}
30+
31+
@Test
32+
fun `test - employees by salary range`() {
33+
val actualEmployees = employeeApi.getEmployeesBySalaryRange(60000..85000)
34+
.sortedBy { it.name }
35+
.map { it.name }
36+
37+
assertEquals(EMPLOYEES_IN_SALARY_RANGE_60k_TO_85k.sorted(), actualEmployees)
38+
}
39+
40+
@Test
41+
fun `test - calculate average salary by department`() {
42+
val departments = employees
43+
.map { it.department }
44+
.distinct()
45+
46+
departments.forEach { department ->
47+
val actualAverageSalary = employeeApi.calculateAverageSalaryByDepartment(department)
48+
49+
assertEquals(DEPARTMENT_NAME_TO_AVERAGE_SALARY[department.name], actualAverageSalary)
50+
}
51+
}
52+
53+
@Test
54+
fun `test - find most common skill employees have`() {
55+
assertEquals("Kotlin", employeeApi.findMostCommonSkill())
56+
}
57+
58+
companion object {
59+
private val DEPARTMENT_TO_EMPLOYEE = mapOf(
60+
"HR" to listOf(
61+
"Alice Rodriguez",
62+
"Alice Wilson",
63+
"Amy Adams",
64+
"Chris Adams",
65+
"David Taylor",
66+
"Emily Doe",
67+
"Emily Smith",
68+
"Emily Wang",
69+
"Jane Johnson",
70+
"Jane Lee",
71+
"Jane Rodriguez",
72+
"Jane Towns",
73+
"John Que",
74+
"Kevin Johnson",
75+
"Kevin Smith",
76+
"Sarah Lee",
77+
"Sarah Wilson"
78+
),
79+
"Finance" to listOf(
80+
"Alice Lee",
81+
"Amy Doe",
82+
"Amy Wang",
83+
"Emily Adams",
84+
"Jane Davis",
85+
"Kevin Doe"
86+
),
87+
"Engineering" to listOf(
88+
"Alice Adams",
89+
"Alice Doe",
90+
"Alice Smith",
91+
"Amy Rodriguez",
92+
"Amy Smith",
93+
"Amy Wilson",
94+
"Chris Rodriguez",
95+
"Chris Wang",
96+
"Chris Wilson",
97+
"David Doe",
98+
"David Smith",
99+
"David Wilson",
100+
"Emily Wilson",
101+
"John Wang",
102+
"Kevin Adams",
103+
"Kevin Lee",
104+
"Kevin Rodriguez",
105+
"Michael Johnson",
106+
"Michael Lee"
107+
),
108+
"Marketing" to listOf(
109+
"Alice Brown",
110+
"Amy Taylor",
111+
"Chris Doe",
112+
"Chris Taylor",
113+
"Jane Brown",
114+
"Jane Doe",
115+
"John Smith",
116+
"Kevin Taylor"
117+
)
118+
)
119+
120+
private val EMPLOYEES_IN_SALARY_RANGE_60k_TO_85k = listOf(
121+
"Kevin Adams",
122+
"Chris Wang",
123+
"Alice Smith",
124+
"Alice Adams",
125+
"Kevin Lee",
126+
"Amy Wang",
127+
"Alice Lee",
128+
"Jane Davis",
129+
"Amy Wilson",
130+
"David Doe",
131+
"David Wilson",
132+
"Chris Wilson",
133+
"Emily Adams",
134+
"Kevin Rodriguez",
135+
"Kevin Doe",
136+
"Michael Lee",
137+
"Emily Wilson",
138+
"David Smith",
139+
"Amy Rodriguez",
140+
"Chris Rodriguez",
141+
"Emily Doe",
142+
"Kevin Johnson",
143+
"John Wang",
144+
)
145+
146+
private val DEPARTMENT_NAME_TO_AVERAGE_SALARY: Map<String, Double> = mapOf(
147+
"HR" to 54986.58823529412,
148+
"Finance" to 67160.33333333333,
149+
"Engineering" to 66920.73684210527,
150+
"Marketing" to 53745.125,
151+
)
152+
}
153+
}

0 commit comments

Comments
 (0)