improved control structure usage

This commit is contained in:
2018-10-12 20:45:18 -04:00
parent 6424593392
commit c4e90971c9
3 changed files with 46 additions and 33 deletions

2
.idea/misc.xml generated
View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_10" default="true" project-jdk-name="10" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

View File

@@ -24,7 +24,7 @@ programming languages: 89
differential equations: 59 differential equations: 59
differential equations: 97 differential equations: 97
software architecture: 56 software architecture: 56
parallel and distributed computing: 89 parallel and distributed computing:
parallel and distributed computing: 66 parallel and distributed computing: 66
differential equations: 58 differential equations: 58
software architecture: 98 software architecture: 98

View File

@@ -1,35 +1,15 @@
import java.io.File import java.io.File
fun main(args: Array<String>) { class ReportCard {
// File I/O is easily done with `File()` constructor
val file = File("res/sample.grades")
// Maps and Lists are, by default, immutable. // Maps and Lists are, by default, immutable.
// Specify our data structure to be mutable at both levels // Specify our data structure to be mutable at both levels
val courses = mutableMapOf<String, MutableList<Int>>() private val courses = mutableMapOf<String, MutableList<Int>>()
// File supports line iteration with forEachLine, which accepts a code block.
// `it` is the iteration variable in the code block
file.forEachLine {
// It is possible to unpack iterables into multiple variables
// This is very brittle, though, if improperly formatted
val (rawCourse, rawGrade) = it.split(":")
// use `trim()` to strip whitespace from either side of the strings
// string conversion is easy with helper methods like `toInt()` and `toIntOrNull()`
val course = rawCourse.trim()
val grade = rawGrade.trim().toInt()
// collection testing is easy with `in` and `!in` operators
if (course !in courses)
courses[course] = mutableListOf() // implicit type arguments are passed: `mutableListOf<Int>()`
// use `!!` to assert the hash lookup will not be null. We just added it to the map.
courses[course]!!.add(grade)
}
// use getOrPut to get a list of course grades, and add the new grade to that list
fun addAssignment(course: String, grade: Int) = courses.getOrPut(course) { mutableListOf() }.add(grade)
fun grades(func: (String, String, Double) -> Unit) {
// Iteration over maps is easy when combined with iterable unpacking // Iteration over maps is easy when combined with iterable unpacking
for ((course, grades) in courses) { for ((course, grades) in courses) {
val average = grades.average() // List<Int> has helper methods such as `sum()` and `average()` val average = grades.average() // List<Int> has helper methods such as `sum()` and `average()`
@@ -40,12 +20,45 @@ fun main(args: Array<String>) {
average > 90 -> "A" average > 90 -> "A"
average > 80 -> "B" average > 80 -> "B"
average > 70 -> "C" average > 70 -> "C"
average > 70 -> "D" average > 60 -> "D"
else -> "F" else -> "F"
} }
// call back to the block given
func(course, letter, average)
}
}
}
// Create an extension method on `Double` that allows us to specify precision
fun Double.format(digits: Int) = java.lang.String.format("%.${digits}f", this)
fun main(args: Array<String>) {
// File I/O is easily done with `File()` constructor
val file = File("res/sample.grades")
val report = ReportCard()
// `File` supports line iteration with `forEachLine`, which accepts a code block.
// `it` is the iteration variable in the code block
file.forEachLine {
// It is possible to unpack iterables into multiple variables
// This is very brittle, though, if improperly formatted
val (rawCourse, rawGrade) = it.split(":").let {
Pair(it[0], it.getOrElse(1) { _ -> "" })
}
// use `trim()` to strip whitespace from either side of the strings
// string conversion is easy with helper methods like `toInt()` and `toIntOrNull()`
val course = rawCourse.trim()
val grade = rawGrade.trim().toIntOrNull()
grade?.let { report.addAssignment(course, it) }
}
// input and output from console are as easy as `println()` and `readline()` // input and output from console are as easy as `println()` and `readline()`
// uses string interpolation for easier formatting // uses string interpolation for easier formatting
println("$course:\n\t$letter ($average)\n") // grade precision is specified with the `format` extension method defined above
report.grades { course: String, letter: String, average: Double ->
println("$course:\n\t$letter (${average.format(2)})\n")
} }
} }