-
Notifications
You must be signed in to change notification settings - Fork 0
/
Pseudocode
247 lines (216 loc) · 7.62 KB
/
Pseudocode
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
### Business Logic - Pseudocode
### Current State: [16.1.2021]
/*
Parent Class of Track and Playlist with the most important properties
*/
class Music {
title : String
artist : String
album : String
genre : String
registeredMood : String
link : String
}
/*
Child Class of Music
Blueprint for a single Track Object
*/
class Track : Music
/*
Blueprint for a playlist of Track Objects
*/
class Playlist {
tracks : Array<Track>()
}
/*
Blueprint for a Cocktail object
Following data retrieved from the Cocktail.json file:
name -> name of the Cocktail
recipe -> combination of Ingredient Objects and their associated quantities
teaserText -> describes the Cocktail in a simple sentence
*/
class Cocktail {
name : String
recipe : Array<Pair<ingredient : Ingredient, quantity : Int>>()
teaserText : String
}
/*
Blueprint for an Ingredient Object
Following data retrieved from the Cocktail.json file:
name -> name of the Ingredient
details -> details belonging to the Ingredient
*/
class Ingredient {
//derives from cocktail.json
name: String
details: String
}
/*
Mood Class, provides functionality to define the mood the user feels or wants to express
currentMood -> the current mood, if not set yet -> null
attribute -> array of specific attributes that can be used for retrieving a track suitable for the currentMood
preferences -> array of the users preferences of the music
*/
class Mood() {
currentMood : String?
//More specific attributes for spotify API (e.g. danceability, acousticeness, ...)
attributes : Array<Pair<name : String, value : Float>>
//User Preferences on things he wants / does not want in music or recipes
preferences : Array<String>
/*
Asks for input to set the currentMood to a string
*/
function getCurrentMood() {
input = readline()
if(input is valid):
currentMood = input
else throw InvalidInputError
}
/*
Asks for input to create an array of specific attributes (as described above)
If there is an old entry of attributes, it will get cleared first
*/
function getAttributes() {
attributes.clear()
input : String
while(True) {
attribute : String = readline()
value : float = readline()
if(attribute || value == "exit") break
attributes.append(Pair(attribute, value))
}
}
/*
Asks for input to create an array of specific preferences (as described above)
If there is an old entry of preferences, it will get cleared first
*/
function getUserPreferences() {
preferences.clear()
input : String
while(True) {
preference : String = readline()
if (preference == "exit") break
preferences.append(preference)
}
}
/*
Translates the String representation of the users mood, represented by currentMood, to a numeric array of specific attributes (as described above)
If there is an old entry of attributes, it will get cleared first
If there is no currentMood set yet, the array will be filled with default values
*/
function translateMood() {
attributes.clear()
when (mood) {
"happy" -> {
attributes.append(Pair("danceability", 1.0))
attributes.append(Pair("valence", 1.0))
attributes.append(Pair("loudness", 0.8))
}
"sad" -> {
attributes.append(Pair("danceability", 0.2))
attributes.append(Pair("valence", 0.2))
attributes.append(Pair("loudness", 0.3))
}
"angry" -> {
attributes.append(Pair("danceability", 0.3))
attributes.append(Pair("valence", 0.3))
attributes.append(Pair("loudness", 1.0))
}
default -> {
attributes.append(Pair("danceability", 0.5))
attributes.append(Pair("valence", 0.5))
attributes.append(Pair("loudness", 0.5))
}
}
}
}
/*
Blueprint for a Combination Object
Represents the requested Combination of a cocktail and music (represented by a single Track or a Playlist) to the corresponding mood
cocktail -> Cocktail Object
trackOrPlaylist -> Track or Playlist Object
*/
class Combination {
cocktail : Cocktail
trackOrPlaylist : Music
function deliverCombi() = this
}
/*
Responsible to request the music and the cocktail to create a Combination object
*/
class Combinator {
/*
returns a single Track
*/
function getSingleTrack(mood : Mood) : Track {
track : Track = GET generateURL(mood.currentMood)[0]
return track
}
/*
returns a Playlist of Track Objects
numberOfTracks -> Int to specify the amount of tracks to add to the Playlist
*/
function getPlaylist(mood : Mood, numberOfTracks : Int) : Playlist {
playlist : Playlist = new Playlist()
tracks = GET generateURL(mood.currentMood)
try:
for (i = 0; i < numberOfTracks; i++) {
playlist.tracks.add(tracks[i])
}
except IndexError:
console.log("The specified number of tracks was too high. I was only able to get ${playlist.length} songs for the playlist.")
finally:
return playlist
}
/*
returns a Cocktail object from the Cocktail.json file
*/
function getCocktail(mood : Mood) : Cocktail {
result = GET Cocktail from Cocktail.json
cocktail : Cocktail = new Cocktail()
cocktail.name = result[name]
cocktail.recipe = result[recipe]
cocktail.teaserText = result[teaserText]
return cocktail
}
/*
Combines the provided Cocktail with the provided Music Object
returns a Combination Object of the Cocktail and Music
*/
createCombination (cocktail : Cocktail, trackOrPlaylist : Music) : Combination {
myCombination : Combination = new Combination()
myCombination.cocktail = cocktail
myCombination.trackOrPlaylist = trackOrPlaylist
return myCombination
}
}
/*
Generates a URL which can be used to access the spotify API
All of the specified Attributes of the Mood Object need to be stringified and then combined and added to the base URL of the API
returns a URL
*/
function generateURL(mood : Mood) : String {
base : String = "https://api.spotify.com/v1/recommendations?"
suffix : String = ""
for (attribute in mood.attributes) {
suffix += "&$attribute.name=$attribute.value"
}
return base + suffix
}
/*
Short example procedure and sequence of function calls
*/
function main() {
combinator : Combinator = new Combinator()
mood : Mood = new Mood()
mood.getCurrentMood()
.translateMood()
track : Track = combinator.getTrack(generateURL(mood))
cocktail : Cocktail = combinator.getCocktail(mood)
combination : Combination = combinator.createCombination(cocktail, track)
}
#### Stand 08.12, 20:06
## Dieser Pseudocode stellt lediglich nur den momentanen Zustand dar, durch weitere Arbeiten am gesamten Projekt und an den zum Modell gehörigen Modellen
## ergeben sich ständig Änderungen die auch diesen Pseudocode betreffen.
## Des Weiteren ist zu erwähnen, dass einige Konstrukte die sich hier finden nicht 1:1 nach Javascript übertragen lassen.
## Dieser Pseudocode soll jedoch Programmiersprachen-Neutral sein, auch wenn er sich an bekannten Sprachen anlehnt.