You are expected to complete this assignment individually. If you need help, you are invited to come to office hours and/or ask questions on piazza. Clarification questions about the assignments may be asked publicly. Once you have specific bugs related to your code, make the posts private.
In this project, you will load data of highly ranked songs in spotify from a csv(comma separated values) file. You will implement some functions to do some simple data analysis. The data file is provided here: data.csv. Each line corresponds to a record of a song. Each line comprises the following fields:
Here are some samples of lines you will see in data.csv.
1,Bad and Boujee (feat. Lil Uzi Vert),Migos,1371493,https://open.spotify.com/track/4Km5HrUvYTaSUfiSGPJeQR,2017-01-01,us 2,Fake Love,Drake,1180074,https://open.spotify.com/track/343YBumqHu19cGoGARUTsd,2017-01-01,us 3,Starboy,The Weeknd,1064351,https://open.spotify.com/track/5aAx2yezTd8zXrkmtKl66Z,2017-01-01,us
We won't need all the fields in the csv file. The fields we will work with in this project are: rank, song, artist and date. We use the following structure record to store these four fields in a single line of the csv file.
typedef struct { int position; char* song; char* artist; struct tm* date; } record;
struct tm is a structure to store date and time information, defined in time.h. It is sufficient to finish this assignment if you understand how we use struct tm in our provided code.
We provide the implementation of reading data from the csv file, storing data inside a 2d array of record*, print the data and free the variable memories. The files are provided hw4_provided.h, hw4_provided.c and hw4_main.c.
Basically, we define a 2 dimensional array of record*, and that is why you see
record*** read_spotify_data(char* filename, int* num_days, int* num_records_per_day, struct tm* first_day);
This function reads data from a csv file named "filename" and store them in the 2d array. The first dimension represents the date, and the second dimension represents the rank of the song. The first line of the csv file will be the first date to read, number of (consecutive) days to read, and number of records per day. Each element in the 2d array is a pointer to a record. Please remember that some elements of the 2d array may be a NULL pointer as the data may not in the csv file.
You should be able to create a Makefile and write down the command to compile the source code.
Make sure that you can compile and execute our provided code. Read the code to understand what the code is doing. Especially how data is stored and accessed in the variable record*** rs.
You should submit four files for this assignment ( hw4.h, hw4.c, hw4_main.c, and Makefile) in your subversion repository as directed below.
You need a hw4.c and hw4.h file for this portion.
You need to add the skeleton code so that your program will minimally execute. You must do this in case you do not complete your assignment. Our testing infrastructure needs to compile and execute even if you did not complete the entire assignment. Refer to past assignments on how to make skeleton code.
record* find_highest_record_by_date(const char* date, record*** rs, int num_days);
Given a date (string), find the record of song ranked first on that date. For example, given "2017-04-07", your code should be able to find the following record: "1, HUMBLE., Kendrick Lamar, 2017-04-07" (printed out by print_record).
Return the pointer of that record.
If you don't know how to convert a string to struct tm*, please read function "record* read_record(char* line)" in hw4_provided.c. There is a line of code doing that.
record* find_artist_highest_rank(const char* artist, record*** rs, int num_days, int num_records_per_day);
Given an artist (string), retrieve the highest ranked record of that artist. If multiple highest ranked records are available, only return the first record. For example, given artist "Bruno Mars", your code should retrieve the following record: "3, That's What I Like, Bruno Mars, 2017-03-03".
Return the pointer to that record.
double score_artist(const char* artist, record*** rs, int num_days, int num_records_per_day);
We define a way to assign scores to artists. The artist gets point by ranking at top 20, the exact points are as following:
1st: 50Now given an artist (string), calculate the score for that artist and return that score. parameter record*** rs is the 2d record pointer array, int num_days is the number of days we have in our array, and int num_records_per_day is the number of records per day.
double score_song(const char* song, record*** rs, int num_days, int num_records_per_day);
Similar to problem 3, we define a way to assign scores to songs. A song gets points by ranked top 20 on a day. The way we assign scores to songs follows the exact rule as scoring artists. Implement this function to return the score (double) given a song (string).
#include "hw4_provided.h"
before your hw4.h file.Add test cases into testscript you created in warmup4.
You will send in command-line arguments with the function being tested, the function parameters, and expected results. You will read in the command-line arguments, determine which function to test, run that test, then compare the actual result with the expected result.
Essentially your test program checks the command-line argument of function naem and function parameters, tries to call the functions accordingly, gets the result and compare with the expected result to determine whether your functions work correctly.
For example, if you run
./hw4_main find_artist_highest_rank "Bruno Mars" "3, That's What I Like, Bruno Mars, 2017-03-03"If your function works correctly, your program should output something likefind_artist_highest_rank "Bruno Mars" expected: 3, That's What I Like, Bruno Mars, 2017-03-03 actual: 3, That's What I Like, Bruno Mars, 2017-03-03 SUCCESSIf your function does not work as expected, your test program should printfind_artist_highest_rank "Bruno Mars" expected: 3, That's What I Like, Bruno Mars, 2017-03-03 actual: [you got something unexpected] FAILUREYour message needs to contain: function name, parameters, the expected output vs actual output, and success or failure.Note that for problem 1 and 2, since the function return type is record*, you need to call print_record to get the text description of the record and compare with the expected result. For problem 3 and 4, since they are doubles you can directly compare them. However, be careful when you compare two doubles, you may not use == directly to determine whether two doubles are equal.
$ svn add hw4.h hw4.c hw4_main.c testscript
$ svn commit -m "hw4 complete"