[Exercice 49] Maths de Lycée avec AngularJs

Introductionpouvoir-statistiques-icone-8550-96.png


Un micro exercice de calculs de pourcentages, probabilité, fait en 2 heures 30.

Il permet d’établir des stats de défectuosité sur un objet, automatiquement et les stats se mettent à jour lorsqu’on ajoute les données du jour. Pas de Back end mais je devrais en faire un rapide avec Firebase, c’est tellement facile.

Explication technique sommaire : $scope.objet est un tableau d’objets Json « container » que l’on rafraichit à loisir par les données d’un carburateur ou d’un démarreur ou que sais-je, on peut réaliser un appel back end lors du changement d’objet. Demain, j’ajouterais un graphique chart.Js et un back end en Firebase noSql vite fait. Je ferais aussi des pbs conditionnelles si possibles et Stats comparatives entre objets.

Note importante : Ce code utilise à fond le 2 way binding, en cela, il est possible qu’il soit sujet à problème de performances si les données dépassaient les 2000 lignes. En ce cas, la ré-écriture totale du code s’imposerait probablement. (A « mocquer » avec un modèle de données de 3000 objets Json pour tester..)

Pour le tester c’est ici : 

Photo de l’exo :


exo49.jpg

Sommaire :


  • Jour 1 : 2 h30 de code.
  • Jour 2 : Ajout d’un graphe en 15 minutes.
  • Jour 3 : Correction de la formule de moyenne d’une série, qui était fausse, grâce au livre 1ère S Prépabac.

 

Le code Jour 1


HTML :


<html ng-app="App">
	<head>
		<meta charset="utf-8" />
		<title>Statistiques de production.</title>

		<!-- JQUERY ET BOOTSRAP -->
		<script src="bower_components/jquery/dist/jquery.min.js"></script>
		<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
		<link rel="stylesheet" type="text/css" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
		<!-- Custom styles for this template -->
		<link href="sticky-footer.css" rel="stylesheet">

		<!-- ANGULAR -->
		<script src='bower_components/angular/angular.min.js'></script>

		<!-- UI BOOTSTRAP -->
		<script src='bower_components/angular-bootstrap/ui-bootstrap.min.js'></script>
		<script src='bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js'></script>
	</head>

	<body ng-controller="MainCtrl">
		<div class="container-fluid">
			<nav class="navbar navbar-inverse">
			  <div class="container-fluid">
					<div class="navbar-header">
						<a class="navbar-brand" href="#">ProductionStats</a>
					</div>
					<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
						<ul class="nav navbar-nav navbar-right">
							<div class="form-group">
								<form>
								</form>
							</div>
						</ul>
					</div><!-- /.navbar-collapse -->
				</div><!-- /.container-fluid -->
			</nav>

			<div class="row">
				<div class="col-md-6">
				<h1> {{objet.nom}}</h1>
				<button ng-click="changerObjet()" class="btn btn-primary btn-lg active ">Demarreur</button>
				<img src="{{objet.image}}" class="img-responsive"/>
				</div>
				<div class="col-md-6">
				<select class="form-control" ng-model="g" required>
					<option value="">Classer par</option>
					<option value="defectueux">Défectueux</option>
					<option value="production">Production</option>
				</select>
					<table class="table-bordered table-hover table-condensed table-responsive" style="width:100%">
						<thead>
							<tr>
								<th>Jour </th>
								<th>Production </th>
								<th>Défectueux</th>
								<th>Fréquence Défectueux</th>
								<th>Pourcentage Défectueux</th>
							</tr>
						</thead>
						<tbody>
							<tr ng-repeat="objet in objet | orderBy:g">
								<td>{{objet.jour}}</td>
								<td>{{objet.production}}</td>
								<td>{{objet.defectueux}}</td>
								<td>{{(objet.defectueux/objet.production).toFixed(2)}}</td>
								<td>{{((objet.defectueux/objet.production)*100).toFixed(2)}} %</td>
							</tr>
						</tbody>
						<tbody>
							<tr class="success" >
								<td >Total</td>
								<td>{{objet.sommeProduction()}}</td>
								<td>{{objet.sommeDefectueux()}}</td>
								<td>{{(objet.sommeDefectueux()/objet.sommeProduction()).toFixed(2)}}</td>
								<td>{{((objet.sommeDefectueux()/objet.sommeProduction())*100).toFixed(2)}} %</td>
							</tr>
						</tbody>

					</table>
				<br>
				</div>
			</div>
			<div class="row">
				<div class="col-md-6">

						<table class="table-bordered table-hover table-condensed table-responsive">
						<thead>
							<tr>
								<th><img class="icone" src="img-app/moyenne.png" ></th>
								<th><img class="icone" src="img-app/probability.png" ></th>
							</tr>
						</thead>
						<thead>
							<tr>
								<th>Moyenne de défectuosité </th>
								<th>Probabilité de défectuosité</th>
							</tr>
						</thead>
						<tbody>
							<tr >
								<td>{{objet.moyenneDefectueux()}}</td>
								<td>{{objet.probabiliteDefectueux()}} %</td>
							</tr>
						</tbody>
					</table>
				</div>
					<div class="col-md-6">

					<form>
						<table class="table-bordered table-hover table-condensed table-responsive">
						<thead>
							<tr>
								<th><img class="icone" src="img-app/add.png" ></th>

							</tr>
						</thead>
						<thead>
							<tr>
								<th>Production</th>
								<th>Défectueux</th>
							</tr>
						</thead>
						<tbody>
							<tr >
								<td><input type="number" ng-model="prod" required></td>
								<td><input type="number" ng-model="defct" required></td>
							</tr>
						</tbody>
						<tbody>
							<tr class="success" >
								<td></td>
								<td><button ng-click="ajouter()" class="btn btn-primary btn-lg active pull-right">Ajouter</button></td>
							</tr>
						</tbody>
						</table>
					</form>
				</div>
			</div>

			<footer class="footer">
			  <div class="container">
				<p class="text-muted">Votre pied de page.</p>
			  </div>
			</footer>

		<!-- FIND DE DIV GLOBALE FLUID BOOSTRAP POUR LES PHONES -->
		</div>
		<script src="app.js"> </script>
	</body>
</html>
<style>
.img{
width:500px;
}
.icone{
width:100px;
}
</style>

Le fichier JS :

var app = angular.module('App', ['ui.bootstrap','chart.js'])

app.controller('MainCtrl', function($scope,$timeout) {
	
$scope.Math = window.Math;

$scope.listeObjets = [
{"nom":"carburateur","image":"img-app/64_3.gif","donnees":[
{"date":"","jour":1,"production":200,"defectueux":10,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":2,"production":180,"defectueux":20,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":3,"production":250,"defectueux":35,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":4,"production":305,"defectueux":75,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":5,"production":250,"defectueux":25,"frequence":"","pourcentage":"","moyenne":""},
]},
{"nom":"Démarreur","image":"img-app/demarreur.gif","donnees":[
{"date":"","jour":1,"production":200,"defectueux":10,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":2,"production":100,"defectueux":20,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":3,"production":250,"defectueux":35,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":4,"production":320,"defectueux":75,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":5,"production":250,"defectueux":25,"frequence":"","pourcentage":"","moyenne":""},
]},
{"nom":"Alternateur","image":"","donnees":[
{"date":"","jour":1,"production":200,"defectueux":10,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":2,"production":180,"defectueux":20,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":3,"production":505,"defectueux":35,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":4,"production":210,"defectueux":75,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":5,"production":250,"defectueux":25,"frequence":"","pourcentage":"","moyenne":""},
]},
];	



/* MODELE DE DONNEES DE LOBJET . */	
$scope.objet = [
{"date":"","jour":1,"production":200,"defectueux":10,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":2,"production":180,"defectueux":20,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":3,"production":250,"defectueux":35,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":4,"production":305,"defectueux":75,"frequence":"","pourcentage":"","moyenne":""},
{"date":"","jour":5,"production":250,"defectueux":25,"frequence":"","pourcentage":"","moyenne":""},
];
$scope.objet.image = "img-app/64_3.gif";
$scope.objet.nom = "Carburateur";


/* SOMME DE LA PRODUCTION DE L OBJET  */
$scope.objet.sommeProduction = function(){
	var total = 0;
	for (var i = 0; i < $scope.objet.length; i++) {
		total = total + $scope.objet[i].production;
	}
    return total;
	
};

/* SOMME D OBJETS DEFECTEUX */
$scope.objet.sommeDefectueux = function(){
	var total = 0;
	for (var i = 0; i < $scope.objet.length; i++) {
		
		total = total + $scope.objet[i].defectueux;
	}
	return total;
};

/* MOYENNE DE LA SERIE D OBJETS DEFECTUEUX (LIVRE DE 1ERE S PREPABAC )*/
$scope.objet.moyenneDefectueux = function(){
	var total = 0;
	var N = 0; 
	for (var i = 0; i < $scope.objet.length; i++) {
		N = N + $scope.objet[i].production;
	}
	
	for (var i = 0; i < $scope.objet.length; i++) {
		total = total + ($scope.objet[i].defectueux*$scope.objet[i].production);
	}
	return (total/N).toFixed(2);
};

/* PROBABILITE D OBJETS DEFECTEUX */
$scope.objet.probabiliteDefectueux = function(){
	var total = 0;
	total = $scope.objet.sommeDefectueux() / $scope.objet.sommeProduction(); 
	return (total*100).toFixed(2);
};

/* AJOUT A OBJET  */
$scope.ajouter = function(){
	var jour = $scope.objet.length+1;
	$scope.objet.push(
	{"date":"","jour":jour,"production":$scope.prod,"defectueux":$scope.defct,"frequence":"","pourcentage":"","moyenne":""}
	)
	$scope.initGraphe();
}


$scope.changerObjet = function(){
	/* Supprimer le contenu de objet */
	$scope.objet.splice(0,$scope.objet.length);
	/* remplir l'objet avec les données du nouvel objet */
	$scope.objet.push(
		{"date":"","jour":1,"production":250,"defectueux":10,"frequence":"","pourcentage":"","moyenne":""},
		{"date":"","jour":2,"production":250,"defectueux":20,"frequence":"","pourcentage":"","moyenne":""},
		{"date":"","jour":3,"production":100,"defectueux":35,"frequence":"","pourcentage":"","moyenne":""},
		{"date":"","jour":4,"production":500,"defectueux":75,"frequence":"","pourcentage":"","moyenne":""},
		{"date":"","jour":5,"production":250,"defectueux":25,"frequence":"","pourcentage":"","moyenne":""});
		 
	$scope.objet.image = "img-app/demarreur.gif";
	$scope.objet.nom = "Démarreur";
	$scope.initGraphe();
}

/* GRAPHE */
$scope.initGraphe = function(){
	
	/* Initialisation des données que l on passe ensuite au graphique , on les puise dans $scope.objet, le modele principal de donnees*/

	var labels = []; // dans ce cas les labels seront les jours
	var tabProd = []; // Va contenir tous les chiffres de production d objet
	var tabDefectueux = [];	 // Va contenir tous les chiffres de production d objet defectueux

	for(x=0;x<$scope.objet.length;x++){
				labels.push($scope.objet[x].jour);
			}

	for(x=0;x<$scope.objet.length;x++){
		tabProd.push($scope.objet[x].production);
	}

	for(x=0;x<$scope.objet.length;x++){
		tabDefectueux.push($scope.objet[x].defectueux);
	}

	$scope.labels = labels; 
	$scope.series = ['Production', 'Défectueux'];
	$scope.data = [tabProd,tabDefectueux]; // le tableau est double il y a deux séries de points, les objets produits et les objets defectueux
	$scope.onClick = function (points, evt) {
		console.log(points, evt);
	};
}
$scope.initGraphe();
})


Publicités