-
-
Notifications
You must be signed in to change notification settings - Fork 132
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
327 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# Instructions | ||
|
||
The first line of the CSV file contains the headings, the other lines contain the results of the participants. | ||
Each line has the following elements separated by commas: an id, a name, then 10 points for 10 exercises. | ||
A maximum of 10 points can be achieved in each exercise. A value of -1 means that no solution has been | ||
submitted. | ||
The lines of the files can be read by: | ||
```scala | ||
val lines = readCSV() | ||
``` | ||
For the following calculations should be solved using Scala’s collections with their higher-order | ||
functions. Try to implement each calculation by a single chain of operations. | ||
|
||
## Task 1: Building a list of Results objects | ||
The first task is to build a list of Results objects from the read lines. Implement a case class Results | ||
with an id of type Int, as name of type String and an list of points of type List[Int]. Then compute | ||
the list of Results objects for the participants | ||
```scala | ||
val resultList : List[Results] = ??? | ||
``` | ||
|
||
## Task 2: Number of solved tasks | ||
From the list of Results objects, create a map that contains the number of solved exercises for each | ||
student. An exercise is considered solved if at least 3 points have been achieved. | ||
|
||
## Task 3: Sufficient tasks solved | ||
A student must solve at least 8 exercises to pass the course. Determine which students have submitted | ||
enough solutions and which have not enough solutions. | ||
```scala | ||
val sufficientSolved : (Set[String], Set[String]) = ... | ||
``` | ||
_Hint: Use method partition._ | ||
|
||
## Task 4: Grading | ||
|
||
Next, the grades should be determined. The grades are calculated based on the points: There must be at least eight solutions with at least 3 | ||
points. If this is the case, the grading is done based on the average of the best eight solutions according | ||
to the following scheme: | ||
``` | ||
- [0.0 .. 5.0) : INSUFFICIENT | ||
- [5.0 .. 6.25) : SUFFICIENT | ||
- [6.25 .. 7.5) : SATISFACTORY | ||
- [7.5 .. 8.75) : GOOD | ||
- [8.75 .. 1.0] : EXCELLENT | ||
``` | ||
```scala | ||
val grades: Map[String, Grade] = ... | ||
``` | ||
|
||
## Task 5: Grade statistics | ||
|
||
Compute statistic measurement from the grading. For each grade, compute the number of students with | ||
that grade: | ||
```scala | ||
val nStudentsWithGrade : Map[Grade, Int] = ... | ||
``` | ||
|
||
## Task 6: Number solved per assignment | ||
For the 10 exercises, compute how many students have solved them (at least 3 points). Result is a list of | ||
10 numbers, which indicate how many students have solved the exercises: | ||
```scala | ||
val nSolvedPerAssnmt : List[(Int, Int)] = ... | ||
``` | ||
|
||
## Task 7: Average points per assignment | ||
For the 10 exercises, compute the average of the achieved points. Only the submitted exercises (points | ||
!= -1) should be considered: | ||
```scala | ||
val avrgPointsPerAssnmt : List[(Int, Double)] = ... | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Processing Results with Collections | ||
In this assignment, we want to use the Scala collections API for analyzing the results of a programming | ||
course. The starting point is a CSV file in which the points achieved in 10 programming exercises are | ||
stored for the course participants: | ||
ID,Name,1,2,3,4,5,6,7,8,9,10 | ||
1,Alred Maier,10,8,2,7,10,9,7,6,7,2 | ||
2,Fritz Michalik,8,6,5,7,-1,-1,8,6,8,10 | ||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
object ResultsAnalysis { | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"authors": [ | ||
"mrtob" | ||
], | ||
"contributors": [ | ||
"mrtob" | ||
], | ||
"files": { | ||
"solution": [ | ||
"src/main/scala/ResultsAnalysis.scala" | ||
], | ||
"test": [ | ||
"src/test/scala/ResultsAnalysisTest.scala" | ||
], | ||
"example": [ | ||
".meta/Example.scala" | ||
], | ||
"invalidator": [ | ||
"build.sbt" | ||
] | ||
}, | ||
"blurb": "Analyze the points of students in a class to ´genrate statistics.", | ||
"source": "Exercism", | ||
"source_url": "" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
scalaVersion := "3.4.2" | ||
|
||
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.19" % Test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
sbt.version=1.10.1 |
82 changes: 82 additions & 0 deletions
82
exercises/practice/result-analyzer/src/main/scala/ResultsAnalysis.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
def readCSV(): List[String] = { | ||
List( | ||
"ID,Name,1,2,3,4,5,6,7,8,9,10", | ||
"1,Jane Doe,9,10,9,6,10,9,10,10,10,9", | ||
"2,John Doe,8,6,5,7,-1,-1,8,6,8,10", | ||
"3,Jake Doe,10,9,9,-1,5,-1,8,-1,10,9", | ||
"4,Jill Doe,10,8,2,7,10,9,7,6,7,2", | ||
) | ||
} | ||
|
||
case class Results(id: Int, name: String, points: IndexedSeq[Int]) | ||
|
||
enum Grade: | ||
case EXCELLENT, GOOD, SATISFACTORY, SUFFICIENT, INSUFFICIENT | ||
|
||
object ResultsAnalysis { | ||
|
||
def task1(lines: List[String]): List[Results] = | ||
//TODO: Implement this method | ||
??? | ||
|
||
def task2(resultList: List[Results]): Map[String, Int] = | ||
//TODO: Implement this method | ||
??? | ||
|
||
def task3(nSolvedPerStnd: Map[String, Int]): (Set[String], Set[String]) = | ||
//TODO: Implement this method | ||
??? | ||
|
||
def task4(resultList: List[Results]): Map[String, Grade] = | ||
//TODO: Implement this method | ||
??? | ||
|
||
def task5(resultList: List[Results]): Map[Grade, Int] = | ||
//TODO: Implement this method | ||
??? | ||
|
||
def task6(resultList: List[Results]): List[(Int, Int)] = | ||
//TODO: Implement this method | ||
??? | ||
|
||
def task7(resultList: List[Results]): List[(Int, Double)] = | ||
//TODO: Implement this method | ||
??? | ||
|
||
def main(args: Array[String]): Unit = { | ||
val lines = readCSV() | ||
|
||
// Task 1 | ||
val resultList: List[Results] = task1(lines) | ||
|
||
// Task 2 | ||
val nSolvedPerStnd = task2(resultList) | ||
|
||
// Task 3 | ||
val sufficientSolved = task3(nSolvedPerStnd) | ||
|
||
// Task 4 | ||
val grades = task4(resultList) | ||
|
||
//Task 5 | ||
val nStudentsWithGrade = task5(resultList) | ||
|
||
//Task 6 | ||
val nSolvedPerAssnmt = task6(resultList) | ||
|
||
//Task 7 | ||
val avrgPointsPerAssnmt = task7(resultList) | ||
} | ||
|
||
private def computeGrade(points: IndexedSeq[Int]): Grade = { | ||
if (points.count(p => p >= 3) < 8) then Grade.INSUFFICIENT | ||
else { | ||
val avrg = points.sorted.drop(2).sum / 8 | ||
if (avrg < 5.0) then Grade.INSUFFICIENT | ||
else if (avrg < 6.5) then Grade.SUFFICIENT | ||
else if (avrg < 8.0) then Grade.SATISFACTORY | ||
else if (avrg < 9.0) then Grade.GOOD | ||
else Grade.EXCELLENT | ||
} | ||
} | ||
} |
134 changes: 134 additions & 0 deletions
134
exercises/practice/result-analyzer/src/test/scala/ResultsAnalysisTest.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import org.scalatest.funsuite.AnyFunSuite | ||
import org.scalatest.matchers.should.Matchers | ||
|
||
import scala.collection.immutable.HashMap | ||
|
||
|
||
/** @version 1.2.0 */ | ||
class ResultsAnalysisTest extends AnyFunSuite with Matchers { | ||
|
||
test("Task 1") { | ||
val lines = List( | ||
"ID,Name,1,2,3,4,5,6,7,8,9,10", | ||
"1,Jane Doe,9,10,9,6,10,9,10,10,10,9", | ||
"2,John Doe,8,6,5,7,-1,-1,8,6,8,10", | ||
"3,Jake Doe,10,9,9,-1,5,-1,8,-1,10,9", | ||
"4,Jill Doe,10,8,2,7,10,9,7,6,7,2", | ||
) | ||
|
||
val expectedResults = List( | ||
Results(1, "Jane Doe", IndexedSeq(9, 10, 9, 6, 10, 9, 10, 10, 10, 9)), | ||
Results(2, "John Doe", IndexedSeq(8, 6, 5, 7, -1, -1, 8, 6, 8, 10)), | ||
Results(3, "Jake Doe", IndexedSeq(10, 9, 9, -1, 5, -1, 8, -1, 10, 9)), | ||
Results(4, "Jill Doe", IndexedSeq(10, 8, 2, 7, 10, 9, 7, 6, 7, 2)) | ||
) | ||
|
||
val resultList = ResultsAnalysis.task1(lines) | ||
resultList shouldEqual expectedResults | ||
} | ||
|
||
test("Task 2") { | ||
val results = List( | ||
Results(1, "Jane Doe", IndexedSeq(9, 10, 9, 6, 10, 9, 10, 10, 10, 9)), | ||
Results(2, "John Doe", IndexedSeq(8, 6, 5, 7, -1, -1, 8, 6, 8, 10)), | ||
Results(3, "Jake Doe", IndexedSeq(10, 9, 9, -1, 5, -1, 8, -1, 10, 9)), | ||
Results(4, "Jill Doe", IndexedSeq(10, 8, 2, 7, 10, 9, 7, 6, 7, 2)) | ||
) | ||
|
||
val expectedResults = Map( | ||
"Jane Doe" -> 10, | ||
"John Doe" -> 8, | ||
"Jake Doe" -> 7, | ||
"Jill Doe" -> 8 | ||
) | ||
|
||
val resultList = ResultsAnalysis.task2(results) | ||
resultList shouldEqual expectedResults | ||
} | ||
|
||
test("Task 3") { | ||
val results = Map( | ||
"Jane Doe" -> 10, | ||
"John Doe" -> 8, | ||
"Jake Doe" -> 7, | ||
"Jill Doe" -> 8 | ||
) | ||
|
||
val expectedResults = (Set("Jane Doe", "John Doe", "Jill Doe"), Set("Jake Doe")) | ||
|
||
val resultList = ResultsAnalysis.task3(results) | ||
resultList shouldEqual expectedResults | ||
} | ||
|
||
test("Task 4") { | ||
val results = List( | ||
Results(1, "Jane Doe", IndexedSeq(9, 10, 9, 6, 10, 9, 10, 10, 10, 9)), | ||
Results(2, "John Doe", IndexedSeq(8, 6, 5, 7, -1, -1, 8, 6, 8, 10)), | ||
Results(3, "Jake Doe", IndexedSeq(10, 9, 9, -1, 5, -1, 8, -1, 10, 9)), | ||
Results(4, "Jill Doe", IndexedSeq(10, 8, 2, 7, 10, 9, 7, 6, 7, 2)) | ||
) | ||
|
||
val expectedResults = Map( | ||
"Jane Doe" -> Grade.EXCELLENT, | ||
"John Doe" -> Grade.SATISFACTORY, | ||
"Jake Doe" -> Grade.INSUFFICIENT, | ||
"Jill Doe" -> Grade.GOOD | ||
) | ||
|
||
val resultList = ResultsAnalysis.task4(results) | ||
resultList shouldEqual expectedResults | ||
} | ||
|
||
test("Task 5") { | ||
val results = List( | ||
Results(1, "Jane Doe", IndexedSeq(9, 10, 9, 6, 10, 9, 10, 10, 10, 9)), | ||
Results(2, "John Doe", IndexedSeq(8, 6, 5, 7, -1, -1, 8, 6, 8, 10)), | ||
Results(3, "Jake Doe", IndexedSeq(10, 9, 9, -1, 5, -1, 8, -1, 10, 9)), | ||
Results(4, "Jill Doe", IndexedSeq(10, 8, 2, 7, 10, 9, 7, 6, 7, 2)) | ||
) | ||
|
||
val expectedResults = HashMap( | ||
Grade.EXCELLENT -> 1, | ||
Grade.SATISFACTORY -> 1, | ||
Grade.INSUFFICIENT -> 1, | ||
Grade.GOOD -> 1 | ||
) | ||
|
||
val resultList = ResultsAnalysis.task5(results) | ||
resultList shouldEqual expectedResults | ||
} | ||
|
||
test("Task 6") { | ||
val results = List( | ||
Results(1, "Jane Doe", IndexedSeq(9, 10, 9, 6, 10, 9, 10, 10, 10, 9)), | ||
Results(2, "John Doe", IndexedSeq(8, 6, 5, 7, -1, -1, 8, 6, 8, 10)), | ||
Results(3, "Jake Doe", IndexedSeq(10, 9, 9, -1, 5, -1, 8, -1, 10, 9)), | ||
Results(4, "Jill Doe", IndexedSeq(10, 8, 2, 7, 10, 9, 7, 6, 7, 2)) | ||
) | ||
|
||
val expectedResults = List( | ||
(1, 4), (2, 4), (3, 3), (4, 3), (5, 3), (6, 2), (7, 4), (8, 3), (9, 4), (10, 3) | ||
) | ||
|
||
val resultList = ResultsAnalysis.task6(results) | ||
resultList shouldEqual expectedResults | ||
} | ||
|
||
test("Task 7"){ | ||
val results = List( | ||
Results(1, "Jane Doe", IndexedSeq(9, 10, 9, 6, 10, 9, 10, 10, 10, 9)), | ||
Results(2, "John Doe", IndexedSeq(8, 6, 5, 7, -1, -1, 8, 6, 8, 10)), | ||
Results(3, "Jake Doe", IndexedSeq(10, 9, 9, -1, 5, -1, 8, -1, 10, 9)), | ||
Results(4, "Jill Doe", IndexedSeq(10, 8, 2, 7, 10, 9, 7, 6, 7, 2)) | ||
) | ||
|
||
val expectedResults = List( | ||
(1,9.25), (2,8.25), (3,6.25), (4,6.666666666666667), (5,8.333333333333334), (6,9.0), (7,8.25), (8,7.333333333333333), (9,8.75), (10,7.5) | ||
) | ||
|
||
val resultList = ResultsAnalysis.task7(results) | ||
resultList shouldEqual expectedResults | ||
|
||
} | ||
|
||
} |