####INFO::Solve this challenge using a project in your editor
The most recently played song is at the start of the list, the least recently played song is the last in the list.
- A recently-used-list is initially empty.
- Songs in the list are unique, so repeatedly played songs should only appear once in the list
- Songs can be looked up by index, which counts from zero.
Optional extras:
- Empty song names are not allowed.
- Add a limit to the number of songs the list contains, with the least recently added items dropped when that limit is reached.
Open the playground project you created at the start of the workshop. Or create it now with the command line lein new playground
.
Add the following two files to the project
src/playground/recent-song-list.clj
test/playground/recent-song-list-test.clj
We are writing our tests with the clojure.test
library so we need to include that first
Open test/playground/recent-song-list-test.clj
file in your editor and update the namespace definition to include clojure.test
(ns playground.recent-song-list-test
(:require [clojure.test :refer :all]
[playground.recent-song-list :refer :all]))
At any time we can use the run-tests
function to get a report back on all of the tests in our current namespace (recent-song-list
)
(run-tests)
In the source file,
src/playground/recent-song-list.clj
, define a name for your collection of recent songsYou can use an empty collection to start with. Which collection type will you use though?
(def recent-songs [])
####Note::Write a test to check a song-list exists Write a test to see if a recent song list exists.
This is an opportunity to think about what kind of data structure you want to use to hold your recent song list.
A simple test that checks for a recent-songs
list, checking
(deftest song-list-exists-test
(testing "Does a recent song list exist"
(is (vector? recent-songs))))
####Note::Write a test to check the song-list is empty The recent song list should be empty to start with.
A simple test that compares an empty vector with the value of recent-songs
(deftest song-list-empty-test
(testing "Is song list empty if we haven't added any songs"
(is
(= [] recent-songs))))
Here is the same test using the empty?
function instead of the =
function.
(deftest song-list-empty-test-2
(testing "Is song list empty if we haven't added any songs"
(is
(empty? recent-songs))))
####Hint:: You could use either of these tests to replace the song list exists test, as these tests would fail if the song list did not exist.
Add a song to the collection, for example
Tubular Bells - Mike Oldfield
(deftest adding-songs-test
(testing "add song returns a song list with entries"
(is
(not (empty?
(add-song "Barry Manilow - Love on the rocks" recent-songs)))))
(testing "add multiple song returns a song list with entries"
(is
(not (empty?
(->> recent-songs
(add-song "Barry Manilow - Love on the rocks")
(add-song "Phil Colins - Sususudio" )))))))
This suggested solution defines our recent songs as an empty vector.
The add-song
function takes the name of a song and the song list to which it will be added.
A Thread-last macro ->>
is used to pass the song list over two functions.
The song-list
is first passed to the remove
expression as its last argument. This expression will remove any occurrence of the new song we want to add from the song-list
.
The results of the remove
expression are then passed to the cons
expression as its last argument. The cons
expression simply adds the new song to the start of the list, making it the most recent song.
(def recent-songs [])
(defn add-song [song song-list]
(->> song-list
(remove #(= song %))
(cons song)))