Created
October 7, 2013 20:49
-
-
Save anonymous/6874721 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*********************************************************************** | |
* This programs plots histograms. | |
* Input is fed through the console/command-line/terminal. | |
* To compile issue : | |
* gcc -o hist <name_you_saved>.c | |
* Ignore warnings... (Remove them if you can. :) ) | |
* Run as ./hist with options. | |
* | |
* Options : | |
* 1. -c<space><character> specifies the character which will be used to | |
* draw bars. | |
* 2. -m specifies to print the mean. | |
* 3. -v specifies to print the value on top of the bar. | |
* | |
* Sample Input : | |
* ./hist -v -c $ -m 2 3 10 5 7 | |
* | |
* Output : | |
* $$ 2 | |
* $$$ 3 | |
* $$$$$$$$$$ 10 | |
* $$$$$ 5 | |
* $$$$$$$ 7 | |
* The mean is : 5.400000 | |
* | |
* It is easy to add more options. Look in the code. ! | |
* | |
* License : Do what the fuck you want to with this code... | |
* | |
* ********************************************************************/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
/* The structure below holds program options */ | |
typedef struct | |
{ | |
unsigned int start ; /* Determines from where the data starts. */ | |
char unit_bar ; /* Character to draw. */ | |
char verbose ; /* Whether to print value. */ | |
char mean ; /* Whether to display mean. */ | |
} print_options ; | |
/* Checks whether the string is a valid unsigned int */ | |
char isuint(const char* string) | |
{ | |
unsigned int i ; | |
for(i=0; string[i]!='\0'; ++i) | |
if(string[i] < 48 || string[i] > 57) | |
return 0 ; | |
return 1 ; | |
} | |
void print_usage_message() | |
{ | |
puts("Usage : hist-plot [OPTIONS] ...data list... \n\n Options : \n\t-c character to draw\n\t-v to display value on top of bars\n\t-m to display mean\n"); | |
} | |
void print_error_message() | |
{ | |
puts("Something went wrong..."); | |
} | |
unsigned int find_max(const unsigned int *data, unsigned int size) | |
{ | |
unsigned int i = 1u, max = data[0]; | |
for(; i<size; ++i) | |
if(max < data[i]) | |
max = data[i] ; | |
return max ; | |
} | |
float mean(const unsigned int *data, unsigned int size) | |
{ | |
unsigned int i ; | |
float sum = 0.0f ; | |
for(i=0; i<size; ++i) | |
sum += (float)data[i] ; | |
return sum/(float)size ; | |
} | |
/* Prints the histogram */ | |
char printh(const unsigned int *data, unsigned int size, print_options ops) | |
{ | |
unsigned int i, j, max ; | |
char **matrix = malloc(sizeof(char*)*size); | |
if(!matrix) | |
return 0 ; | |
max = find_max(data, size); | |
for(i=0; i<size; ++i) | |
{ | |
matrix[i] = malloc(sizeof(char)*(max+1)); | |
if(!matrix[i]) | |
return 0 ; | |
for(j=0; j<max; ++j) | |
matrix[i][j] = ((j < data[i]) ? ops.unit_bar : ' ') ; | |
matrix[i][max] = '\0' ; /* Make a valid string. */ | |
} | |
for(i=0; i<size; ++i) | |
(ops.verbose) ? printf("%s %u\n", matrix[i], data[i]) : | |
printf("%s\n", matrix[i]); | |
if(ops.mean) | |
printf("The mean is : %f\n", mean(data, size)); | |
return 1 ; | |
} | |
char parse_options(const char** argv, print_options* options) | |
{ | |
unsigned int i = 1 ; | |
int ret = 1 ; | |
while((argv[i][0] == '-') && (argv[i] != NULL)) | |
{ | |
switch(argv[i][1]) | |
{ | |
/* If -c option, then read the character to draw */ | |
case 'c' : | |
++i ; | |
(*options).unit_bar = argv[i][0] ; | |
break ; | |
case 'v' : | |
(*options).verbose = 1 ; | |
break ; | |
case 'm' : | |
(*options).mean = 1 ; | |
break ; | |
default : | |
return 0 ; | |
} | |
++i ; | |
} | |
(*options).start = i ; | |
return ret ; | |
} | |
char parse_data(int argc, const char** argv, print_options ops) | |
{ | |
unsigned int* data, i, j ; | |
data = malloc(sizeof(unsigned int)*(argc-ops.start)); | |
if(!data) | |
return 0 ; | |
for(i=ops.start, j=0; i<argc; ++i) | |
{ | |
if(isuint(argv[i])) | |
{ | |
data[j] = atoi(argv[i]); | |
++j ; | |
} | |
else | |
return 0 ; | |
} | |
return printh(data, j, ops); | |
} | |
int main(int argc, char **argv) { | |
/* Default options : All turned off, draws '=' character. */ | |
print_options ops = { .start = 1, .unit_bar = '=', .verbose = 0, .mean = 0 } ; | |
if(argc < 2 || !parse_options(argv, &ops)) | |
{ | |
print_usage_message() ; | |
return 0 ; | |
} | |
if(!parse_data(argc, argv, ops)) | |
print_error_message() ; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment