-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBackendImplementation.java
More file actions
198 lines (176 loc) · 7.88 KB
/
Copy pathBackendImplementation.java
File metadata and controls
198 lines (176 loc) · 7.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.io.BufferedReader;
import java.io.FileReader;
/**
* Class to implement the functions of several backend functions for a song app
*/
public class BackendImplementation implements BackendInterface{
public IterableSortedCollection<SongInterface> data;
private int minSpeed = 0;
private int[] energyRange;
public BackendImplementation(IterableSortedCollection<SongInterface> tree) {
// what do I do with this
// storing the value of the tree passed in as an argument
data = tree;
}
/**
* Loads data from the .csv file referenced by filename.
* @param filename is the name of the csv file to load data from
* @throws IOException when there is trouble finding/reading file
*/
@Override
public void readData(String filename) throws IOException {
// creates a file object, file reader, buffered reader, and arraylist to read and stores csv data
//file path - TODO: may need to be changed when added to the Version Control!!!!!!
//String file = "C:\\Users\\Noahb\\eclipse-workspace\\CS400_P105_RoleCode\\src\\" + filename;
String file = filename; // for the VM
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr); // buffered reader for the csv file
List<String> songData = null; // the current song data
// current line in csv file
String song = br.readLine();
while (song != null) {
// uses a regex to ignore all commands between quotes
songData = Arrays.asList(song.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1));
// replaces the leftover quotes in song titles with blanks
songData.set(0, songData.get(0).replace("\"", ""));
// prevents adding the column headers as a song
if (songData.get(0).equals("title") == false) {
// adds the song's data to the List as an object type Song
data.insert(new Song(songData));
}
// moves on to the next line
song = br.readLine();
}
br.close();
}
/**
* Retrieves a list of song titles for songs that have an Energy rating
* within the specified range (sorted by Energy in ascending order). If
* a minSpeed filter has been set using filterFastSongs(), then only songs
* with speeds greater than or equal to minSpeed should be included in the
* list that is returned by this method.
*
* Note that either this energy range, or the resulting unfiltered list
* of songs should be saved for later use by the other methods defined in
* this class.
*
* @param low is the minimum Energy rating of songs in the returned list
* @param hight is the maximum Energy rating of songs in the returned list
* @return List of titles for all songs in specified range
*/
@Override
public List<String> getRange(int low, int high) { // MAYBE UES ITERATOR AND STARTING POINT
// saves the range
if (energyRange != null) {
energyRange[0] = low;
energyRange[1] = high;
} else
energyRange = new int[]{low,high};
// arrayList of sorted results
List<String> results = new ArrayList<>();
// returns empty list if the low is greater than high
if (low > high)
return results;
// for loop through each song in csv file
for (SongInterface song:data) { // changes the type here to SongInterface and data
// if the song has the required energy level and is at or above minspeed, add it to list
// the list should already be sorted in ascending order for energy!!
if (song.getEnergy() >= low && song.getEnergy() <= high && song.getBPM() >= minSpeed)
results.add(song.getTitle());
}
return results;
}
/**
* Filters the list of songs returned by future calls of getRange() and
* fiveMostDanceable() to only include fast songs. If getRange() was
* previously called, then this method will return a list of song titles
* (sorted in ascending order by Energy) that only includes songs with
* speeds greater than or equal to minSpeed. If getRange() was not
* previously called, then this method should return an empty list.
*
* Note that this minSpeed threshold should be saved for later use by the
* other methods defined in this class.
*
* @param minSpeed is the minimum speed of a returned song
* @return List of song titles, empty if getRange was not previously called
*/
@Override
public List<String> filterFastSongs(int minSpeed) {
// update the minSpeed varaible
this.minSpeed = minSpeed;
// creates a List to store the results
List<String> results = new ArrayList<>();
// if getRange has not yet been called, returns an empty list
if (energyRange == null)
return results;
// calls the get range method with a new minSpeed variable set
results = getRange(energyRange[0], energyRange[1]);
// returns the songs that meet the criteria in ascending order
return results;
}
/**
* This method makes use of the attribute range specified by the most
* recent call to getRange(). If a minSpeed threshold has been set by
* filterFastSongs() then that will also be utilized by this method.
* Of those songs that match these criteria, the five most danceable will
* be returned by this method as a List of Strings in increasing order of
* energy. Each string contains the energy rating followed by a colon,
* a space, and then the song's title.
* If fewer than five such songs exist, return all of them.
*
* @return List of five most danceable song titles and their energy
* @throws IllegalStateException when getRange() was not previously called.
*/
@Override
public List<String> fiveMostDanceable() throws IllegalStateException{
if (energyRange == null)
throw new IllegalStateException();
// arrayList of sorted results
List<SongInterface> results = new ArrayList<>();
List<String> mostDanceable = new ArrayList<>();
// returns empty list if the low is greater than high
if (energyRange[0] > energyRange[1])
return mostDanceable;
// for loop through each song in csv file
for (SongInterface song:data) {
// if the song has the required energy level and is at or above minspeed, add it to list
// list should already be sorted in increasing order by energy !!!!
if (song.getEnergy() >= energyRange[0] && song.getEnergy() <= energyRange[1]
&& song.getBPM() >= minSpeed && results.contains(song) == false)
results.add(song);
}
// filter out any repeats
for (int i = 0; i < results.size();i++) {
for (int j = 1; j < results.size(); j++) {
if (results.get(i).getTitle().equals(results.get(j).getTitle()) && j!=i)
results.remove(results.get(j));
}
}
// results is a list of the songs that meet the criteria
// Now pick the 5 most danceable songs
int smallestIndex;
int lowestDance;
while (results.size() > 5) {
smallestIndex = 0;
lowestDance = results.get(0).getDanceability();
// remove the least danceable
for (int i = 1; i < results.size(); i++) {
if (results.get(i).getDanceability() < lowestDance) {
lowestDance = results.get(i).getDanceability();
smallestIndex = i;
}
}
results.remove(smallestIndex);
}
// convert the 5 most danceable songs into the proper format and keep them stored
for(SongInterface song:results) {
mostDanceable.add(song.getEnergy() + ": " + song.getTitle());
}
// return list of the five most danceable songs
return mostDanceable;
}
}