Skip to content

Instantly share code, notes, and snippets.

@titouanc
Created December 5, 2011 00:03
Show Gist options
  • Save titouanc/1431721 to your computer and use it in GitHub Desktop.
Save titouanc/1431721 to your computer and use it in GitHub Desktop.
Projet INFO2009
CC = gcc
TARGET = info2009-projet1.exe
FILES = ui.c stats.c
OPTIONS = --std=c99 --pedantic -Wall -W -Wmissing-prototypes -O3
LIBS = -lm
all : ${TARGET}
${TARGET} : ${FILES}
${CC} ${OPTIONS} ${LIBS} -o ${TARGET} -DBIO_T_TAILLE=13 ${FILES}
clean:
rm -f ${TARGET} ._*
#include "stats.h"
void Biometrique_tableauEchange(Biometrique *tableau, int e1, int e2){
Biometrique tmp;
Biometrique_cpy(&tmp, &tableau[e1]);
Biometrique_cpy(&tableau[e1], &tableau[e2]);
Biometrique_cpy(&tableau[e2], &tmp);
}
void Biometrique_triBulle(Biometrique *tableau, unsigned char champ, int longueur){
int i, j;
for (i=longueur-1; i>0; i--){
for (j=1; j<=i; j++){
if (tableau[j-1][champ] > tableau[j][champ])
Biometrique_tableauEchange(tableau, j-1, j);
}
}
}
double Biometrique_moyenneChamp(Biometrique *donnees, unsigned char champ, int nombre){
double sum=0.0;
int i;
if (nombre == 0) return 0;
for (i=0; i<nombre; i++)
sum += donnees[i][champ];
return sum/nombre;
}
double Biometrique_ecartTypeChamp(Biometrique *donnees, unsigned char champ, int nombre){
double sum=0.0, dif;
int i;
double moy = Biometrique_moyenneChamp(donnees, champ, nombre);
if (nombre==0) return 0.0;
for (i=0; i<nombre; i++){
dif = donnees[i][champ] - moy;
sum += dif*dif;
}
return sqrt(sum/nombre);
}
int Biometrique_litFichier(const char *chemin, Biometrique *resultat, int nombre){
int i=0, champ, ajouts_entree;
FILE *input = fopen(chemin, "r");
if (input == NULL)
return -1;
while (i < nombre){
if (feof(input))
break;
ajouts_entree = 0;
for (champ=0; champ<BIO_T_TAILLE; champ++)
ajouts_entree += fscanf(input, "%lf", &resultat[i][champ]);
if (ajouts_entree == BIO_T_TAILLE)
i++;
}
fclose(input);
return i;
}
double Biometrique_freqRelAge(Biometrique *donnees, int age, int nombre){
int i;
double sum=0.0;
for (i=0; i<nombre; i++)
if ((int) donnees[i][BIO_AGE] == age)
sum += 1;
return sum/nombre;
}
void Biometrique_afficheFreqRelCumuleeAges(Biometrique *donnees, FILE *output, int nombre){
int age_min, age_max, nombre_ages;
int *occurences_ages = NULL;
int i;
double frel, res=0.0;
Biometrique_triBulle(donnees, BIO_AGE, nombre);
age_min = (int) donnees[0][BIO_AGE];
age_max = (int) donnees[nombre-1][BIO_AGE];
nombre_ages = 1+age_max-age_min;
occurences_ages = malloc(nombre_ages*sizeof(int));
for (i=0; i<nombre_ages; i++)
occurences_ages[i] = 0;
for (i=0; i<nombre; i++)
occurences_ages[(int) donnees[i][BIO_AGE] - age_min] ++;
fprintf(output, "Age Freq.rel. Fr.rel.cum\n");
for (i=0; i<nombre_ages; i++){
frel = (double) occurences_ages[i]/nombre;
res += frel;
if (occurences_ages[i] > 0)
fprintf(output, "%3d %.8lf %.8lf\n", age_min+i, frel, res);
}
free(occurences_ages);
}
#ifndef DEFINE_MESURES_HEADER
#define DEFINE_MESURES_HEADER
/*
* Projet n.1 du cours d'INFO2009 (ULg, 2011-2012)
* Note: les mots entre ++ dans les specifications
* referent a des noms de parametres
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* permet de changer la taille d'une entree biometrique a la compilation
(en utilisant gcc -DBIO_T_TAILLE=x ...) */
#if ! defined BIO_T_TAILLE
#define BIO_T_TAILLE 13
#endif
/*
* Definition d'un type biometrique.
* Comme toutes les donnees sont du meme type (double)
* l'utilisation d'un vecteur facilite l'ecriture de fonctions generiques
*/
typedef double Biometrique[BIO_T_TAILLE];
/*
* [pre] +source+ est un pointeur vers une entree Biometrique allouee
+dest+ est un pointeur vers une zone de memoire
pouvant accueillir au moins une entree biometrique
* [post] +dest+ contient une copie de +source+
*/
#define Biometrique_cpy(dest, source) memcpy((dest), (source), sizeof(Biometrique))
/*
* Position des differents champs dans l'entree biometrique
*/
#define BIO_AGE 0
#define BIO_MASSE 1
#define BIO_TAILLE 2
#define BIO_NUQUE 3
#define BIO_POITRINE 4
#define BIO_ABDOMEN 5
#define BIO_HANCHE 6
#define BIO_CUISSE 7
#define BIO_GENOU 8
#define BIO_CHEVILLE 9
#define BIO_BICEPS 10
#define BIO_AVANTBRAS 11
#define BIO_POIGNET 12
/*
* [pre] +tableau+ est alloue, et les indices e1 et e2 existent
* [post] les elements aux positions e1 et e2 sont intervertis
*/
void Biometrique_tableauEchange(Biometrique *tableau, int e1, int e2);
/*
* [pre] tableau est alloue et a une longueur >= a longueur
* [post] le tableau est trie par ordre croissant avec l'algorithme tri-bulle
selon le champ specifie
*/
void Biometrique_triBulle(Biometrique *tableau, unsigned char champ, int longueur);
/*
* [pre] +donnees+ est initialise, +champ+ le champ a traiter (utiliser defines ci-dessus)
+nombre+ le nombre de donnees a traiter
* [post] Renvoie la moyenne des donnees pour le champ specifie
*/
double Biometrique_moyenneChamp(Biometrique *donnees, unsigned char champ, int nombre);
/*
* [pre] +donnees+ est initialise, +champ+ le champ a traiter
+nombre+ le nombre de donnees a traiter
* [post] Renvoie l'ecart type des donnees pour le champ specifie
*/
double Biometrique_ecartTypeChamp(Biometrique *donnees, unsigned char champ, int nombre);
/*
* [pre] +donnees+ est initialise, +champ+ le champ a traiter
+nombre+ le nombre de donnees a traiter
* [post] Renvoie le coefficient de variation
*/
#define Biometrique_coefVariationChamp(donnees, champ, nombre)\
Biometrique_ecartTypeChamp((donnees),(champ),(nombre))/Biometrique_moyenneChamp((donnees),(champ),(nombre))
#
/*
* [pre] +donnees+ est initialise, +champ+ le champ a traiter
+nombre+ le nombre de donnees a traiter
* [post] Renvoie la longueur de l'intervalle de confiance
*/
#define Biometrique_intConfianceChamp(donnees, champ, nombre)\
(3.92*Biometrique_ecartTypeChamp((donnees), (champ), (nombre))/sqrt(nombre))
#
/*
* [pre] +chemin+ est le chemin d'un fichier, +resultat+ est alloue
* [post] les +n+ premieres entrees de resultat contiennent des donnees du fichier,
* ou +n+ est la valeur de retour de la fonction (<= +nombre+).
En cas d'erreur, la fonction renvoie un nombre negatif.
*/
int Biometrique_litFichier(const char *chemin, Biometrique *resultat, int nombre);
/*
* [pre] +donnees+ est initialise, +nombre+ le nombre de donnees a traiter
+age+ est l'age dont on souhaite la frequence relative
* [post] Renvoie la frequence relative de cet age
*/
double Biometrique_freqRelAge(Biometrique *donnees, int age, int nombre);
/*
* [pre] +donnees+ est initialise, +nombre+ le nombre de donnees a traiter
+output+ est un pointeur sur fichier ouvert en ecriture
* [post] Ecrit toutes les frequences relatives et frequences relatives
cumulees dans +output+ au format specifie dans l'enonce
*/
void Biometrique_afficheFreqRelCumuleeAges(Biometrique *donnees, FILE *output, int nombre);
#endif
#include "stats.h"
#include <stdio.h>
/* Nombre maximal d'entrees biometriques par fichier */
#define DONNEES_MAX 252
/*
* vrai si +n+ est compris entre +min+ et +max+ inclus
*/
#define entre(min,n,max) (min<=n && n<=max)
/*
* Demande a l'utilisateur de choisir une action et renvoie le numero de l'action choisie
* 1: moyenne - 2: ecart type - 3: intervalle de confiance
* 4: coefficient de variation - 5: frequence relative+cumulee
* 6: quitter
*/
int menuChoixAction(void);
/*
* Demande a l'utilisateur de choisir un champ, et renvoie l'indice
* qu'a ce champ dans une entree biometrique
*/
int menuChoixChamp(void);
/*
* Programme d'interface utilisateur.
* Main ne s'occupe que de traiter les arguments
*/
int programme(const char *fichier_input);
int main(int argc, char **argv){
char *fichier_input = NULL;
int res;
if (argc >= 2)
fichier_input = argv[1];
else {
fichier_input = malloc(12*sizeof(char));
strcpy(fichier_input, "Dataset.dat");
fichier_input[11] = '\0';
}
res = programme(fichier_input);
if (fichier_input != argv[1])
free(fichier_input);
return res;
}
int menuChoixAction(void){
int choix = 0;
printf("Que voulez-vous faire ?\n");
printf("1. Calculer la moyenne\n");
printf("2. Calculer l'ecart type\n");
printf("3. Calculer l'intervalle de confiance\n");
printf("4. Calculer le coefficient de variation\n");
printf("5. Calculer la frequence relative et la frequence relative cumulee de l'age\n");
printf("6. Quitter\n");
while (! entre(1, choix, 6)) {
printf(" > ");
if (scanf("%d", &choix) != 1)
//Vide le tampon des caracteres qui ne peuvent etre traites par %d
fpurge(stdin);
}
return choix;
}
int menuChoixChamp(void){
int choix=0, res;
printf("Quelle donnee voulez-vous utiliser ?\n");
printf("1: age\n2: poignet\n3: taille\n4: abdomen\n");
while (! entre(1, choix, 4)) {
printf(" > ");
if (scanf("%d", &choix) != 1)
//Vide le tampon des caracteres qui ne peuvent etre traites par %d
fpurge(stdin);
}
switch (choix){
case 1: res = BIO_AGE; break;
case 2: res = BIO_POIGNET; break;
case 3: res = BIO_TAILLE; break;
case 4: res = BIO_ABDOMEN; break;
}
return res;
}
int programme(const char *fichier_input){
Biometrique donnees[DONNEES_MAX];
int actif=1;
int nbre_donnees = Biometrique_litFichier(fichier_input, donnees, DONNEES_MAX);
double moyenne, intervalle_confiance;
int choix_champ;
if (nbre_donnees < 1){
printf("Erreur de lecture du fichier\n");
return 1;
}
printf("Fichier %s charge (%d personnes)\n", fichier_input, nbre_donnees);
while (actif){
switch (menuChoixAction()){
case 1:
printf("Moyenne: %lf\n",
Biometrique_moyenneChamp(donnees, menuChoixChamp(), nbre_donnees));
break;
case 2:
printf("Ecart-type: %lf\n",
Biometrique_ecartTypeChamp(donnees, menuChoixChamp(), nbre_donnees));
break;
case 3:
choix_champ = menuChoixChamp();
intervalle_confiance = Biometrique_intConfianceChamp(donnees, choix_champ, nbre_donnees);
moyenne = Biometrique_moyenneChamp(donnees, choix_champ, nbre_donnees);
printf("Intervalle de confiance: ]%lf,%lf[ (longueur: %lf)\n",
moyenne-intervalle_confiance/2,
moyenne+intervalle_confiance/2, intervalle_confiance);
break;
case 4:
printf("Intervalle de confiance:%lf\n",
Biometrique_coefVariationChamp(donnees, menuChoixChamp(), nbre_donnees));
break;
case 5:
Biometrique_afficheFreqRelCumuleeAges(donnees, stdout, nbre_donnees);
break;
case 6: actif=0; break;
}
}
printf("Au revoir !\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment