Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- double const STDDEV_SCALAR = 1.5;
- int *load_readings(char fileName[], int *numReadings);
- void lumens_std_def(int *listMemory, int numElements, double *average, double *stdDev);
- int get_outliers(int *firstReadingList, int numElements, int *secondReadingList, double *average, double *stdDev, double devMultiplier);
- void write_outliers(char outputName[], int *outlierList, int numElements);
- /*
- * argc - # of command line arguments
- * argv - Is the actual command line argument
- *
- * In this case, argv[1] will be our input file name
- * and argv[2] will be the output file name.
- */
- int main(int argc, char *argv[]) {
- if (argc != 3) {
- printf("Invalid number of command line parameters, exiting...\n");
- exit(1);
- }
- /*
- * Program specifies that the first function
- * should have a pointer to the number of readings,
- * however, the other functions simply need an int,
- * so I just take the value from the pointer and set it
- * to a new variable
- */
- int *readingsPointer = malloc(sizeof *readingsPointer);
- int *dataPointer = load_readings(argv[1], readingsPointer);
- int numReadings = *readingsPointer;
- //Free memory allocated to the temporary pointer
- free(readingsPointer);
- /*
- * Allocate memory to the 'average and standard
- * deviation pointers.
- */
- double *average = malloc(sizeof *average);
- double *stdDev = malloc(sizeof *stdDev);
- lumens_std_def(dataPointer, numReadings, average, stdDev);
- int *outlierList = malloc(sizeof *outlierList);
- /*
- * Why would you pass a constant to a function
- * when the function can access it?
- */
- int numOutliers = get_outliers(dataPointer, numReadings, outlierList, average, stdDev, STDDEV_SCALAR);
- write_outliers(argv[2], outlierList, numOutliers);
- //printf("Readings = %d\n", numReadings);
- //printf("Average = %0.2f\n", *average);
- //printf("Standard Deviation = %0.2f\n", *stdDev);
- //printf("Outliers = %d\n", numOutliers);
- return 0;
- }
- int *load_readings(char fileName[], int *size) {
- FILE *in = NULL;
- in = fopen(fileName, "r");
- //ERROR CHECK: Check to see if there is a file name.
- if (in == NULL) {
- printf("Unable to open input file \"%s\", exiting...\n", fileName);
- fclose(in);
- exit(4);
- }
- /*
- * Go to the end of the file to get the size
- * Divide that size by 4 to get number of elements
- * Go back to beginning with 'SEEK_SET'
- * It's like rewind(), but better.
- */
- fseek(in, 0L, SEEK_END);
- size[0] = ftell(in) / 4;
- fseek(in, 0L, SEEK_SET);
- //ERROR CHECK: Check file size
- if (size == 0) {
- printf("Input file contains no data, exiting...\n");
- fclose(in);
- exit(2);
- }
- //Allocate memory to the pointer 'data'
- int *data = (int *) calloc(size[0], sizeof(int));
- //ERROR CHECK: Check to see if enough memory was allocated
- if (data == NULL) {
- printf("Unable to allocated needed memory, exiting...\n");
- fclose(in);
- exit(3);
- }
- int i = 0;
- int *memoryAt;
- for (i; i < size[0]; i++) {
- memoryAt = (data + i);
- fscanf(in, "%d", memoryAt);
- }
- //free(memoryAt);
- fclose(in);
- return data;
- }
- void lumens_std_def(int *data, int numElements, double *average, double *stdDev) {
- int i = 0;
- int sum = 0;
- /* I just use a temporary address to clean up the code */
- int *tempAddress;
- for (i; i < numElements; i++) {
- tempAddress = (data + i);
- sum += *tempAddress;
- }
- *average = (double) sum / (double) numElements;
- /*
- * Reset sum back to 0 for use again. No need
- * in wasting memory making new variables.
- */
- sum = 0;
- for (i = 0; i < numElements; i++) {
- tempAddress = (data + i);
- sum = (double) sum + pow((*tempAddress - *average), 2);
- }
- *stdDev = sqrt((double) sum / (double) numElements);
- }
- int get_outliers(int *firstReadingList, int numElements, int *secondReadingList, double *average, double *stdDev, double devMultiplier) {
- int i = 0;
- int *tempAddress, *tempOutlier;
- int numOutliers = 0;
- double plusOutlier = *average + (*stdDev * devMultiplier);
- double minusOutlier = *average - (*stdDev * devMultiplier);
- /*
- * Loop through the elements, and if
- * the current value is either
- * average +- (std. dev. * multiplier)
- * then it is considered an 'outlier'
- */
- for (i; i < numElements; i++) {
- tempAddress = firstReadingList++;
- if ((double) *tempAddress > plusOutlier || (double) *tempAddress < minusOutlier) {
- *secondReadingList++ = *tempAddress;
- numOutliers++;
- printf("%d ", *tempAddress);
- }
- }
- return numOutliers;
- }
- void write_outliers(char outputName[], int *outlierList, int numElements) {
- printf("\n");
- //Create output file pointer and open it
- FILE *out;
- out = fopen(outputName, "w");
- if (out == NULL) {
- printf("Unable to open out file '%s', exiting...\n", outputName);
- exit(5);
- }
- int i = 0;
- int *tempAddress;
- //Loop through and write each element in the outlier list
- for (i; i < numElements; i++) {
- tempAddress = (outlierList + i);
- printf("%d ", *tempAddress);
- fprintf(out, "%d ", *tempAddress);
- }
- fclose(out);
- printf("\n");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement