-
-
Notifications
You must be signed in to change notification settings - Fork 45
Ozan's Playlist concept exercise #435
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
Merged
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
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
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 @@ | ||
| # Hints | ||
|
|
||
| ## General | ||
|
|
||
| These are all short and simple tasks. | ||
| If you find yourself writing several lines of code in a function, please stop and read the introduction. | ||
|
|
||
| ## 3. Add tracks | ||
|
|
||
| - Return tracks that are in either the playlist or the tracks to add. | ||
|
|
||
| ## 4. Delete tracks | ||
|
|
||
| - Tracks which are in the playlist but not the tracks to delete. | ||
|
|
||
| ## 5. Compare playlists | ||
|
|
||
| - Tracks which are in both playlists. | ||
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,86 @@ | ||
| # Instructions | ||
|
|
||
| Ozan is putting together a playlist for an upcoming roadtrip. He doesn"t want to hear the same track more than once, but the playlist has gotten so long that he"s having trouble remembering which tracks have already been added. | ||
|
|
||
| The API for Ozan"s music player only knows how to work with vectors. No explicit loops or if/else logic are possible. He needs your help! | ||
|
|
||
| ## 1. Remove duplicate tracks | ||
|
|
||
| Implement the `remove_duplicates` function, which takes a playlist as a _parameter_ and _returns_ a new playlist where all the tracks are unique. | ||
|
|
||
| ```R | ||
| > playlist <- c( | ||
| "Court and Spark - Joni Mitchell", | ||
| "Big Yellow Taxi - Joni Mitchell", | ||
| "Court and Spark - Joni Mitchell" | ||
| ) | ||
|
|
||
| > remove_duplicates(playlist) | ||
| [1] "Court and Spark - Joni Mitchell" "Big Yellow Taxi - Joni Mitchell" | ||
| ``` | ||
|
|
||
| ## 2. Check whether a track has already been added | ||
|
|
||
| Implement the `has_track` function, which takes a playlist and a track as _parameters_ and _returns_ a boolean that indicates whether the playlist contains the track. | ||
|
|
||
| ```R | ||
| > playlist <- c( | ||
| "The Fashion Show - Grace Jones", | ||
| "Dr. Funkenstein - Parliament" | ||
| ) | ||
|
|
||
| > has_track(playlist, "Dr. Funkenstein - Parliament") | ||
| [1] TRUE | ||
|
|
||
| > has_track(playlist, "Walking in the Rain - Grace Jones") | ||
| [1] FALSE | ||
| ``` | ||
|
|
||
| ## 3. Add tracks | ||
|
|
||
| Implement the `add_tracks` function, which takes a playlist and a vector of one or more tracks as _parameters_ and _returns_ a new playlist that includes the tracks. | ||
|
|
||
| ```R | ||
| > playlist <- c("Selma - Bijelo Dugme") | ||
|
|
||
| > playlist <- add_tracks(playlist, "Atomic Dog - George Clinton") | ||
| > playlist | ||
| [1] "Selma - Bijelo Dugme" "Atomic Dog - George Clinton" | ||
|
|
||
| > add_tracks(playlist, "Selma - Bijelo Dugme") | ||
| [1] "Selma - Bijelo Dugme" "Atomic Dog - George Clinton" | ||
|
|
||
| > add_tracks(playlist, c("The Chain - Fleetwood Mac", "Selma - Bijelo Dugme")) | ||
| [1] "Selma - Bijelo Dugme" "Atomic Dog - George Clinton" "The Chain - Fleetwood Mac" | ||
|
|
||
| ``` | ||
|
|
||
| ## 4. Delete tracks | ||
|
|
||
| Implement the `delete_tracks` function, which takes a playlist and one or more tracks as _parameters_ and _returns_ a new playlist that does not include the tracks. | ||
|
|
||
| ```R | ||
| > playlist <- c( | ||
| "The Treasure - Fra Lippo Lippi", | ||
| "After the Fall - Klaus Nomi" | ||
| ) | ||
|
|
||
| > playlist <- delete_tracks(playlist, "The Treasure - Fra Lippo Lippi") | ||
| > playlist | ||
| [1] "After the Fall - Klaus Nomi" | ||
|
|
||
| > delete_tracks(playlist, "I Feel the Magic - Belinda Carlisle") | ||
| [1] "After the Fall - Klaus Nomi" | ||
| ``` | ||
|
|
||
| ## 5. Compare playlists | ||
|
|
||
| Ozan meets a new friend and wonders how similar their tastes are. | ||
| Implement the `find_common_tracks` function, which takes two playlists and returns a new playlist containing only tracks present in both. | ||
|
|
||
| ```R | ||
| > playlist_1 <- c("Karma - Taylor Swift", "Tired - Adele") | ||
| > playlist_2 <- c("Andromeda - Weyes Blood", "Karma - Taylor Swift") | ||
| > find_common_tracks(playlist_1, playlist_2) | ||
| [1] "Karma - Taylor Swift" | ||
| ```` |
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,36 @@ | ||
| # Introduction | ||
|
|
||
| R has no separate Set datatype, instead using a variety of functions to perform similar operations on vectors. | ||
|
|
||
| The `%in%` operator tests for set membership. | ||
|
|
||
| ```R | ||
| 2 %in% 1:10 # TRUE | ||
| 12 %in% 1:10 # FALSE | ||
| ``` | ||
|
|
||
| Relevant functions include `unique` (to remove duplicates), plus `union()`, `intersect()`, `setdiff()` and `setequal()` to operate on pairs of sets. | ||
|
|
||
| ```R | ||
| > set_1 <- c("a", "b", "c", "b", "a") | ||
| > unique(set_1) # deduplicate | ||
| [1] "a" "b" "c" | ||
|
|
||
| > set_2 <- c('a', "c", "d") | ||
| > union(set_1, set_2) # values in either set | ||
| [1] "a" "b" "c" "d" | ||
|
|
||
| > intersect(set_1, set_2) # values in both sets | ||
| [1] "a" "c" | ||
|
|
||
| > setdiff(set_1, set_2) # values in set_1 but not set_2 | ||
| [1] "b" | ||
|
|
||
| > setdiff(set_2, set_1) # values in set_2 but not set_1 | ||
| [1] "d" | ||
|
|
||
| setequal(set_1, c("c", "b", "a", "b")) # are elements the same after deduplication? | ||
| [1] TRUE | ||
| ``` | ||
|
|
||
| In each case, `set_1` and `set_2` remain unchanged. |
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,20 @@ | ||
| { | ||
| "authors": [ | ||
| "colinleach" | ||
| ], | ||
| "files": { | ||
| "solution": [ | ||
| "ozans-playlist.R" | ||
| ], | ||
| "test": [ | ||
| "test_ozans-playlist.R" | ||
| ], | ||
| "exemplar": [ | ||
| ".meta/exemplar.R" | ||
| ] | ||
| }, | ||
| "forked_from": [ | ||
| "javascript/ozans-playlist" | ||
| ], | ||
| "blurb": "Use set operations to manage a playlist" | ||
| } |
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,24 @@ | ||
| # Design | ||
|
|
||
| ## Goal | ||
|
|
||
| The goal of this exercise is to introduce basic set operations in R. | ||
|
|
||
| ## Learning objectives | ||
|
|
||
| - Understand that base R uses vectors for set operations, with no dediicated class. | ||
| - Understand the use of `%in%`, `unique()`, `union()`, `intersect()` and `setdiff()`. | ||
|
|
||
| ## Out of scope | ||
|
|
||
| - Use of the `hashtable` package (or similar), though this is mentioned in `set-operations/about.md` which unlocks on completing this exercise. | ||
|
|
||
| ## Concepts | ||
|
|
||
| The Concepts this exercise unlocks are: | ||
|
|
||
| - None. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - `vectors` |
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,19 @@ | ||
| remove_duplicates <- function(playlist) { | ||
| unique(playlist) | ||
| } | ||
|
|
||
| has_track <- function(playlist, track) { | ||
| track %in% playlist | ||
| } | ||
|
|
||
| add_tracks <- function(playlist, tracks) { | ||
| union(playlist, tracks) | ||
| } | ||
|
|
||
| delete_tracks <- function(playlist, tracks) { | ||
| setdiff(playlist, tracks) | ||
| } | ||
|
|
||
| find_common_tracks <- function(playlist_1, playlist_2) { | ||
| intersect(playlist_1, playlist_2) | ||
| } |
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,14 @@ | ||
| remove_duplicates <- function(playlist) { | ||
| } | ||
|
|
||
| has_track <- function(playlist, track) { | ||
| } | ||
|
|
||
| add_tracks <- function(playlist, tracks) { | ||
| } | ||
|
|
||
| delete_tracks <- function(playlist, tracks) { | ||
| } | ||
|
|
||
| find_common_tracks <- function(playlist_1, playlist_2) { | ||
| } |
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,110 @@ | ||
| source("./ozans-playlist.R") | ||
| library(testthat) | ||
|
|
||
| # 1) remove_duplicates | ||
|
|
||
| test_that("1. works for a non-empty playlist", { | ||
| track_1 <- "Two Paintings and a Drum - Carl Cox" | ||
| track_2 <- "Leash Called Love - The Sugarcubes" | ||
| playlist <- c(track_1, track_2, track_1) | ||
| expected <- c(track_1, track_2) | ||
| expect_equal(remove_duplicates(playlist), expected) | ||
| }) | ||
|
|
||
| test_that("1. works for an empty playlist", { | ||
| playlist <- c() | ||
| expected <- c() | ||
| expect_equal(remove_duplicates(playlist), expected) | ||
| }) | ||
|
|
||
| # 2) has_track | ||
|
|
||
| test_that("2. returns true when the track is in the playlist", { | ||
| track_1 <- "Big Science - Laurie Anderson" | ||
| track_2 <- "Tightrope - Laurie Anderson" | ||
| playlist <- c(track_1, track_2) | ||
| expect_equal(has_track(playlist, track_1), TRUE) | ||
| }) | ||
|
|
||
| test_that("2. returns false when the track is not in the playlist", { | ||
| track_1 <- "Big Science - Laurie Anderson" | ||
| track_2 <- "Tightrope - Laurie Anderson" | ||
| playlist <- c(track_2) | ||
| expect_equal(has_track(playlist, track_1), FALSE) | ||
| }) | ||
|
|
||
| # 3) add_tracks | ||
|
|
||
| test_that("3. adds tracks that are not already in the playlist", { | ||
| track_1 <- "Jigsaw Feeling - Siouxsie and the Banshees" | ||
| track_2 <- "Feeling Good - Nina Simone" | ||
| playlist <- c() | ||
| expected <- c(track_1) | ||
| expect_equal(add_tracks(playlist, track_1), expected) | ||
| }) | ||
|
|
||
| test_that("3. does not add a track that is already in the playlist", { | ||
| track_1 <- "Jigsaw Feeling - Siouxsie and the Banshees" | ||
| track_2 <- "Feeling Good - Nina Simone" | ||
| playlist <- c(track_1, track_2) | ||
| expected <- c(track_1, track_2) | ||
| expect_equal(add_tracks(playlist, track_1), expected) | ||
| }) | ||
|
|
||
| test_that("3. add multiple tracks, some already in the playlist", { | ||
| track_1 <- "Jigsaw Feeling - Siouxsie and the Banshees" | ||
| track_2 <- "Feeling Good - Nina Simone" | ||
| track_3 <- "I Was an Eagle - Laura Marling" | ||
| playlist <- c(track_1, track_2) | ||
| expected <- c(track_1, track_2, track_3) | ||
| expect_equal(add_tracks(playlist, c(track_1, track_3)), expected) | ||
| }) | ||
|
|
||
| # 4) delete_tracks | ||
|
|
||
| test_that("4. works if the track is present in the playlist", { | ||
| track_1 <- "Ancestors - Tanya Tagaq" | ||
| track_2 <- "Take This Hammer - Lead Belly" | ||
| playlist <- c(track_1, track_2) | ||
| expected <- c(track_2) | ||
| expect_equal(delete_tracks(playlist, track_1), expected) | ||
| }) | ||
|
|
||
| test_that("4. works if the track is not present in the playlist", { | ||
| track_1 <- "Ancestors - Tanya Tagaq" | ||
| track_2 <- "Take This Hammer - Lead Belly" | ||
| playlist <- c(track_2) | ||
| expected <- c(track_2) | ||
| expect_equal(delete_tracks(playlist, track_1), expected) | ||
| }) | ||
|
|
||
| test_that("4. works for multiple tracks if some present in the playlist", { | ||
| track_1 <- "Ancestors - Tanya Tagaq" | ||
| track_2 <- "Take This Hammer - Lead Belly" | ||
| track_3 <- "With Or Without You - U2" | ||
| playlist <- c(track_1, track_2) | ||
| expected <- c(track_2) | ||
| expect_equal(delete_tracks(playlist, c(track_1, track_3)), expected) | ||
| }) | ||
|
|
||
| # 5) find_common_tracks | ||
|
|
||
| test_that("5. works when there is partial overlap", { | ||
| track_1 <- "Ancestors - Tanya Tagaq" | ||
| track_2 <- "Take This Hammer - Lead Belly" | ||
| track_3 <- "With Or Without You - U2" | ||
| playlist_1 <- c(track_1, track_2) | ||
| playlist_2 <- c(track_2, track_3) | ||
| expected <- c(track_2) | ||
| expect_equal(find_common_tracks(playlist_1, playlist_2), expected) | ||
| }) | ||
|
|
||
| test_that("5. works when there nothing in common", { | ||
| track_1 <- "Paranoid - Black Sabbath" | ||
| track_2 <- "Overkill - Motörhead" | ||
| track_3 <- "Gurre-Lieder - Schönberg" | ||
| track_4 <- "Gymnopédies - Satie" | ||
| playlist_1 <- c(track_1, track_2) | ||
| playlist_2 <- c(track_3, track_4) | ||
| expect_equal(length(find_common_tracks(playlist_1, playlist_2)), 0) | ||
| }) |
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if we need to have a complete list (from 1 to 5 here). I would venture a guess that it's not necessary, but that really is just a guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Point noted, but I'm curious to test whether hints need to be numbered consecutively from 1. Is it OK to merge this as-is and see how it looks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May as well give it a look to see how the website reacts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems absolutely fine. I think the Rails backend just looks for level-2 headers (starting with
##).