-
-
Notifications
You must be signed in to change notification settings - Fork 656
[V3] Add Concept Exercise: While and Switch #1073
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
SleeplessByte
merged 24 commits into
exercism:main
from
junedev:add-concept-exercise-while
Apr 11, 2021
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
16ddcb4
add new entries to config
junedev 53f3a0e
add while loops concept
junedev c00f54a
finish while loop concept
junedev 5535879
fix line breaks
junedev d49d64e
add concept switch
junedev 83f7c11
update config
junedev f1f6646
Merge branch 'main' into add-concept-exercise-while
junedev 8589693
add config.json to concepts
junedev 100993b
general setup for new exercise
junedev 020a609
rename exercise
junedev 49c9e21
add instructions and exemplar solution
junedev 32dd9bd
add test and stub file
junedev 521199b
add design and hints
junedev c258a14
minor fixes
junedev 8adcde6
Merge branch 'main' into add-concept-exercise-while
junedev d2fea20
some minor text changes
junedev f70fa10
Merge branch 'main' into add-concept-exercise-while
junedev dcc6d4a
run sync script
junedev f95a4ec
Merge branch 'main' into add-concept-exercise-while
junedev 59a6d0d
Apply suggestions from code review
junedev af1a258
more text changes according to review
junedev 20a7e78
Merge branch 'main' into add-concept-exercise-while
junedev c736ddd
run sync
junedev 7c34ded
add scope section
junedev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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,5 @@ | ||
| { | ||
| "blurb": "Besides the if-statement, JavaScript also has a switch-statement to conditionally execute logic. It is used when a single variable needs to be compared to multiple variants.", | ||
| "authors": ["junedev"], | ||
| "contributors": [] | ||
| } |
This file contains hidden or 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,85 @@ | ||
| # About | ||
|
|
||
| ## General Syntax | ||
|
|
||
| Besides the if-statement, JavaScript also has a switch-statement to conditionally execute logic. | ||
| It is used when a single variable needs to be compared to multiple variants. | ||
| The comparison is done by checking for strict equality (`===`), see [concept comparison][concept-comparison]. | ||
| For some variable `x`, the switch statement in JavaScript has the following syntax. | ||
|
|
||
| <!-- prettier-ignore-start --> | ||
| ```javascript | ||
| switch (x) { | ||
| case option1: | ||
| // code that is executed when "x === option1" is true | ||
| break; | ||
| case option2: | ||
| // code that is executed when "x === option2" is true | ||
| break; | ||
| default: | ||
| // code that is executed when x does not equal any of the options | ||
| } | ||
| ``` | ||
| <!-- prettier-ignore-end --> | ||
|
|
||
| The `default` case is optional and used in case you want to execute some code if none of the other options match the variable. | ||
|
|
||
| ## Fallthrough by Default | ||
|
|
||
| The `break` statements above are needed because by default all cases are "fallthrough" in JavaScript. | ||
| That means without any `break` statement all the code in the cases below the first matching option would be executed even though `x` did not match those options. | ||
| This "fallthrough by default" behavior is a common pitfall when using `switch` in JavaScript. | ||
| Inside a function, `return` can also be used instead of `break` to avoid this problem. | ||
|
|
||
| You can use the fallthrough behavior to your advantage when you want to apply the same code for multiple cases. | ||
| You can find an example of this in the [MDN documentation][mdn-group-cases]. | ||
|
|
||
| ## Scope | ||
|
|
||
| By default the variables in the different `case` statements share the same scope. | ||
| This can lead to unexpected behavior. | ||
| For example due to copying and pasting a case, you could end up with a `let message` declaration in two cases which results in an error, see [MDN documentation][mdn-switch-scope]. | ||
| To avoid problems due to the shared scope, you can create a separate scope for each case statement by adding code blocks with curly brackets for each case. | ||
|
|
||
| ```javascript | ||
| switch (x) { | ||
| case option1: { | ||
| // Variables declared here are contained to this case. | ||
| break; | ||
| } | ||
| case option2: { | ||
| // ... | ||
| break; | ||
| } | ||
| default: { | ||
| // ... | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Using Expressions | ||
|
|
||
| Instead of a variable `x`, you can also use an expression. | ||
| That expression is evaluated once at the beginning of the switch statement and the result compared against the cases. | ||
| A common use of this is a "type switch" that executes different code depending on the type of a variable. | ||
|
|
||
| <!-- prettier-ignore-start --> | ||
| ```javascript | ||
| switch (typeof x) { | ||
| case 'string': | ||
| // code that is executed when x is a string | ||
| break; | ||
| case 'number': | ||
| // code that is executed when x is a number | ||
| break; | ||
| default: | ||
| // code that is executed when x has some other type | ||
| } | ||
| ``` | ||
| <!-- prettier-ignore-end --> | ||
|
|
||
| The options can be expressions as well. | ||
|
|
||
| [concept-comparison]: /tracks/javascript/concepts/comparison | ||
| [mdn-group-cases]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch#methods_for_multi-criteria_case | ||
| [mdn-switch-scope]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch#block-scope_variables_within_switch_statements | ||
This file contains hidden or 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,30 @@ | ||
| # Introduction | ||
|
|
||
| Besides the if-statement, JavaScript also has a switch-statement to conditionally execute logic. | ||
| It is used when a single variable needs to be compared to multiple variants. | ||
| The comparison is done by checking for strict equality (`===`), see [concept comparison][concept-comparison]. | ||
| For some variable `x`, the switch statement in JavaScript has the following syntax. | ||
|
|
||
| <!-- prettier-ignore-start --> | ||
| ```javascript | ||
| switch (x) { | ||
| case option1: | ||
SleeplessByte marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // code that is executed when "x === option1" is true | ||
| break; | ||
| case option2: | ||
| // code that is executed when "x === option2" is true | ||
| break; | ||
| default: | ||
| // code that is executed when x does not equal any of the options | ||
| } | ||
| ``` | ||
| <!-- prettier-ignore-end --> | ||
|
|
||
| The `default` case is optional and used when you want to execute some code if none of the other options match the variable. | ||
|
|
||
| The `break` statements above are needed because by default all cases are "fallthrough" in JavaScript. | ||
| That means that without any `break` statement all the code in the cases below the first matching option would be executed even though `x` did not match those options. | ||
| This "fallthrough by default" behavior is a common pitfall when using `switch` in JavaScript. | ||
| Inside a function, `return` can also be used instead of `break` to avoid this problem. | ||
|
|
||
| [concept-comparison]: /tracks/javascript/concepts/comparison | ||
This file contains hidden or 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,6 @@ | ||
| [ | ||
| { | ||
| "url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch", | ||
| "description": "MDN: Switch Statement" | ||
| } | ||
| ] |
This file contains hidden or 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,5 @@ | ||
| { | ||
| "blurb": "Execute code repeatedly as long as a certain condition is fulfilled. Depending on when that condition should be checked, you can use a while or a do-while loop in JavaScript.", | ||
| "authors": ["junedev"], | ||
| "contributors": [] | ||
| } |
This file contains hidden or 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,89 @@ | ||
| # About | ||
|
|
||
| ## General Syntax | ||
|
|
||
| With a while loop you can execute code repeatably as long as a certain condition is fulfilled. | ||
|
|
||
| It is written with the `while` keyword followed by a condition wrapped in round brackets and a code block that contains the _body_ of the loop wrapped in curly brackets. | ||
|
|
||
| ```javascript | ||
| while (condition) { | ||
| // code that is executed repeatedly as long as the condition is true | ||
| } | ||
| ``` | ||
|
|
||
| JavaScript also has a do-while loop. | ||
| Here the condition is checked after the loop body was executed. | ||
| This is useful when the condition depends on evaluations done in the body. | ||
|
|
||
| ```javascript | ||
| do { | ||
| // The code here will always be executed once and then | ||
| // repeatedly while the condition is true. | ||
| } while (condition); | ||
| ``` | ||
|
|
||
| ## Break | ||
|
|
||
| Inside a loop body you can use the `break` keyword to stop the execution of the loop entirely. | ||
| This is often used in combination with `true` as condition. | ||
| With that, you can control when the loop should stop from any place inside the loop body. | ||
|
|
||
| ```javascript | ||
| const winningNumber = 7; | ||
|
|
||
| while (true) { | ||
| const num = readUserGuess(); | ||
| if (num === winningNumber) { | ||
| break; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The `break` keyword cannot be used inside a function that is nested in the loop, see the [MDN documentation][mdn-break-in-function] for an example. | ||
|
|
||
| ## Continue | ||
|
|
||
| In contrast to `break`, the keyword `continue` only stops the execution of the current iteration and continues with the next one. | ||
| With `continue` you can often avoid wrapping big parts of the loop body in an if-statement. | ||
|
|
||
| ```javascript | ||
| let i = 0; | ||
|
|
||
| while (i < 100) { | ||
| i = i + 2; | ||
|
|
||
| if (i % 3 === 0) { | ||
| continue; | ||
| } | ||
|
|
||
| // The code here will only executed when i was not divisible | ||
| // by 3 in the check above. | ||
| } | ||
| ``` | ||
|
|
||
| ## Infinite Loops | ||
|
|
||
| A loop that is (theoretically) repeated forever is created when the loop condition is always fulfilled and no break or return statement is reached in the loop body. | ||
| The execution has to be terminated from the outside. | ||
| Depending on the environment in which such code runs, this will be done automatically or needs a manual intervention. | ||
|
|
||
| ```javascript | ||
| let i = 0; | ||
|
|
||
| while (i < 100) { | ||
| if (i % 3 === 0) { | ||
| continue; | ||
| } | ||
|
|
||
| i = i + 2; | ||
| } | ||
|
|
||
| // This loop runs forever since the variable i does not change | ||
| // anymore after it is divisible by 3 the first time. | ||
| ``` | ||
|
|
||
| Spotting infinite loops might seem trivial in this toy example, but is not always that easy with more complex code. | ||
| It is good practice to thoroughly think about whether your condition eventually becomes false or whether your break or return statement is actually reached. | ||
|
|
||
| [mdn-break-in-function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break#break_within_functions |
This file contains hidden or 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,40 @@ | ||
| # Introduction | ||
|
|
||
| With a while loop you can execute code repeatably as long as a certain condition is fulfilled. | ||
| It is written with the `while` keyword followed by a condition wrapped in round brackets and a code block that contains the _body_ of the loop wrapped in curly brackets. | ||
|
|
||
| ```javascript | ||
| while (condition) { | ||
| // code that is executed repeatedly as long as the condition is true | ||
| } | ||
| ``` | ||
|
|
||
| JavaScript also has a do-while loop. | ||
| Here the condition is checked after the loop body was executed. | ||
| This is useful when the condition depends on the outcome of the code in the body. | ||
|
|
||
| ```javascript | ||
| do { | ||
| // The code here will always be executed once and then | ||
| // repeatedly while the condition is true. | ||
| } while (condition); | ||
| ``` | ||
|
|
||
| Inside a loop body you can use the `break` keyword to stop the execution of the loop entirely. | ||
| In contrast to this, the keyword `continue` only stops the execution of the current iteration and continues with the next one. | ||
| With `continue` you can often avoid wrapping big parts of the loop body in an if-statement. | ||
|
|
||
| ```javascript | ||
| let i = 0; | ||
|
|
||
| while (i < 100) { | ||
| i = i + 2; | ||
|
|
||
| if (i % 3 === 0) { | ||
| continue; | ||
| } | ||
|
|
||
| // The code here will only executed when i was not divisible | ||
| // by 3 in the check above. | ||
| } | ||
| ``` |
This file contains hidden or 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,18 @@ | ||
| [ | ||
| { | ||
| "url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while", | ||
| "description": "MDN: While Loop" | ||
| }, | ||
| { | ||
| "url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/do...while", | ||
| "description": "MDN: Do-While Loop" | ||
| }, | ||
| { | ||
| "url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break", | ||
| "description": "MDN: break" | ||
| }, | ||
| { | ||
| "url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/continue", | ||
| "description": "MDN: continue" | ||
| } | ||
| ] |
This file contains hidden or 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
This file contains hidden or 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,30 @@ | ||
| # Hints | ||
|
|
||
| ## 1. Determine how long it takes to mix a juice | ||
|
|
||
| - Set up a [switch statement][mdn-switch] for the `name` variable. | ||
| - The different cases should represent the different juice names. | ||
| - Use the `default` case to cover all other names. | ||
| - Remember that the cases are [fallthrough by default][mdn-fallthrough] so make sure you did something to prevent that behavior. | ||
|
|
||
| ## 2. Replenish the lime wedge supply | ||
|
|
||
| - Use a [while loop][mdn-while] to cut one lime after the other. | ||
| - Revisit the [arrays concept][concept-arrays] to find a way to remove the limes from the list in the correct order. | ||
| - Set up a [switch statement][mdn-switch] to get the number of wedges for a certain size of a lime. | ||
| - You need to keep track of two things, how many limes where already cut and how many wedges are still missing. | ||
| - You can combine two conditions for the loop using [logical operators][concept-booleans]. | ||
|
|
||
| ## 3. Finish up the shift | ||
|
|
||
| - Use a [do-while loop][mdn-do-while] to handle one order after the other. | ||
| - Revisit the [arrays concept][concept-arrays] to find a way to remove the drinks from the list in the correct order. | ||
| - You already have a function that determines the time it takes to prepare a drink, use it to reduce the time that is left accordingly. | ||
| - You can combine two conditions for the loop using [logical operators][concept-booleans]. | ||
|
|
||
| [mdn-switch]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch# | ||
| [mdn-fallthrough]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch#what_happens_if_i_forgot_a_break | ||
| [mdn-while]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while | ||
| [mdn-do-while]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/do...while | ||
| [concept-booleans]: /tracks/javascript/concepts/booleans | ||
| [concept-arrays]: /tracks/javascript/concepts/arrays |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.