40 Commits
v0.2 ... master

Author SHA1 Message Date
b9e7bb6b7d Need an extra line there. 2016-07-13 22:22:40 +02:00
aaa653afcd Added travis to README.md 2016-07-13 22:21:28 +02:00
147fc10bd8 Removed a couple problematic flags. 2016-07-13 22:13:05 +02:00
bf76b4a911 Added a build file.
Hope this works...
2016-07-13 22:07:15 +02:00
1685ecc1e9 Removed the binary (it was a test.) 2016-07-12 15:40:25 +02:00
c33919a3c6 Adding a temporary windows binary. 2016-07-08 20:01:33 +02:00
ecd4980ba2 Now reads a file and obtains its numbers. 2016-07-08 18:26:04 +02:00
e9bd5bcdd0 Now parsing commandline arguments. 2016-07-07 20:45:57 +02:00
156f8de5c0 Strict compiler with reldeb default build. 2016-07-04 16:17:16 +02:00
597fc22124 Added to the README.md 2016-07-04 12:52:40 +02:00
3675ee066f Adding the C code.
I'm keeping the Java file for now as reference.
2016-07-04 12:43:19 +02:00
f7a0384ff3 Ignore the build directory. 2016-07-04 12:17:21 +02:00
19f9c3c333 Preparing for switch to C. 2016-07-04 12:16:35 +02:00
eebc90e392 Commented Q3 out. 2014-11-06 12:06:59 -06:00
5acd4908ab Update README.md 2014-10-30 15:45:22 -05:00
f022fda0d6 Fixed warning from build. 2014-10-10 11:55:19 -05:00
6d6ef03710 Simplifying comilation. 2014-10-08 19:47:21 -05:00
b5d0d55290 Update .gitignore 2014-09-21 11:25:47 -05:00
81548b20e6 Update README.md 2014-09-21 11:24:23 -05:00
ede6827cb6 Merge branch 'master' of https://github.com/Deathsbreed/MMMCalc 2014-09-21 11:22:57 -05:00
015da8fd34 Now using Apache Ant to compile. 2014-09-21 11:22:22 -05:00
326038107c Update README.md 2014-09-17 21:21:43 -05:00
a1b8f22383 Removed a comment. 2014-06-01 15:40:38 -05:00
fb4d81fe67 Removed FIXME from Q1 function. 2014-05-31 23:51:59 -05:00
497c7d0bea Fixed Q1 calculations (though they could be simplified). 2014-05-31 23:49:00 -05:00
b5db1fbdc2 Forgot to add the gitignore file. 2014-05-31 22:08:03 -05:00
1adc60c991 Added a gitignore file for the binary folder, and moved the manifest to that folder. 2014-05-31 22:06:43 -05:00
4980d8b57c Merge branch 'master' of https://github.com/Deathsbreed/MMMCalc 2014-05-07 15:42:40 -05:00
8d048e9a68 Trying to rever this. 2014-05-07 15:42:35 -05:00
f9a739f556 Added FIXME notices for Q1 and Q2
Q1 and Q2 are calculating incorrectly, specifically that they are ignoring the median value.
2014-05-07 11:03:00 -05:00
3b24d422d2 Preparing for version 0.4 2014-04-15 13:41:35 -05:00
e8b1d79f79 Oops, forgot to change the version. Oh well, minor details. 2014-04-14 17:50:36 -05:00
0ce346b714 There is now a verbose mode for Q1 and Q3. 2014-04-14 17:36:28 -05:00
cbe1aeb123 Now calculates Q1 and Q3. 2014-04-14 17:18:24 -05:00
da36eac98a Setting up for calculations of Q1 and Q3. 2014-04-14 12:02:36 -05:00
dec3bdca0a Added info on building information. 2014-04-14 11:57:29 -05:00
7d2cf7e91a Median is now better emphasized in verbose mode. 2014-04-10 19:28:56 -05:00
0cac8482b6 Fixed median verbose print. 2014-04-10 18:06:07 -05:00
62d4d703a8 Fixed median calculation for even array length. Verbose needs fix. 2014-04-10 17:24:08 -05:00
14ce9cdc3c There is now a verbose mode for median and mode. 2014-04-10 17:08:22 -05:00
8 changed files with 332 additions and 9 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Ignore CMake files:
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
Makefile
# Ignore build files:
build/

13
.travis.yml Normal file
View File

@ -0,0 +1,13 @@
# Define the language
language: c
addons:
apt:
packages:
- build-essential
- cmake
script:
- cd build/
- cmake -DCMAKE_BUILD_TYPE=Release ..
- make

17
CMakeLists.txt Normal file
View File

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 2.6)
project(MMMCalc)
if(CMAKE_BUILD_TYPE STREQUAL "")
set(CMAKE_BUILD_TYPE RelWithDebInfo)
endif()
set(CMAKE_C_FLAGS "-std=gnu99 -Wall -Wextra -Werror -Wfatal-errors -Wmissing-declarations -pedantic-errors")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g -O0")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O3")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g -O3")
set(CMAKE_C_FLAGS_MIN_SIZEREL "${CMAKE_C_FLAGS} -Os")
set(SRCS
src/main.c)
add_executable(mmmcalc ${SRCS})

View File

@ -1,6 +1,21 @@
MMMCalc
=======
[![Build Status](https://travis-ci.org/Deathsbreed/MMMCalc.svg?branch=master)](https://travis-ci.org/Deathsbreed/MMMCalc)
This is a very simple project, it was made for educational purposes (hence why it is open-source), and I encourage everyone to contribute if they have something to add.
MMMCalc is a program I made after school one day after having to learn about Mean, Median, and Mode for the thousandth time. So instead of doing my actual homework I decided to make this program which would do it for me. Of course, the program with this is that your teachers often ask you to show your work. Well, fear not! For MMMCalc shows you **its** work. After it does its calculations, if you turn on _verbose mode_ (by using the `-v` argument) it will show you how MMMCalc got to that answer that it's giving you. After going through Mean, Median, and Mode (the reason why this program is called **MMM**Calc) I decided to add a few other basic statistical properties to it.
To contact me, send me an e-mail at <nicolas.ortega.froysa@gmail.com>.
I hope this helps someone to make their millionth time of doing Mean, Median, and Mode in school a little less of a pain in the ass.
### Compiling
MMMCalc uses [CMake](http://cmake.org/) to compile. Please install the C development tools and CMake (along with whichever build script you plan on having CMake generate) in order to run this command.
```bash
$ cd build/
$ cmake ..
$ make
```
### Contributing
To contribute, simply open a pull request, however, be aware that this code is licensed under a GNU GPLv3 and so will yours.
### License
All code in this repository is under the [GNU GPLv3](/LICENSE).

0
build/.keep Normal file
View File

128
src/main.c Normal file
View File

@ -0,0 +1,128 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#include <getopt.h>
#include <unistd.h>
// Version string
const char *version = "v0.5";
// Whether or not the calculations should be verbose
bool verboseFlag = false;
// Function that prints help info
inline void printHelp();
int main(int argc, char **argv) {
// There should always be at least be 2 arguments and no more than 4
if(argc <= 1) {
fprintf(stderr, "No arguments were provided. Use `-h' for help.\n");
return 1;
}
// Variable where the argument is stored
int arg;
// If help info should be printed
bool helpFlag = false;
// If version info should be printed
bool versionFlag = false;
// The file to read the numbers from
char *infile = NULL;
while((arg = getopt(argc, argv, "hvVf:")) != -1) {
switch(arg) {
case 'h':
// Only 2 arguments can be used
if(argc != 2) {
fprintf(stderr, "Invalid use of arguments. Use `-h' for help.\n");
return 1;
}
helpFlag = true;
break;
case 'v':
verboseFlag = true;
break;
case 'V':
// Only 2 arguments can be used
if(argc != 2) {
fprintf(stderr, "Invalid use of arguments. Use `-h' for help.\n");
return 1;
}
versionFlag = true;
break;
case 'f':
// There needs to be between 3 and 4 arguments
if(argc > 4 || argc < 3) {
fprintf(stderr, "Invalid use of arguments. Use `-h' for help.\n");
}
// Set the input file
infile = optarg;
break;
case '?':
if(optopt == 'f') {
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
} else if(isprint(optopt)) {
fprintf(stderr, "Unknown option `-%c'.\n", optopt);
} else {
fprintf(stderr, "Unknown character `\\x%x'.\n", optopt);
}
return 1;
default:
// If we get anything else that's weird just abort
abort();
}
}
if(helpFlag) {
printHelp();
return 0;
} else if(versionFlag) {
printf("%s\n", version);
return 0;
}
// Print copyright & license information
printf("MMMCalc %s, Copyright (c) 2016 Nicolás A. Ortega.\n", version);
printf("This program comes with ABSOLUTELY NO WARRANTY.\n");
printf("This program is free software and you are welcome to redistribute\n");
printf("under the terms and conditions of the GNU GPLv3 or higher.\n\n");
// Open a file as read only
FILE *numfile = fopen(infile, "r");
// Temporary variable to see how many numbers are in this file
double num;
// The size of the coming nums array
int size = 0;
// Get the size for the array
while(fscanf(numfile, "%lf", &num) == 1) size++;
rewind(numfile);
printf("There are %d numbers in the file.\n", size);
// Create the array with that size
double nums[size];
for(int i = 0; i < size; i++) {
// Store result of fscanf in err
int err = fscanf(numfile, "%lf", &nums[i]);
// If fscanf returned error exit out of here
if(err != 1) {
fprintf(stderr, "Error reading entire file.\n");
return 1;
}
// If not let's continue printing
printf("%f\n", nums[i]);
}
return 0;
}
void printHelp() {
printf("Usage: mmmcalc [options]\n");
printf("Options:\n");
printf(" -f <file> -- The file to read variables from.\n");
printf(" -h -- Show this help information.\n");
printf(" -v -- Be verbose, prints the equations used.\n");
printf(" -V -- Print the version number.\n");
}

View File

@ -1,2 +0,0 @@
Manifest-Version: 0.2
Main-Class: MMMCalc

View File

@ -1,3 +1,5 @@
package mmmcalc;
import java.lang.Math;
import java.util.Arrays;
import java.util.HashMap;
@ -6,7 +8,7 @@ import java.util.Map;
/**
* @author Nicolás A. Ortega
* @copyright (C) Nicolás A. Ortega
* @license GNU General Public License 3.0 (GPLv3)
* @license GNU GPLv3
* @year 2014
*
*/
@ -14,14 +16,16 @@ public class MMMCalc {
private static boolean verbose = false;
private static float[] numArray;
private static float mean = 0;
private static float q1 = 0;
private static float median = 0;
private static float q3 = 0;
private static float mode = 0;
private static float range = 0;
private static float stdDev = 0;
private static float variance = 0;
public static void main(String[] args) {
System.out.println("MMMCalc v0.2, Copyright (C) 2014 Nicolás A. Ortega\n" +
System.out.println("MMMCalc v0.4, Copyright (C) 2014 Nicolás A. Ortega\n" +
"This program comes with ABSOLUTELY NO WARRANTY; for details use '-w'\n" +
"This is free software, and you are welcome to redistribute it\n" +
"under certain conditions; use '-c' for details.\n");
@ -66,7 +70,9 @@ public class MMMCalc {
sortArray();
calcMean();
calcQ1();
calcMedian();
calcQ3();
calcMode();
calcRange();
calcStdDev();
@ -80,13 +86,15 @@ public class MMMCalc {
sortArray();
calcMean();
calcQ1();
calcMedian();
calcQ3();
calcMode();
calcRange();
calcStdDev();
calcVariance();
}
} else {
} else {
System.out.println("You did not mention any variables. Use the -h argument for help.");
}
}
@ -128,12 +136,142 @@ public class MMMCalc {
}
}
private static void calcQ1() {
int q1Pos;
// c stands for case... Cases correspond to their order in the following if statements (4 different cases).
int c;
if(numArray.length % 2.0 == 0) {
q1Pos = (int)(numArray.length / 4);
if(numArray.length % 4.0 == 0) {
q1 = (numArray[q1Pos] + numArray[q1Pos-1]) / 2;
c = 1;
} else {
q1 = numArray[q1Pos];
c = 2;
}
} else {
if(Math.ceil(numArray.length / 2.0) % 2.0 == 0) {
q1Pos = (int)(Math.ceil(numArray.length / 2.0) / 2.0);
q1 = (numArray[q1Pos] + numArray[q1Pos+1]) / 2;
c = 3;
} else {
q1Pos = (int)Math.ceil(numArray.length / 4.0);
q1 = numArray[q1Pos];
c = 4;
}
}
System.out.println("Q1: " + q1);
if(verbose) {
for(int i = 0; i < numArray.length; i++) {
if(c == 1) {
if(i == q1Pos - 1) {
System.out.print(">>" + numArray[i] + " !" + q1 + "! ");
} else if(i == q1Pos) {
System.out.print(numArray[i] + "<< ");
} else {
System.out.print(numArray[i] + " ");
}
} else if(c == 2) {
if(i == q1Pos) {
System.out.print(">>" + numArray[i] + "<< ");
} else {
System.out.print(numArray[i] + " ");
}
} else if(c == 3) {
if(i == q1Pos) {
System.out.print(">>" + numArray[i] + " !" + q1 + "! ");
} else if(i == q1Pos + 1) {
System.out.print(numArray[i] + "<< ");
} else {
System.out.print(numArray[i] + " ");
}
} else if(c == 4) {
if(i == q1Pos) {
System.out.print(">>" + numArray[i] + "<< ");
} else {
System.out.print(numArray[i] + " ");
}
}
}
System.out.print("\n\n");
}
}
private static void calcMedian() {
int midVar = numArray.length / 2;
boolean exact;
median = numArray[midVar];
if(numArray.length % 2 == 0) {
median = (numArray[midVar] + numArray[midVar-1]) / 2;
exact = false;
} else {
median = numArray[midVar];
exact = true;
}
System.out.println("Median: " + median);
if(verbose) {
for(int i = 0; i < numArray.length; i++) {
if(!exact) {
if(i == midVar - 1) {
System.out.print(">>" + numArray[i] + " !" + median + "! ");
} else if(i == midVar) {
System.out.print(numArray[i] + "<< ");
} else {
System.out.print(numArray[i] + " ");
}
} else {
if(i == midVar) {
System.out.print(">>" + numArray[i] + "<< ");
} else {
System.out.print(numArray[i] + " ");
}
}
}
System.out.print("\n\n");
}
}
// FIXME: Needs to calculate haflway between the median value and the last value.
private static void calcQ3() {
/*int q3Pos = (numArray.length * 3) / 4;
boolean exact;
if((numArray.length * 3) % 4 != 0) {
q3 = (numArray[q3Pos+1] + numArray[q3Pos]) / 2;
exact = false;
} else {
q3 = numArray[q3Pos];
exact = true;
}
System.out.println("Q3: " + q3);
if(verbose) {
for(int i = 0; i < numArray.length; i++) {
if(!exact) {
if(i == q3Pos) {
System.out.print(">>" + numArray[i] + " !" + q3 + "! ");
} else if(i == q3Pos + 1) {
System.out.print(numArray[i] + "<< ");
} else {
System.out.print(numArray[i] + " ");
}
} else {
if(i == q3Pos) {
System.out.print(">>" + numArray[i] + "<< ");
} else {
System.out.print(numArray[i] + " ");
}
}
}
System.out.print("\n\n");
}*/
System.out.println("Q3 is not currently functional.\n");
}
private static void calcMode() {
@ -159,6 +297,13 @@ public class MMMCalc {
}
System.out.println("Mode: " + mode + " (frequency: " + modeFreq + ")");
if(verbose) {
for(Map.Entry<Float, Float> entry:fx.entrySet()) {
System.out.print(entry.getKey() + "(" + entry.getValue() + ") ");
}
System.out.print("\n\n");
}
}
private static void calcRange() {
@ -195,7 +340,6 @@ public class MMMCalc {
}
private static void calcVariance() {
// NOTE: I'm doing it this way so I don't have to convert the variables to doubles and lose precision.
variance = stdDev * stdDev;
System.out.println("Variance: " + variance);