Lab materials
- Slides: QSort
- Slides: Dividing code
- Sample project on code division: https://blue.pri.ee/ttu/files/iax0584/demokood/division_to_files.zip
Lab tasks
This lab has two tasks
- First task consist of two separately graded parts plus an additional advanced task.
- Second task consist of a base task and an advanced task.
Task 1: Quicksort
This task is based on practicing using the qsort() function to sort both basic data types and structs. During this, we will also start dividing our code into multiple code files and you can also start making your first header file. The starter code already has file structure given for you.
Download the starter code: https://blue.pri.ee/ttu/files/iax0584/aluskoodid/5_1_qsort_task_basecode.zip
NB! The base code contains code for both parts of the base task and the advanced task as one!
Requirements
- Implement the functions that are described in the header files required for the specific part of the task (look below for parts description). Implementation must be written in the .c file with the same name.
- Call the required functions to sort and display the results from the switch statement in the main function
- Compile the code from multiple files as was given by the structure in the starter code. Use command line to do so (or Makefile if you already know how).
Graded parts of the task
For part one of the base task, you must have menu options 1 and 2 completed. For this you must
- Implement the qsort comparison function for arrays made out of integers and real numbers
- Call out the qsort function with the comparison function made before as well as the print function to prove completion of the task.
For part two of the base task, you must have menu options 3 and 4 completed. For this you must
- Implement the qsort comparison function for arrays made out of structures. One of them must compare the first name, the other one the employment length.
- Implement the function to print out the structure array
- Call out the qsort function with the comparison function made before as well as the print function to prove completion of the task.
For the advanced task, you must have menu option 5 completed. For this you must
- Implement the qsort comparison functions to compare the structure array members based on their last name. If the last names are the same, you must use first name as an additional criteria for sorting the structures.
- Call out the qsort function with the comparison function made before as well as the print function to prove completion of the task.
Testing
The following example includes all three graded parts (part 1 and 2 as base tasks and the advanced task).
Task 2: External libraries (covid-data)
In this task, we’ll introduce you how to include and compile programs using external libraries. We will use the libcurl library, which can be used to access various online APIs, download files etc. We’ll use this to download Estonian governments opendata. We’ll also proceed to practice dividing code into multiple files.
NB! To simplify your life, solve this task on a UNIX based operating system (e.g. Linux). It can be done on Windows, but the additional setup for this is more exhaustive and you need to change a few parts of the given source code.
Download the starter code: https://blue.pri.ee/ttu/files/iax0584/aluskoodid/5_2_covid_starter.zip
Requirements
- Use the starter code given, follow the structure provided.
- Download Estonian Covid-19 opendata (already given in the starter code)
NB! The open data is updated once per week! - Data specification
- Display the confirmed cases for the last 14 days
- Display the top 10 days with the highest confirmed cases count.
- At minimum, your code needs to be separated into three code and header files
- file_helper.c and file_helper.h contain the data download and preparation (given in the starter code, no need to modify)
- data_processor.c and data_processor.h contain the reading and processing of the data
- main.c and main.h have controls for the program flow and generic macros.
- If you want, you can separate out reading of the file and processing the data to additional files.
- Compile all the code files together either from the command line or by using a Makefile.
Recommended workflow
- Get acquainted with the structure and the contents of the code files.
- Comment in the preferred download format (either space or comma separated data).
- Compile and see if the data download works. To compile, you need to add an additional flag -lcurl
- Add a description of the data structure and the necessary macros for sizes to the
main.h header file.
Hint: You don’t need to store all of the data from the file in the structures. Pick only the data you need. - Write the reading function to read data from the file into memory into
data_process.c . Add the prototype to that function into
data_process.h header file and call the function in the main() function.
NB! Did you notice the contents of the first line of the file?
Hint: To ignore a certain field in the file, you can use the format %*s in the scanf function. Asterisk notes that the field matching this format will not be stored. In this case, any string until a space or a newline is encountered will be ignored. When you use an asterisk in the format, you also don’t need to provide a pointer where to store the data (scanf parameter).
Compile and test if your data is successfully read into the structure array! - Create a function to print the data. Call it to print the last 14 days of data.
Hint: Use your knowledge of arrays and poiinter-arithmetic that we used in the first week (task 1, part 2)! This way you will get a simple printing function that you can reuse in the next step. - Create a comparison function for
qsort to sort by the confirmed case count and and call
qsort to sort the data. Display the top 10 days based on confirmed case count.
Hint: If you used pointer-arithmetic to call the printing function in the last step and left your print function to be as simple as possible, you can reuse it to print the top 10!
Testing
NB! The output contains both the base task and the advanced task!
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 |
risto@risto-wk-tux:~/Nextcloud/work/ttu/teaching/_generic/prog2/lab/wk5_div/t2_covid/covid_solution$ ./covid_stats Warning! The file opendata_covid19_tests_total.txt already exists! Are you sure you wish to download again? Enter [Y] or [N] n Last 14 days Date Cases 1. 2023-02-07 48 2. 2023-02-08 55 3. 2023-02-09 54 4. 2023-02-10 52 5. 2023-02-11 21 6. 2023-02-12 28 7. 2023-02-13 76 8. 2023-02-14 37 9. 2023-02-15 47 10. 2023-02-16 67 11. 2023-02-17 48 12. 2023-02-18 24 13. 2023-02-19 23 14. 2023-02-20 53 Top 10 days Date Cases 1. 2022-02-15 8467 2. 2022-02-03 8045 3. 2022-02-04 7849 4. 2022-02-01 7243 5. 2022-01-28 7171 6. 2022-02-05 7082 7. 2022-02-18 6996 8. 2022-02-02 6886 9. 2022-02-17 6751 10. 2022-02-08 6704 Date range: 2023-02-07 - 2023-02-13 total cases 334 Date range: 2023-02-14 - 2023-02-20 total cases 299 Case count decreased by 11.71% |
Advanced task
- Find the number of cases for the last 7-day period.
- Find the number of cases for the 7-day period preceding it.
- Print out the date ranges and infection counts for both periods.
- Find and print if the case count as increased, decreased or remained the same from one period to the next. Also print out the change as a percentage, showing two places after the comma.
Hint: The array was sorted during the base task and cannot be used for the advanced task in a good way without resorting (which we should always avoid if possible). We can however prepare a partial copy of the original data, before we run qsort to sort it. To make a copy, check out the function memcpy() – look into the parameters it requires to set the starting point of the copy, you can use pointer arithmetic to make a copy of only the relevant data.
MS Windows
This task is also solvable in MS Windows, however it is a bit more tedious, requiring a few additional steps. These steps have been tested in the spring of 2022! This assumes you installed the 64-bit version of the MinGW (e.g. through chocolatey – as given in the simple installation guide for MS Windows, using the command line). The steps are given as a transcript of the conversion from last year and are provided as-is!
1. Install libcurl on Windows. Uses chocolatey package manager
choco install curl
2. Make the library (dll file) available to the compiled program. Copy libcurl-x64.dll from libcurl installation directory to your program directory (assumes 64-bit compiler).
3. You need to download CA certificate so cURL can verify the certificate on the opendata website https://curl.se/ca/cacert.pem.
4. You need to specify the certificate authority file location to the code. Add this to the setup of the download in the file_helper.c, replacing the path\\to\\file with the path to the downloaded .pem file.
curl_easy_setopt(curl_handle, CURLOPT_CAINFO, "path\\to\\file");
5. You need to rewrite the check if a file is already downloaded because that uses POSIX library available on UNIX systems – unistd.h. You should rewrite it with windows solution of that. Haven’t tested, but you’ll likely find the function BOOL FileExists(LPCTSTR szPath)
in the library io.h
. You may need to add additional Windows-specific libraries.
6. You can only download as CSV with the code provided. To download space delimited, you need to rewrite the ReplaceChars function. Easy option would be to open up a second file pointer for writing to a different file and remove the fseek, Simplest would be to do getchar -> putchar with a check in between for commas to be replaced with spaces.
7. You need to add -I and -L flags to your compiler command line arguments. Mine were:
-I C:\ProgramData\chocolatey\lib\curl\tools\curl-7.81.0-win64-mingw\include\ -L C:\ProgramData\chocolatey\lib\curl\tools\curl-7.81.0-win64-mingw\lib\
After the class
- Be able to separate your program between multiple (.c) code files and compile them into a program.
- Know how to use the qsort function.
- Understand the requirements for the qsort comparison function and be able to write such comparison functions for simple arrays and structure arrays.
- Know about the existence of function pointers and be able to pass a pointer to a function to another function.
- Know the general steps required to use third party libraries with your programs and be able to compile a program with them.
Additional materials
- Sorting algorithms visualized
https://www.toptal.com/developers/sorting-algorithms - Big-O cheat sheet
https://www.bigocheatsheet.com - Quicksort algorithm
https://en.wikipedia.org/wiki/Quicksort - Example structure
https://github.com/JackWetherell/c-project-structure - List of common C libraries
https://github.com/oz123/awesome-c