diff --git a/README.md b/README.md index 290ef50..73650bf 100644 --- a/README.md +++ b/README.md @@ -1,91 +1,37 @@ -# MP3 Player - Second Weekend Assignment -You are going to implement an MP3 player. +# MP3 Player : +this project suppose to demonstrate simple MP3 Player. +![image](https://user-images.githubusercontent.com/89573774/132813316-8c310d9f-ef3a-4223-bf49-b59422ba651a.png) -## Instructions -1. Fork this repo into your account. -2. Clone the forked repo to your computer. -3. Execute `npm install` in the project folder to install the [tests](#testing). -4. Create a new git branch for your work. -5. Complete the project [requirements](#requirements). -6. Remember to push your commits regularly to GitHub. -7. Submit your work (explanation [below](#submission)) -8. Good luck & have fun! +## Basic functions you should know about: +- `playSong` - Gets a song ID and number of song to play automatically(optional), and plays it by printing it's data. +- `removeSong` - Gets a song ID, and removes it from the player (from songs and playlists). +- `addSong` - Gets a title, album, artist, duration(`mm:ss`) & ID(optional). +- `removePlaylist` - Gets a playlist ID. Remove the playlist from the player. +- `createPlaylist` - Gets a name & ID(optional). Creates a new, empty playlist with the given details. +- `playPlaylist` - Gets a playlist ID. Plays all songs in the playlist. +- `editPlaylist` - Gets a playlist ID & a song ID: -If the song ID exists in the playlist, removes it. + -If it was the only song in the playlist, also deletes the playlist. + -If the song ID does not exist in the playlist, adds it to the end of the playlist. +- `playlistDuration` - Gets a playlist ID. Returns the total duration of the entire playlist. +- `searchByQuery` - Gets a query string. search in songs(title,album and artist) and playlists. +- `searchByDuration` - Gets a duration in `mm:ss` format (for example 01:03). Returns the song, or playlist, with the closest duration to what was given. -## Requirements -The player itself is an object that has: -- `songs`: an array of songs -- `playlists`: an array of playlists -- `playSong`: a method that plays a song. -It receives a song object and should print the following format `"Playing {song.title} from {song.album} by {song.artist} | {song.duration}."` (replace the stuff inside the `{}` with the real values). -The song duration should be in `mm:ss` format (for example 02:40). +__Note__: The functions are not yet merge to the main branch. -A song object has: -- `id`: a unique ID (a number) -- `title`: a title -- `album`: album title -- `artist`: artist name -- `duration`: duration (number, in seconds) -A playlist object has: -- `id`: a unique ID (a number) -- `name`: a name -- `songs`: an array of song IDs +## Additions +- `shufflePlaylist` -play any playlist in random order. +- `autoPlay` - automatically play next song.(insted of adding it as new function I updated playSong so you can choose how many song you want it to play automatically(randomly),if you don't choose it plays only the song that match the ID.) -You are asked to implement the following functions: -- `playSong` - Gets a song ID. Uses `player.playSong` to play the song with the given ID. -- `removeSong` - Gets a song ID. Removes the song with the given ID from the player (from songs and playlists). -- `addSong` - Gets a title, album, artist, duration & ID. Adds a new song with given properties to the player. The ID is optional, and if omitted should be automatically generated. The song duration should be in `mm:ss` format (for example 06:27). Returns the ID of the new song. -- `removePlaylist` - Gets a playlist ID. Remove the playlist with the given ID from the player (does not delete the songs inside it). -- `createPlaylist` - Gets a name & ID. Creates a new, empty playlist with the given details. The ID is optional, and if omitted should be automatically generated. Returns the ID of the new playlist. -- `playPlaylist` - Gets a playlist ID. Plays all songs in the specified playlist, in the order the appear in the playlist. -- `editPlaylist` - Gets a playlist ID & a song ID. If the song ID exists in the playlist, removes it. If it was the only song in the playlist, also deletes the playlist. If the song ID does not exist in the playlist, adds it to the end of the playlist. -- `playlistDuration` - Gets a playlist ID. Returns the total duration of the entire playlist with the given ID. -- `searchByQuery` - Gets a query string. Returns a results object, which has: - - `songs`: an array of songs in which either title or album or artist contain the query string. The songs should be sorted by their titles. - - `playlists`: an array of playlists in which the name contains the query string. The playlists should be sorted by their names. - - The comparison in both cases should be case-insensitive. -- `searchByDuration` - Gets a duration in `mm:ss` format (for example 11:03). Returns the song, or playlist, with the closest duration to what was given. +__Note__: The functions are not yet merge to the main branch. -## Testing -We have added some automated tests for you to use. They will help you make sure your code covers the requirements. +## bugs /errors +- The autoPlay adittion choose the songs the next song randomly from all the songs in the player…so if you don't have many songs it will probably repeat the same songs all the time! maybe even 2 or 3 times in a row. -To run the tests, execute `npm run test` in the project folder. -__Note__: These tests might not cover everything. Don't just count on them. You should remain responsible and vigilant for other possible edge-cases. +### If you have anything to add or comment I would love it. -## Grading -Your work will be graded based on the following considerations: -- The number of automatic tests you pass -- Readable and ordered code - - Spacing & indentation - - Indicative vairable/function names - - Comments (where necessary) -- Proper use of Git - - Granular commits - - Descriptive commit messages -- Extra features you might have added - - -## Submission -1. On GitHub, open a pull request from your branch to the main branch. -2. __Do not merge the pull request!__ -3. Add the user `Cyber4sPopo` as collaborator to your repo. -4. Submit a link to the pull request in Google Classroom. - - -## Important Tip -Try to work in small iterations. You've got a big and complex task ahead of you. Break it down into smaller tasks. Concentrate on making small progress every time. Do it step by step. - - -## Remarks -- The player object must be stored in a global variable called `player`. -- The function, method & property names should be __exactly__ as described above (for the tests to function). -- __Avoid code duplication!__ You are free to add as many extra functions as you like. -- Pay attention to edge-cases! Your code should throw errors when the user tries to do something invalid (delete a song that doesn't exist, etc.). -- You can use all the material you've learned so far, including extras you've learned on your own. -- Write your code in the `index.js` file. It contains a template which you can use as the basis for your code. \ No newline at end of file diff --git a/index.js b/index.js index 10f4784..439cdbc 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,4 @@ +"use strict" const player = { songs: [ { @@ -48,50 +49,186 @@ const player = { { id: 5, name: 'Israeli', songs: [4, 5] }, ], playSong(song) { - console.log(/* your code here */) - }, + console.log(`Playing ${song.title} from ${song.album} by ${song.artist} | ` + +((Math.floor(song.duration/60))<10? "0": "")+`${Math.floor(song.duration/60)}:` +((song.duration%60)<10? "0": "")+`${song.duration%60}.`) + } +} + +function findSong(id){ + for(let song of player.songs){ + if (song.id===id){ + return song; + } + } + throw "ID not found"; +} + +function findPlaylist(id){ + for(let Playlist of player.playlists){ + if (Playlist.id===id){ + return Playlist; + } + } + throw "ID not found"; } function playSong(id) { - // your code here + player.playSong(findSong(id)); } function removeSong(id) { - // your code here + player.songs.splice(player.songs.indexOf(findSong(id)),1); + for(let playlist of player.playlists){ + playlist.songs.splice(playlist.songs.indexOf(id),1) + } +} + +let newSongId=10; +function generateSongId(){ + newSongId+=1; + return newSongId; +} + +function durationToSeconds(duration){ + checkDurationInput(duration) + return((parseInt(duration[0])*10)+parseInt(duration[1]))*60 + +parseInt(duration[3]*10)+parseInt(duration[4]) +} + +function checkDurationInput(duration){ // checks digits(maximum is 59:59/minimum is 00:00),:,length. + if(0<=parseInt(duration[0])&&parseInt(duration[0])<6&&0<=parseInt(duration[1])&&parseInt(duration[1])<=9 + &&duration[2]===":"&&0<=parseInt(duration[3])&&parseInt(duration[3])<6&&0<=parseInt(duration[4]) + &&parseInt(duration[4])<=9&&duration.length===5){ + return true + }else throw 'Duration is not in the correct format...This is the format-"mm:ss" (for example 03:13)' } -function addSong(title, album, artist, duration, id) { - // your code here +function addSong(title, album, artist, duration, id=generateSongId()) { + try{ + findSong(id) + }catch(err) { + player.songs.push({"id":id, + "title": title, + "album": album, + "artist": artist, + "duration": durationToSeconds(duration), + }) + return id; + } + throw "ID taken" } function removePlaylist(id) { - // your code here + player.playlists.splice(player.playlists.indexOf(findPlaylist(id)),1); } -function createPlaylist(name, id) { - // your code here +let newPlaylistId=3 +function generatePlaylistId(){ + newPlaylistId+=1 + return newPlaylistId +} + +function createPlaylist(name, id=generatePlaylistId()) { + try{ + findPlaylist(id) + }catch(err) { + player.playlists.push({ "id":id , "name": name, "songs": [] }) + return id; + } + throw "ID taken" } function playPlaylist(id) { - // your code here + for(let songId of findPlaylist(id).songs){ + playSong(songId) + } } -function editPlaylist(playlistId, songId) { - // your code here +function editPlaylist(PlaylistId, songId) { // to check readability!! + let playlistIndex=player.playlists.indexOf(findPlaylist(PlaylistId)); + findSong(songId); + if(player.playlists[playlistIndex].songs.indexOf(songId)===(-1)){ + player.playlists[playlistIndex].songs.push(songId); + }else{ + player.playlists[playlistIndex].songs.splice(player.playlists[playlistIndex].songs.indexOf(songId),1); + } + if(player.playlists[playlistIndex].songs.length===0){ + removePlaylist(PlaylistId); + } } function playlistDuration(id) { - // your code here + let plDuration=0; + for(let songID of findPlaylist(id).songs){ + plDuration+=(findSong(songID).duration); + } + return (plDuration); } function searchByQuery(query) { - // your code here + const QUERY=query.toUpperCase(); + const queryObj={"songs":[],"playlists":[]} + for(let song of player.songs) { + if(song.title.toUpperCase().includes(QUERY) + ||song.artist.toUpperCase().includes(QUERY) + ||song.album.toUpperCase().includes(QUERY)) + { + queryObj.songs.push(song); + } + } + for(let playlist of player.playlists){ + if(playlist.name.toUpperCase().includes(QUERY)){ + queryObj.playlists.push(playlist); + } + } + queryObj.songs.sort(sortByTitle); + queryObj.playlists.sort(sortByName); + return queryObj; } -function searchByDuration(duration) { - // your code here +function sortByTitle(a, b) { + let titleA = a.title.toUpperCase(); + let titleB = b.title.toUpperCase(); + if (titleA < titleB) { + return -1; + } + if (titleA > titleB) { + return 1; + } } +function sortByName(a, b) { + let nameA = a.name.toUpperCase(); + let nameB = b.name.toUpperCase(); + if (nameA < nameB) { + return -1; + } + if (nameA > nameB) { + return 1; + } +} + +function searchByDuration(duration) { + checkDurationInput(duration); + let sec=durationToSeconds(duration); + let allDurationArr=[]; + let matchingArr=[]; //matching array that saves the song and playlist parallel(they will have the same index) to the duration array(allDurationArr) + let closestDuration=player.songs[0].duration; + for(let song of player.songs){ + allDurationArr.push(song.duration); + matchingArr.push(song); + } + for(let playlist of player.playlists){ + allDurationArr.push(playlistDuration(playlist.id)); + matchingArr.push(playlist); + } + for(let dur of allDurationArr){ + if(Math.abs(dur-sec)