diff --git a/concepts/for-loops/.meta/config.json b/concepts/for-loops/.meta/config.json deleted file mode 100644 index 4d60e60ad..000000000 --- a/concepts/for-loops/.meta/config.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "blurb": "For loops allow for iteration over a specified range.", - "authors": [ - "samuelteixeiras", - "ystromm" - ], - "contributors": [] -} diff --git a/concepts/for-loops/about.md b/concepts/for-loops/about.md deleted file mode 100644 index 6988a26b9..000000000 --- a/concepts/for-loops/about.md +++ /dev/null @@ -1,67 +0,0 @@ -# About For Loops - -The [for loop](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html) provides a mechanism to execute a group of statements repeatedly until some condition is met. -The loop consists of four parts: - -```java -for (initialization; test; update) { - body; -} -``` - -The `initialization` sets an initial state for the loop and is executed exactly once at the start of the loop. -Typically it declares and assigns a variable used in the test expression and update statement. -For example: - -```java -int i = 1 -``` - -The `test` expression tests if the loop should end. -If it evaluates to true, the body and then the update expression will be executed. -If it evaluates to false, neither the body nor the update statement will be executed and execution resumes after the loop's closing bracket. -Typically it checks the variable assigned in the initialization block. -For example: - -```java -i <= 10 -``` - -After executing the loop body, the `update` expression is executed. -Typically it increments or decrements the loop variable by some value. -For example: - -```java -i++ -``` - -A for loop printing out the first four squares would look like this: - -```java -for (int i = 1; i <= 4; i++) { - System.out.println(i * i); -} - -/* => -1 -4 -9 -16 -*/ -``` - -If iterating through every element in a collection, a `for-each` loop is preferred, but it can be done with a `for` loop like this: - -```java -for (int i = 0; i < array.length; i++) { - System.out.print(array[i]); -} -``` - -A `for` loop does have some advantages over a `for-each` loop: - -- You can start or stop at the index you want. -- You can use any (boolean) termination condition you want. -- You can skip elements by customizing the incrementing of the loop variable. -- You can process collections from back to front by counting down. -- You can use `for` loops in scenarios that do not involve collections. diff --git a/concepts/for-loops/introduction.md b/concepts/for-loops/introduction.md deleted file mode 100644 index 7412e28ee..000000000 --- a/concepts/for-loops/introduction.md +++ /dev/null @@ -1,69 +0,0 @@ -# Introduction to For Loops - -The [for loop](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html) provides a mechanism to execute a group of statements repeatedly until some condition is met. -The loop consists of four parts: - -```java -for (initialization; test; update) { - body; -} -``` - -The `initialization` sets an initial state for the loop and is executed exactly once at the start of the loop. -Typically it declares and assigns a variable used in the test expression and update statement. -For example: - -```java -int i = 1 -``` - -The `test` expression tests if the loop should end. -If it evaluates to `true`, the body and then the update expression will be executed. -If it evaluates to `false`, neither the body nor the update statement will be executed and execution resumes after the loop's closing bracket. -Typically it checks the variable assigned in the initialization block. -For example: - -```java -i <= 10 -``` - -After executing the loop body, the `update` expression is executed. -Typically it increments or decrements the loop variable by some value. -For example: - -```java -i++ -``` - -A `for` loop printing out the first four squares would look like this: - -```java -for (int i = 1; i <= 4; i++) { - System.out.println("square of " + i + " is " + i * i); -} -``` - -The output would be: - -```text -square of 1 is 1 -square of 2 is 4 -square of 3 is 9 -square of 4 is 16 -``` - -If iterating through every element in a collection, a `for-each` loop is preferred, but it can be done with a `for` loop like this: - -```java -for (int i = 0; i < array.length; i++) { - System.out.print(array[i]); -} -``` - -A `for` loop does have some advantages over a `for-each` loop: - -- You can start or stop at the index you want. -- You can use any (boolean) termination condition you want. -- You can skip elements by customizing the incrementing of the loop variable. -- You can process collections from back to front by counting down. -- You can use `for` loops in scenarios that do not involve collections. diff --git a/concepts/for-loops/links.json b/concepts/for-loops/links.json deleted file mode 100644 index 15e9e6533..000000000 --- a/concepts/for-loops/links.json +++ /dev/null @@ -1,6 +0,0 @@ -[ - { - "url": "https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html", - "description": "for-loop" - } -] diff --git a/concepts/foreach-loops/.meta/config.json b/concepts/foreach-loops/.meta/config.json deleted file mode 100644 index e2102abed..000000000 --- a/concepts/foreach-loops/.meta/config.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "blurb": "For-each loops allow for iteration over every element in a collection.", - "authors": [ - "samuelteixeiras", - "ystromm" - ], - "contributors": [] -} diff --git a/concepts/foreach-loops/about.md b/concepts/foreach-loops/about.md deleted file mode 100644 index 293b9c38f..000000000 --- a/concepts/foreach-loops/about.md +++ /dev/null @@ -1,45 +0,0 @@ -# About For-Each Loops - -The [for-each loop](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html) provides a mechanism for executing a block of code for each element in a collection. -Some documentation (eg. Oracle's documentation) refers to these as enhanced for loops. - -Here is the general syntax: - -```java -for(declaration: collection) { - body; -} -``` - -The `declaration` declares the variable used to hold the values assigned from the collection. - -The `collection` is an array or a collection holding the values that will be assigned to the loop variable. - -The `body` contains the statements that will be executed once for each value in the collection. - -For example: - -```java -char[] vowels = {'a', 'e', 'i', 'o', 'u'}; - -for(char vowel: vowels) { - System.out.println(vowel); -} -``` - -which outputs: - -```text -a -e -i -o -u -``` - -Generally a `for-each` loop is preferrable over a `for` loop for the following reasons: - -- A `for-each` loop is guaranteed to iterate over _all_ values. -- A `for-each` loop is more _declarative_ meaning the code is communicating _what_ it is doing, instead of _how_ it is doing it. -- A `for-each` loop is foolproof, whereas with `for` loops it is easy to have an off-by-one error (think of using `<` versus `<=`). -- A `for-each` loop works on all collection types, including those that do not support using an index to access elements (eg. a `Set`). diff --git a/concepts/foreach-loops/introduction.md b/concepts/foreach-loops/introduction.md deleted file mode 100644 index 7e2eec3c4..000000000 --- a/concepts/foreach-loops/introduction.md +++ /dev/null @@ -1,45 +0,0 @@ -# Introduction to For-Each Loops - -The [for-each loop](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html) provides a mechanism for executing a block of code for each element in a collection. -Some documentation (eg. Oracle's documentation) refers to these as enhanced for loops. - -Here is the general syntax: - -```java -for(declaration: collection) { - body; -} -``` - -The `declaration` declares the variable used to hold the values assigned from the collection. - -The `collection` is an array or collection holding the values that will be assigned to the loop variable. - -The `body` contains the statements that will be executed once for each value in the collection. - -For example: - -```java -char[] vowels = {'a', 'e', 'i', 'o', 'u'}; - -for(char vowel: vowels) { - System.out.println(vowel); -} -``` - -which outputs: - -```text -a -e -i -o -u -``` - -Generally a `for-each` loop is preferrable over a `for` loop for the following reasons: - -- A `for-each` loop is guaranteed to iterate over _all_ values. -- A `for-each` loop is more _declarative_ meaning the code is communicating _what_ it is doing, instead of _how_ it is doing it. -- A `for-each` loop is foolproof, whereas with `for` loops it is easy to have an off-by-one error (think of using `<` versus `<=`). -- A `for-each` loop works on all collection types, including those that do not support using an index to access elements (eg. a `Set`). diff --git a/concepts/foreach-loops/links.json b/concepts/foreach-loops/links.json deleted file mode 100644 index cd413aee3..000000000 --- a/concepts/foreach-loops/links.json +++ /dev/null @@ -1,6 +0,0 @@ -[ - { - "url": "https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html", - "description": "foreach-loop" - } -] diff --git a/concepts/loops/.meta/config.json b/concepts/loops/.meta/config.json new file mode 100644 index 000000000..2111551f8 --- /dev/null +++ b/concepts/loops/.meta/config.json @@ -0,0 +1,5 @@ +{ + "blurb": "Loops are a fundamental concept in Java programming that allow you to execute a block of code repeatedly.", + "authors": ["manumafe98"], + "contributors": [] +} diff --git a/concepts/loops/about.md b/concepts/loops/about.md new file mode 100644 index 000000000..18f31373b --- /dev/null +++ b/concepts/loops/about.md @@ -0,0 +1,240 @@ +# About + +In Java there are four looping constructs, two that are iteration centric: [`For`] and [`For-each`] and the other two are condition centric: [`While`] and [`Do-while`]. + +## For + +A for loop is a control flow statement that allows you to efficiently execute a block of code multiple times. +It achieves this repetition through a concept called iteration, where a variable (often called a loop counter) takes on different values within a specified range. This loop continues executing the code block until the iteration reaches its end. + +```java +for (initialization; test; update) { + body; +} +``` + +The `initialization` sets an initial state for the loop and is executed exactly once at the start of the loop. +Typically it declares and assigns a variable used in the test expression and update statement. +For example: + +```java +int i = 1 +``` + +The `test` expression tests if the loop should end. +If it evaluates to `true`, the body and then the update expression will be executed. +If it evaluates to `false`, neither the body nor the update statement will be executed and execution resumes after the loop's closing bracket. +Typically it checks the variable assigned in the initialization block. + +For example: + +```java +i <= 10 +``` + +After executing the loop body, the `update` expression is executed. +Typically it increments or decrements the loop variable by some value. +For example: + +```java +i++ +``` + +A `for` loop printing out the first four squares would look like this: + +```java +for (int i = 1; i <= 4; i++) { + System.out.println("square of " + i + " is " + i * i); +} +``` + +The output would be: + +```text +square of 1 is 1 +square of 2 is 4 +square of 3 is 9 +square of 4 is 16 +``` + +Iterating through every element in a collection is usually performed using a `for-each`, but it can be done with a `for` loop like this: + +```java +for (int i = 0; i < array.length; i++) { + System.out.print(array[i]); +} +``` + +A `for` loop does have some advantages over a `for-each` loop: + +- You can start or stop at the index you want. +- You can use any (boolean) termination condition you want. +- You can skip elements by customizing the incrementing of the loop variable. +- You can process collections from back to front by counting down. +- You can use `for` loops in scenarios that do not involve collections. + +## For-each + +A for-each loop provides a mechanism for executing a block of code for each element in a collection. + +```java +for (declaration: collection) { + body; +} +``` + +The `declaration` declares the variable used to hold the values assigned from the collection. + +The `collection` is an array or collection holding the values that will be assigned to the loop variable. + +The `body` contains the statements that will be executed once for each value in the collection. + +For example: + +```java +char[] vowels = {'a', 'e', 'i', 'o', 'u'}; + +for(char vowel: vowels) { + System.out.println(vowel); +} +``` + +which outputs: + +```text +a +e +i +o +u +``` + +Generally a `for-each` loop is preferrable over a `for` loop for the following reasons: + +- A `for-each` loop is guaranteed to iterate over _all_ values. +- A `for-each` loop is more _declarative_ meaning the code is communicating _what_ it is doing, instead of _how_ it is doing it. +- A `for-each` loop is foolproof, whereas with `for` loops it is easy to have an off-by-one error (think of using `<` versus `<=`). +- A `for-each` loop works on all collection types, including those that do not support using an index to access elements (eg. a `Set`). + +## While + +The `while` loop continually executes a block of statements while a particular condition is true. + +```java +while (condition) { + body; +} +``` + +The `condition` It's a statement that can be true or false. As long as the condition is true, the loop keeps running. +The `body` it's the code that gets executed repeatedly until the condition becomes false. + +For example: + +```java +int counter = 1; + +while (counter <= 5) { + System.out.println(counter); + counter++; +} +``` + +which outputs: + +```text +1 +2 +3 +4 +5 +``` + +Generally good rule of thumb is to use a `while` loops when you don't know exactly how many times you need to loop beforehand. + +## Do-while + +As `while` loops `do-while` loops are condition centric loops, but unlike a regular `while` loop, a `do-while` loop guarantees that the code inside the loop will run at least once, no matter what. + +```java +do { + body; +} while (condition); +``` + +For example: + +```java +int counter = 1; + +do { + System.out.println(counter); + counter++; +} while (counter < 2); +``` + +which outputs: + +```text +1 +``` + +## Loop control statements + +Loop control statements are special keywords used within loops to alter the normal execution flow. + +### Break + +The break statement acts as an "exit door" for a looping construct. +When encountered within the loop's body, `break` immediately terminates the loop's execution. + +For example: + +```java +for (int i = 0; i < 10; i++) { + if (i == 5) { + break; + } + + System.out.println(i); +} +``` + +which outputs: + +```text +0 +1 +2 +3 +4 +``` + +### Continue + +The continue statement on the other hand acts similar to a "skip button" in a looping construct. +When encountered within a loop's body, `continue` skips the remaining statements in the current iteration. + +For exmaple: + +```java +for (int i = 0; i < 5; i++) { + if (i < 3) { + continue; + } + + System.out.println(i); +} +``` + +which outputs: + +```text +3 +4 +``` + +[`For`]: #for +[`For-each`]: #for-each +[`While`]: #while +[`Do-while`]: #do-while diff --git a/concepts/loops/introduction.md b/concepts/loops/introduction.md new file mode 100644 index 000000000..a43f20ef3 --- /dev/null +++ b/concepts/loops/introduction.md @@ -0,0 +1,5 @@ +# Introduction + +Programming is full of tasks that need to be done over and over again. +To handle these repetitive actions efficiently, Java offers special control flow statements called looping constructs. +This concept will guide you through exploring these constructs and how to use them to your advantage. diff --git a/concepts/loops/links.json b/concepts/loops/links.json new file mode 100644 index 000000000..555411ece --- /dev/null +++ b/concepts/loops/links.json @@ -0,0 +1,10 @@ +[ + { + "url": "https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html", + "description": "The for and for-each statements" + }, + { + "url": "https://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html", + "description": "The while and do-while statements" + } +] diff --git a/config.json b/config.json index 0b281151c..0dee4aa5f 100644 --- a/config.json +++ b/config.json @@ -61,9 +61,7 @@ "name": "Bird Watcher", "uuid": "60600885-8684-45c3-b8a9-a2f9e3ce2d97", "concepts": [ - "arrays", - "for-loops", - "foreach-loops" + "arrays" ], "prerequisites": [ "if-else-statements" @@ -308,6 +306,19 @@ "generic-types" ], "status": "beta" + }, + { + "slug": "making-the-grade", + "name": "Making the Grade", + "uuid": "e5d2a004-8c9b-4da3-831b-f7bbabf178a3", + "concepts": [ + "loops" + ], + "prerequisites": [ + "if-else-statements", + "lists" + ], + "status": "beta" } ], "practice": [ @@ -494,7 +505,7 @@ "uuid": "8e983ed2-62f7-439a-a144-fb8fdbdf4d30", "practices": [], "prerequisites": [ - "foreach-loops", + "loops", "strings" ], "difficulty": 2 @@ -505,7 +516,7 @@ "uuid": "c31bbc6d-bdcf-44f7-bf35-5f98752e38d0", "practices": [], "prerequisites": [ - "for-loops", + "loops", "strings" ], "difficulty": 3 @@ -537,7 +548,7 @@ "uuid": "ce899ca6-9cc7-47ba-b76f-1bbcf2630b76", "practices": [], "prerequisites": [ - "for-loops" + "loops" ], "difficulty": 3 }, @@ -689,7 +700,7 @@ "practices": [], "prerequisites": [ "chars", - "for-loops" + "loops" ], "difficulty": 4 }, @@ -700,7 +711,7 @@ "practices": [], "prerequisites": [ "if-else-statements", - "for-loops", + "loops", "strings" ], "difficulty": 4 @@ -735,7 +746,7 @@ "prerequisites": [ "chars", "numbers", - "for-loops" + "loops" ], "difficulty": 4 }, @@ -746,7 +757,7 @@ "practices": [], "prerequisites": [ "numbers", - "for-loops" + "loops" ], "difficulty": 4 }, @@ -768,7 +779,7 @@ "practices": [], "prerequisites": [ "exceptions", - "for-loops", + "loops", "if-else-statements", "numbers" ], @@ -780,7 +791,7 @@ "uuid": "9906491b-a638-408d-86a4-4ad320a92658", "practices": [], "prerequisites": [ - "for-loops", + "loops", "arrays" ], "difficulty": 4 @@ -793,7 +804,7 @@ "prerequisites": [ "chars", "if-else-statements", - "for-loops" + "loops" ], "difficulty": 4 }, @@ -846,7 +857,7 @@ "uuid": "581afdbb-dfb6-4dc5-9554-a025b5469a3c", "practices": [], "prerequisites": [ - "for-loops", + "loops", "arrays" ], "difficulty": 4 @@ -877,7 +888,7 @@ "uuid": "6a617ddb-04e3-451c-bb30-27ccd0be9125", "practices": [], "prerequisites": [ - "for-loops", + "loops", "enums", "bit-manipulation" ], @@ -890,7 +901,7 @@ "practices": [], "prerequisites": [ "chars", - "foreach-loops" + "loops" ], "difficulty": 5 }, @@ -955,7 +966,7 @@ "uuid": "85aa50ac-0141-49eb-bc6f-62f3f7a97647", "practices": [], "prerequisites": [ - "foreach-loops", + "loops", "strings" ], "difficulty": 5 @@ -967,7 +978,7 @@ "practices": [], "prerequisites": [ "if-else-statements", - "for-loops" + "loops" ], "difficulty": 5 }, @@ -1038,7 +1049,7 @@ "prerequisites": [ "chars", "if-else-statements", - "for-loops" + "loops" ], "difficulty": 5 }, @@ -1069,7 +1080,7 @@ "uuid": "3603b770-87a5-4758-91f3-b4d1f9075bc1", "practices": [], "prerequisites": [ - "for-loops", + "loops", "arrays" ], "difficulty": 5 @@ -1081,7 +1092,7 @@ "practices": [], "prerequisites": [ "arrays", - "for-loops", + "loops", "if-else-statements", "strings" ], @@ -1095,7 +1106,7 @@ "prerequisites": [ "chars", "exceptions", - "for-loops", + "loops", "if-else-statements", "numbers" ], @@ -1109,7 +1120,7 @@ "prerequisites": [ "arrays", "exceptions", - "for-loops", + "loops", "if-else-statements", "numbers" ], @@ -1171,7 +1182,7 @@ "uuid": "4b3f7771-c642-4278-a3d9-2fb958f26361", "practices": [], "prerequisites": [ - "for-loops", + "loops", "arrays" ], "difficulty": 6 @@ -1182,7 +1193,7 @@ "uuid": "76d28d97-75d3-47eb-bb77-3d347b76f1b6", "practices": [], "prerequisites": [ - "foreach-loops", + "loops", "strings" ], "difficulty": 6 @@ -1216,7 +1227,7 @@ "practices": [], "prerequisites": [ "strings", - "for-loops" + "loops" ], "difficulty": 6 }, @@ -1273,7 +1284,7 @@ "prerequisites": [ "arrays", "chars", - "foreach-loops", + "loops", "if-else-statements" ], "difficulty": 6 @@ -1317,7 +1328,7 @@ "uuid": "163fcc6b-c054-4232-a88b-0aded846a6eb", "practices": [], "prerequisites": [ - "for-loops", + "loops", "numbers" ], "difficulty": 6 @@ -1338,7 +1349,7 @@ "uuid": "57b76837-4610-466f-9373-d5c2697625f1", "practices": [], "prerequisites": [ - "for-loops", + "loops", "lists", "strings" ], @@ -1365,7 +1376,7 @@ "arrays", "if-else-statements", "lists", - "for-loops" + "loops" ], "difficulty": 7 }, @@ -1402,7 +1413,7 @@ "prerequisites": [ "chars", "constructors", - "for-loops", + "loops", "if-else-statements", "numbers" ], @@ -1473,7 +1484,7 @@ "chars", "if-else-statements", "lists", - "for-loops" + "loops" ], "difficulty": 7 }, @@ -1653,7 +1664,7 @@ "uuid": "1bac7473-9ee8-4cfc-928b-77792102ffc1", "practices": [], "prerequisites": [ - "for-loops", + "loops", "randomness", "strings" ], @@ -1679,7 +1690,7 @@ "practices": [], "prerequisites": [ "exceptions", - "for-loops", + "loops", "if-else-statements", "numbers" ], @@ -1694,7 +1705,7 @@ "strings", "if-else-statements", "lists", - "for-loops" + "loops" ], "difficulty": 8 }, @@ -1739,7 +1750,7 @@ "prerequisites": [ "chars", "exceptions", - "for-loops", + "loops", "if-else-statements", "numbers", "randomness" @@ -1853,16 +1864,6 @@ "slug": "exceptions", "name": "Exceptions" }, - { - "uuid": "3a1f7a96-b4a5-43d3-99e2-7c248e74e6c8", - "slug": "foreach-loops", - "name": "For-Each Loops" - }, - { - "uuid": "b1bb63e6-4540-48fc-9d11-4ee72653484e", - "slug": "for-loops", - "name": "For Loops" - }, { "uuid": "7de03b7d-ed91-4699-b275-96a6ab2e441c", "slug": "generic-types", @@ -1883,6 +1884,11 @@ "slug": "lists", "name": "Lists" }, + { + "uuid": "b84a2119-71cc-46d0-af7f-32fe9a07d0e2", + "slug": "loops", + "name": "Loops" + }, { "uuid": "54118389-9c01-431b-a850-f47da498f845", "slug": "method-overloading", diff --git a/exercises/concept/making-the-grade/.docs/hints.md b/exercises/concept/making-the-grade/.docs/hints.md new file mode 100644 index 000000000..d68604794 --- /dev/null +++ b/exercises/concept/making-the-grade/.docs/hints.md @@ -0,0 +1,28 @@ +# Hints + +## 1. Non-Passing Students + +- Try using one of the loops that is iteration centric. + +## 2. Get the average grade of students + +- Try using one of the loops that is condition centric using `numberOfStudents` as one of the core conditions. + +## 3. Calculating letter grades + +- Remember that there is a condition centric loop that guarantees the body to be executed at least once. + +## 4. Matching Names to Scores + +- Try using a iteration centric loop that allow you to work with indexes. + +## 5. Count Odd Scores + +- Remember that you could use the modulus operator `%` to check if a division has a certain reminder. +- Try using a iteration centric loop +- Check the statements/keywords covered in the concept an use one of them. + +## 6. Challenging Exam + +- Try using a iteration centric loop +- Check the statements/keywords covered in the concept an use one of them. diff --git a/exercises/concept/making-the-grade/.docs/instructions.md b/exercises/concept/making-the-grade/.docs/instructions.md new file mode 100644 index 000000000..22b72e7ff --- /dev/null +++ b/exercises/concept/making-the-grade/.docs/instructions.md @@ -0,0 +1,89 @@ +# Instructions + +You're a teaching assistant correcting student exams. +Keeping track of results manually is getting both tedious and mistake-prone. +You decide to make things a little more interesting by putting together some functions to count and calculate results for the class. + +## 1. Non-Passing Students + +As you were grading the exam, you noticed some students weren't performing as well as you had hoped. +But you were distracted, and forgot to note exactly _how many_ students. + +Create the method `countFailedStudents(List studentScores)` that takes a `List` of students scores. +This method should count up the number of students who don't have passing scores and return that count as an integer. +A student needs a score greater than **40** to achieve a passing grade on the exam. + +```java +MakingTheGrade.countFailedStudents(List.of(40, 70, 80, 20, 39)); +// => 3 +``` + +## 2. Get the average grade of students + +As your second task of the day the professor asks you to get the average score of a certain number of students. + +Create the method `getAverageScoreOfStudents(List studentScores, int numberOfStudents)` that takes a `List` of studentScores and a `int` of numberOfStudents. +This method should get the average score of the number of students passed. +The number of students is guaranteed to be lower than the size of the list of scores. + +```java +MakingTheGrade.getAverageScoreOfStudents(List.of(40, 70, 80, 20, 39, 50, 100, 90, 66, 15, 79), 10); +// => 57 +``` + +## 3. Calculating letter grades + +The teacher you are assisting needs to handle a letter with the amount of students needed to sum a score of 95 to the principal of the school. +This letter has to have at least 1 student in it (if the first students alone exceeds the score should be added as well). +And if already one student was added to the letter do not exceed the maximum score. + +Create the method `MakingTheGrade.letterGrades(List studentScores, List studentNames)` that takes a `List studentScores` of students scores and `List studentNames` corresponding with the names of the students. This method should return the list of students added to the letter. + +```java +MakingTheGrade.letterGrades(List.of(100, 20, 53, 91), List.of("Joci", "Sara", "Bern", "Fred")); +// => ["Joci"] + +MakingTheGrade.letterGrades(List.of(20, 40, 30, 85), List.of("Jan", "Kora", "Sara", "Peter")); +// => ["Jan", "Kora", "Sara"] +``` + +## 4. Matching Names to Scores + +You have a list of exam scores in descending order, and another list of student names also sorted in descending order by their exam scores. You would like to match each student name with their exam score and print out an overall class ranking. + +Create the method `studentRanking(List studentScores, List studentNames)` with parameters `List` of studentScores and `List` studentNames. Match each student name on the studentNames list with their score from the studentScores list. You can assume each argument list will be sorted from highest score(er) to lowest score(er). The function should return a list of strings with the format . : . + +```java +List studentScores = List.of(100, 99, 90, 84, 66, 53, 47); +List studentNames = List.of("Joci", "Sara", "Kora", "Jan", "John", "Bern", "Fred"); + +MakingTheGrade.studentRanking(studentScores, studentNames); +// => ["1. Joci: 100", "2. Sara: 99", "3. Kora: 90", "4. Jan: 84", "5. John: 66", "6. Bern: 53", "7. Fred: 47"] +``` + +## 5. Count Odd Scores + +As an investigation, the principal asked the teacher to count how many scores of the math exam result being odd scores, and since you want to help him handle it efficiently. + +We are going to create the method `countOddScores(List studentScores)` with the parameter `List` of studentScores. +This method should count up the number of odd students scores and return that count as an integer. + +```java +MakingTheGrade.countOddScores(List.of(20, 35, 40, 10, 39, 77)); +// => 3 +``` + +## 6. Challenging Exam + +The teacher has prepared a challenging exam and wants to analyze the results. +As his assistant you'll evaluate the exams in the same order students handed them in. +The teacher is particularly interested in knowing how many students passed the exam before the first non-passing student. +As you know a student needs a score greater than **40** to achieve a passing grade on the exam. + +Create the method `evaluateChallengingExam(List studentScores)` that takes a `List` of students scores in the handed order. +This method should count up the number of passing student scores until the first non-passing score and return that count as an integer. + +```java +MakingTheGrade.evaluateChallengingExam(List.of(45, 90, 15, 100, 70)); +// => 2 +``` diff --git a/exercises/concept/making-the-grade/.docs/introduction.md b/exercises/concept/making-the-grade/.docs/introduction.md new file mode 100644 index 000000000..a43f20ef3 --- /dev/null +++ b/exercises/concept/making-the-grade/.docs/introduction.md @@ -0,0 +1,5 @@ +# Introduction + +Programming is full of tasks that need to be done over and over again. +To handle these repetitive actions efficiently, Java offers special control flow statements called looping constructs. +This concept will guide you through exploring these constructs and how to use them to your advantage. diff --git a/exercises/concept/making-the-grade/.docs/introduction.md.tpl b/exercises/concept/making-the-grade/.docs/introduction.md.tpl new file mode 100644 index 000000000..313a2f9d4 --- /dev/null +++ b/exercises/concept/making-the-grade/.docs/introduction.md.tpl @@ -0,0 +1,3 @@ +# Introduction + +%{concept:loops} diff --git a/exercises/concept/making-the-grade/.meta/config.json b/exercises/concept/making-the-grade/.meta/config.json new file mode 100644 index 000000000..005357cc8 --- /dev/null +++ b/exercises/concept/making-the-grade/.meta/config.json @@ -0,0 +1,23 @@ +{ + "authors": [ + "manumafe98" + ], + "files": { + "solution": [ + "src/main/java/MakingTheGrade.java" + ], + "test": [ + "src/test/java/MakingTheGradeTest.java" + ], + "exemplar": [ + ".meta/src/reference/java/MakingTheGrade.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "forked_from": [ + "python/making-the-grade" + ], + "blurb": "Learn to use different kinds of loops by automating the tasks of an assistant teacher." +} diff --git a/exercises/concept/making-the-grade/.meta/design.md b/exercises/concept/making-the-grade/.meta/design.md new file mode 100644 index 000000000..709fa5fff --- /dev/null +++ b/exercises/concept/making-the-grade/.meta/design.md @@ -0,0 +1,39 @@ +# Design + +## Learning objectives + +- Know how to repeteadly execute code using a `for` loop.´ +- Know how to repeteadly execute code using a `for-each` loop. +- Know how to repeteadly execute code using a `while` loop. +- Know how to repeteadly execute code using a `do-while` loop. +- Know the control flow statements `break` and `continue`. + +## Concepts + +- `loops` + +## Prerequisites + +This exercise's prerequisites Concepts are: + +- `lists` +- `if-else-statements` + +## Analyzer + +This exercise could benefit from the following rules in the [analyzer]: + +- `essential`: If the student did not use a `for-each` loop in the `countFailedStudents` method, instruct them to do so. +- `essential`: If the student did not use a `while` loop in the `getAverageScoreOfStudents` method, instruct them to do so. +- `essential`: If the student did not use a `do-while` loop in the `letterGrades` method, instruct them to do so. +- `essential`: If the student did not use a `for` loop in the `studentRanking` method, instruct them to do so. +- `essential`: If the student did not use the `continue` statement in the `countOddScores` method, instruct them to do so. +- `essential`: If the student did not use the `break` statement in the `evaluateChallengingExam` method, instruct them to do so. +- `actionable`: If the student solved the exercise using a different loop that `for-each` in the `countOddScores` method, encourage them to use `for-each` instead. +- `actionable`: If the student solved the exercise using a different loop that `for-each` in the `evaluateChallengingExam` method, encourage them to use `for-each` instead. +- `informative`: If the solution uses `String.format` in the `studentRanking` method, inform the student that this cause a small performance penalty compared to string concatenation. + +If the solution does not receive any of the listed feedback, it must be exemplar. +Leave a `celebratory` comment to celebrate the success! + +[analyzer]: https://github.com/exercism/java-analyzer diff --git a/exercises/concept/making-the-grade/.meta/src/reference/java/MakingTheGrade.java b/exercises/concept/making-the-grade/.meta/src/reference/java/MakingTheGrade.java new file mode 100644 index 000000000..9ea3314fb --- /dev/null +++ b/exercises/concept/making-the-grade/.meta/src/reference/java/MakingTheGrade.java @@ -0,0 +1,84 @@ +import java.util.List; +import java.util.ArrayList; + +class MakingTheGrade { + + static int countFailedStudents(List studentScores) { + int count = 0; + + for (int score : studentScores) { + if (score <= 40) { + count++; + } + } + + return count; + } + + static int getAverageScoreOfStudents(List studentScores, int numberOfStudents) { + int count = 0; + int sum = 0; + + while (count < numberOfStudents) { + sum += studentScores.get(count); + count++; + } + + return sum / numberOfStudents; + } + + static List letterGrades(List studentScores, List studentNames) { + List letter = new ArrayList<>(); + int sum = 0; + int count = 0; + + do { + sum += studentScores.get(count); + letter.add(studentNames.get(count)); + count++; + } while (sum + studentScores.get(count) < 95); + + return letter; + } + + static List studentRanking(List studentScores, List studentNames) { + List ranking = new ArrayList<>(); + + for (int i = 0; i < studentScores.size(); i++) { + String student = String.valueOf(i + 1) + ". " + studentNames.get(i) + ": " + + String.valueOf(studentScores.get(i)); + + ranking.add(student); + } + + return ranking; + } + + static int countOddScores(List studentScores) { + int count = 0; + + for (int score : studentScores) { + if (score % 2 == 0) { + continue; + } + + count++; + } + + return count; + } + + static int evaluateChallengingExam(List studentScores) { + int count = 0; + + for (int score : studentScores) { + if (score <= 40) { + break; + } + + count++; + } + + return count; + } +} diff --git a/exercises/concept/making-the-grade/build.gradle b/exercises/concept/making-the-grade/build.gradle new file mode 100644 index 000000000..d2eca9ec7 --- /dev/null +++ b/exercises/concept/making-the-grade/build.gradle @@ -0,0 +1,23 @@ +plugins { + id "java" +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform("org.junit:junit-bom:5.10.0") + testImplementation "org.junit.jupiter:junit-jupiter" + testImplementation "org.assertj:assertj-core:3.25.1" +} + +test { + useJUnitPlatform() + + testLogging { + exceptionFormat = "full" + showStandardStreams = true + events = ["passed", "failed", "skipped"] + } +} diff --git a/exercises/concept/making-the-grade/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/making-the-grade/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..e6441136f Binary files /dev/null and b/exercises/concept/making-the-grade/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/making-the-grade/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/making-the-grade/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..2deab89d5 --- /dev/null +++ b/exercises/concept/making-the-grade/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/exercises/concept/making-the-grade/gradlew b/exercises/concept/making-the-grade/gradlew new file mode 100644 index 000000000..1aa94a426 --- /dev/null +++ b/exercises/concept/making-the-grade/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/exercises/concept/making-the-grade/gradlew.bat b/exercises/concept/making-the-grade/gradlew.bat new file mode 100644 index 000000000..25da30dbd --- /dev/null +++ b/exercises/concept/making-the-grade/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/exercises/concept/making-the-grade/src/main/java/MakingTheGrade.java b/exercises/concept/making-the-grade/src/main/java/MakingTheGrade.java new file mode 100644 index 000000000..2f7a7b529 --- /dev/null +++ b/exercises/concept/making-the-grade/src/main/java/MakingTheGrade.java @@ -0,0 +1,28 @@ +import java.util.List; + +class MakingTheGrade { + + static int countFailedStudents(List studentScores) { + throw new UnsupportedOperationException("Please implement the (static) MakingTheGrade.countFailedStudents() method"); + } + + static int getAverageScoreOfStudents(List studentScores, int numberOfStudents) { + throw new UnsupportedOperationException("Please implement the (static) MakingTheGrade.getAverageScoreOfStudents() method"); + } + + static List letterGrades(List studentScores, List studentNames) { + throw new UnsupportedOperationException("Please implement the (static) MakingTheGrade.letterGrades() method"); + } + + static List studentRanking(List studentScores, List studentNames) { + throw new UnsupportedOperationException("Please implement the (static) MakingTheGrade.studentRanking() method"); + } + + static int countOddScores(List studentScores) { + throw new UnsupportedOperationException("Please implement the (static) MakingTheGrade.countOddScores() method"); + } + + static int evaluateChallengingExam(List studentScores) { + throw new UnsupportedOperationException("Please implement the (static) MakingTheGrade.evaluateChallengingExam() method"); + } +} diff --git a/exercises/concept/making-the-grade/src/test/java/MakingTheGradeTest.java b/exercises/concept/making-the-grade/src/test/java/MakingTheGradeTest.java new file mode 100644 index 000000000..edbb10194 --- /dev/null +++ b/exercises/concept/making-the-grade/src/test/java/MakingTheGradeTest.java @@ -0,0 +1,184 @@ +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class MakingTheGradeTest { + + @Test + @Tag("task:1") + @DisplayName("All students scored above 40") + void testAllStudentsScoredAbove40() { + assertThat(MakingTheGrade.countFailedStudents(List.of(50, 60, 70, 80, 90, 100))).isEqualTo(0); + } + + @Test + @Tag("task:1") + @DisplayName("One student failed the exam") + void testOneStudentFailedTheExam() { + assertThat(MakingTheGrade.countFailedStudents(List.of(39, 100, 90, 96, 73))).isEqualTo(1); + } + + @Test + @Tag("task:1") + @DisplayName("Multiple students failed the exam") + void testMultipleStudentsFailedTheExam() { + assertThat(MakingTheGrade.countFailedStudents(List.of(20, 10, 15, 35, 50, 60, 85))).isEqualTo(4); + } + + @Test + @Tag("task:2") + @DisplayName("Getting the average of 10 students") + void testGettingTheAverageOf10Students() { + assertThat( + MakingTheGrade.getAverageScoreOfStudents(List.of(40, 70, 80, 20, 39, 50, 100, 90, 66, 15, 79), 10) + ).isEqualTo(57); + } + + @Test + @Tag("task:2") + @DisplayName("Getting the average of 5 students, with multiple failed scores") + void testGettingTheAverageOf5StudentsWithMultipleFailedScores() { + assertThat( + MakingTheGrade.getAverageScoreOfStudents(List.of(33, 22, 11, 20, 39, 90, 100, 90, 95, 87, 75, 74, 13), 5) + ).isEqualTo(25); + } + + @Test + @Tag("task:2") + @DisplayName("Getting the average of 7 students, without failed scores") + void testGettingTheAverageOf7StudentsWithoutFailedScores() { + assertThat( + MakingTheGrade.getAverageScoreOfStudents(List.of(70, 60, 65, 55, 95, 100, 80, 70, 20, 30, 15, 100, 50), 7) + ).isEqualTo(75); + } + + @Test + @Tag("task:3") + @DisplayName("First student exceeds the score limit for the letter") + void testFirstStudentExceedTheScoreForTheLetter() { + assertThat( + MakingTheGrade.letterGrades( + List.of(100, 20, 53, 91), + List.of("Joci", "Sara", "Bern", "Fred")) + ).isEqualTo(List.of("Joci")); + } + + @Test + @Tag("task:3") + @DisplayName("The sum of the scores of the first three students are lower than 95") + void testSumOfFirstThreeStudentsLowerThan95() { + assertThat( + MakingTheGrade.letterGrades( + List.of(20, 40, 30, 85), + List.of("Jan", "Kora", "Sara", "Peter")) + ).isEqualTo(List.of("Jan", "Kora", "Sara")); + } + + @Test + @Tag("task:3") + @DisplayName("The sum of the scores of the first two students exceed 95") + void testSumOfFirstTwoStudentsExceed95() { + assertThat( + MakingTheGrade.letterGrades( + List.of(50, 46, 100, 15), + List.of("Cole", "Mason", "Enzo", "Connor")) + ).isEqualTo(List.of("Cole")); + } + + @Test + @Tag("task:4") + @DisplayName("Creating an all exceeded students ranking") + void testAllStudentsExceededRanking() { + List answer = List.of( + "1. Joci: 100", "2. Sara: 99", "3. Kora: 90", + "4. Jan: 84", "5. John: 66", "6. Bern: 53", "7. Fred: 47"); + + assertThat( + MakingTheGrade.studentRanking( + List.of(100, 99, 90, 84, 66, 53, 47), + List.of("Joci", "Sara", "Kora", "Jan", "John", "Bern", "Fred")) + ).isEqualTo(answer); + } + + @Test + @Tag("task:4") + @DisplayName("Creating an all failed students ranking") + void testAllStudentsFailedRanking() { + List answer = List.of( + "1. Kai: 35", "2. Kevin: 30", "3. Erling: 29", "4. Jude: 26", + "5. Benjamin: 19", "6. Malo: 13", "7. Moises: 5"); + + assertThat( + MakingTheGrade.studentRanking( + List.of(35, 30, 29, 26, 19, 13, 5), + List.of("Kai", "Kevin", "Erling", "Jude", "Benjamin", "Malo", "Moises")) + ).isEqualTo(answer); + } + + @Test + @Tag("task:4") + @DisplayName("Giving empty students and score lists") + void testEmptyLists() { + assertThat( + MakingTheGrade.studentRanking(List.of(), List.of()) + ).isEqualTo(List.of()); + } + + @Test + @Tag("task:5") + @DisplayName("Three student scores were odd after the correction of the math tests") + void testThreeOddScores() { + assertThat( + MakingTheGrade.countOddScores(List.of(20, 35, 40, 10, 39, 77)) + ).isEqualTo(3); + } + + @Test + @Tag("task:5") + @DisplayName("None of the scores are odd") + void testNoneOfTheScoresAreOdd() { + assertThat( + MakingTheGrade.countOddScores(List.of(20, 40, 60, 80, 10)) + ).isEqualTo(0); + } + + @Test + @Tag("task:5") + @DisplayName("All the scores are odd") + void testAllTheScoresAreOdd() { + assertThat( + MakingTheGrade.countOddScores(List.of(11, 33, 55, 77, 99)) + ).isEqualTo(5); + } + + @Test + @Tag("task:6") + @DisplayName("Two students passed the exam before the first non-passing score") + void testTwoStudentsPassedTheExamBeforeTheNonPassingScore() { + assertThat( + MakingTheGrade.evaluateChallengingExam(List.of(45, 90, 15, 100, 70)) + ).isEqualTo(2); + } + + @Test + @Tag("task:6") + @DisplayName("None of the students passed the exam") + void testNoneOfTheStudentsPassedTheExam() { + assertThat( + MakingTheGrade.evaluateChallengingExam(List.of(5, 10, 25, 2, 37)) + ).isEqualTo(0); + } + + @Test + @Tag("task:6") + @DisplayName("All the students passed the exam") + void testAllTheStudentsPassedTheExam() { + assertThat( + MakingTheGrade.evaluateChallengingExam(List.of(90, 98, 75, 80, 100)) + ).isEqualTo(5); + } +} diff --git a/exercises/settings.gradle b/exercises/settings.gradle index 916d7dd7f..962bd3765 100644 --- a/exercises/settings.gradle +++ b/exercises/settings.gradle @@ -15,6 +15,7 @@ include 'concept:karls-languages' include 'concept:lasagna' include 'concept:log-levels' include 'concept:logs-logs-logs' +include 'concept:making-the-grade' include 'concept:need-for-speed' include 'concept:remote-control-competition' include 'concept:salary-calculator'