using System; //using System.IO; using System.Threading.Tasks; using Xamarin.Forms; //using Android.Views.InputMethods; [assembly:ExportFont("digital-7.ttf")] namespace CalculadorDeEstadisticos { public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); } private decimal Entrada1; int A=1,B=1; int c=0; private string Operacion; double Media; double CU=0; double M=0; string MedText=""; double?[] x; string orden=""; private bool Operador; int N=0; int[] f; string Cuartiles=""; double[] Datos; string frec=""; string MO=""; int dec=0; decimal b = 2.11M; double sturges=0; double Interval=0; string DISPERSION; string Sesgo=""; double sk=0; string AgrupD=""; string AgrupC=""; string CURTOSIS=""; protected override void OnAppearing() { Entero.Focus(); ResED.IsVisible=false; } private async void BtEntClick(object sender, EventArgs e) { try { double Sum=0; //double Datos=new Datos[]; N = int.Parse(Entero.Text); Datos = new double[N]; if (N>1) { ResED.Text=$"Número de Datos = {N}"; marco.IsVisible=true; ResED.IsVisible=true; Inicio2: await Task.Delay(10); int muestreo = int.Parse (await DisplayPromptAsync("Enteros aleatorios: 1 ", "Muestreo manual: 2", keyboard : Keyboard.Numeric)); if(muestreo!=1 & muestreo!=2) { goto Inicio2; } switch(muestreo) { case 1: { string[] extremo=new string[2]; extremo[0]="Menor"; extremo[1]="Mayor"; int[] extremos = new int[2]; for (int i=0; i<2; i++) { int Ingreso = int.Parse (await DisplayPromptAsync($"Ingrese valor", $"{extremo[i]}", keyboard : Keyboard.Numeric)); extremos[i]=Ingreso; } Random Num = new Random(); for(int a=0; a Datos[k + 1]) { double y = Datos[k]; Datos[k] = Datos[k + 1]; Datos[k + 1] = y; } } } } //Calculo de segundo y cuarto momento double Ds; double SM = 0; double X = Math.Round(Sum / N, 2); double CM = 0; for (int j = 0; j < N; j++) { SM = SM + Math.Pow(Datos[j] - Media, 2); CM = CM + Math.Pow(Datos[j] - Media, 4); } double VAR = SM/(N-1); Ds = Math.Sqrt(SM/(N-1)); if (Ds != 0) { CU = CM / ((N-1) * Math.Pow(Ds, 4)); } b = Math.Round(Convert.ToDecimal(Ds), 2); //Calculo de frecuencias simples x = new double? [Datos.Length]; f = new int [Datos.Length]; int Max = 0; for (int i = 0; i < N; i++) { c = 0; f[i] = 0; for (int k = 0; k < N; k++) { if (Datos[k] == Datos[i]) { ++c; if (caso(Datos[i])) { x[i] = Datos[i]; } } if (c >= Max) { Max = c; } } f[i] = c; double r = Math.Round(100 * Convert.ToDouble(f[i]) / Convert.ToDouble(N), 1); if (x[i] != null) { frec= frec + $"\n({x[i]} → {c} → {r} %)"; } } bool caso(double valor) { for (int i = 0; i < x.Length; i++) { if (x[i] == valor) { return false; } } return true; } // Visualizacion de valores modales posibles string modas = ""; int z = 0; int s = 0; int us = 1; for (int j = 0; j < x.Length; j++) { if (f[j] == Max && Max > 1) { z++; if (x[j] != null) { s++; MO=MO+$"\nModa {s} = {x[j]}"; us = j; modas = modas + Convert.ToString(x[j]) + ", "; } } } if (Max != 1) { MO=MO+$"\nFrecuencia modal = {Max}"; } string modas1 = modas; if (s > 1) { modas1 = modas.TrimEnd(' '); modas1 = modas1.TrimEnd(','); string umoda = Convert.ToString(x[us]); int ulm = umoda.Length + 1; modas1 = modas1.Insert(modas1.Length - ulm, " y"); } if (Max == 1) { modas = null; MO="No existe valor modal alguno.\n La muestra tiende a una distribución Uniforme, ningún valor se repite."; } else if (Max > 1 && s == 2) { MO=MO+$"\nBimodal: {modas1} con una frecuencia de {Max} las dos."; } else if (Max > 1 && s > 2) { MO=MO+$"\nMultimodal: {modas1} con una frecuencia de {Max} cada una."; } //Condicionales para determinar la Mediana if (N % 2 == 1) { M = Datos[((N + 1) / 2) - 1]; MedText=$"La mediana es {M} y pertenece a la muestra"; } if (N % 2 == 0 && Datos[N / 2 - 1] == Datos[N / 2]) { M = Datos[N / 2]; MedText=$"La mediana es {M} y pertenece a la muestra"; } else if (N % 2 == 0 && Datos[N / 2 - 1] != Datos[N / 2]) { M = (Datos[N / 2 - 1] + Datos[N / 2]) / 2; MedText=$"La mediana es {M} y no pertenece a la muestra"; } //CÁLCULO parámetros de DISPERSIÓN double unit = Math.Pow(10, -dec); double range = (Datos[N - 1] - Datos[0]) + unit; DISPERSION=$"Xmax = {Datos[N - 1]}, Xmin = {Datos[0]}"; DISPERSION=DISPERSION+$"\nRANGO = {range}"; if (N >= 8) { sturges = Math.Round(1 + 3.3 * Math.Log10(N), 0); DISPERSION=DISPERSION+$"\nIntervalos de clase sugeridos según Sturges:\n#CLASES = Math.Round(1 + 3.3 x Log {N},0) = {sturges}"; } Interval = Math.Round(Convert.ToDouble(range * Math.Pow(10, dec)) / sturges, 0) * unit; DISPERSION=DISPERSION+$"\nLONGITUD DE INTERVALO:\n I = Math.Round(RANGO/#clases,0) = {Interval}"; DISPERSION=DISPERSION+$"\nVarianza S² = {Math.Round(VAR,2)}"; DISPERSION=DISPERSION+$"\nDesviación estándar S = {b} unidades."; DISPERSION=DISPERSION+"\nRELACIÓN DE 'CHEBYSHEV':"; DISPERSION=DISPERSION+$"\nμ = {Media}, S = {b}"; if (Ds!=0) { int tn=1; do { int ch=0; double ms =Math.Round(Media - tn*Convert.ToDouble(b),2); double Ms = Math.Round(Media + tn*Convert.ToDouble(b),2); for(int j=0; j=ms & Datos[j]<=Ms) { ch++; } } double chr = 100*Math.Round(Convert.ToDouble(ch)/Convert.ToDouble(N),2); if (tn==1) { DISPERSION=DISPERSION+$"\n(μ ± S) = ({ms}, {Ms}), {ch} de {N} se encuentran en este intervalo, ≈ un {chr}%."; if (ch==N){break;} goto next; } DISPERSION=DISPERSION+$"\n(μ ± {tn}S) = ({ms}, {Ms}), {ch} de {N} se encuentran en este intervalo, ≈ un \t{chr}%."; if (ch==N){break;} next: tn++; } while (tn<=3); } else { DISPERSION=DISPERSION+"\nDesviación estándar nula, no existe relación de Chebyshev"; } //Determinación de ASIMETRIA O SESGO Sesgo="sk=(N/(N-1)(N-2))(Σ((x - Media)/s)³"; double TM=0; for(int i=0; i 1 && s == 1) { if (Math.Abs(sk) <= 0.2) { if(Math.Abs(Media-Convert.ToDouble(x[us]))<0.2) { Sesgo=Sesgo+$"\n sk = {sk} ¡ Asimetría o sesgo mínimo !!:"; Sesgo=Sesgo+"\nMuestra con tendencia simétrica, o tendencia t-Student: Distribución unimodal con Media, Mediana y Moda muy cercanas entre sí."; } else { if(sk<0) { Sesgo=Sesgo+$"\nMuestra ligeramente sesgada a la izquierda, con sk = {sk}"; } else if(sk>0) { Sesgo=Sesgo+$"\nMuestra ligeramente sesgada a la derecha, con sk = {sk}"; } } } else if (Math.Abs(sk) > 0.2 && sk<0 ) { Sesgo=Sesgo+$"\nMuestra unimodal con sesgo {sk} negativo o tendencia asimétrica con sesgo hacia la izquierda."; } else if (Math.Abs(sk) > 0.2 && sk>0) { Sesgo=Sesgo+$"\nMuestra unimodal con sesgo {sk} positivo o tendencia asimétrica con sesgo hacia la derecha."; } else { Sesgo=Sesgo+$"\nMuestra con sesgo sk = {sk}"; } } else if (Max > 1 && s > 1)//Si existe moda y hay más de una. { Sesgo=Sesgo+$"\nEl valor del sesgo {sk}, podría no ser significativo porque la muestra presenta {s} picos modales en {modas1} los cuales forman altibajos."; } else { Sesgo=Sesgo+$"\nMuestra con tendencia uniforme. El valor sk = {sk} es irrelevante"; } //Determinación de CURTOSIS CURTOSIS="CURTOSIS (Ω):"; CURTOSIS=CURTOSIS+"\nAglomeración entorno a la media. Tipos:"; CURTOSIS=CURTOSIS+"Leptocúrtica Ω > 3 (Punteaguda)"; CURTOSIS=CURTOSIS+"\nMesocúrtica Ω = 3 (Curva Normal)"; CURTOSIS=CURTOSIS+"\nFlaticúrtica Ω < 3 (Achatada)"; CURTOSIS=CURTOSIS+"\nPara esta muestra:"; if (Ds == 0) { CURTOSIS=CURTOSIS+"\n Ω es Indefinida, porque S = 0."; } if (Ds != 0) { CURTOSIS=CURTOSIS+$"\n Ω = {Math.Round(CU, 3)}"; } if(CU>0 && Max>1 && s>1 || modas==null) { CURTOSIS=CURTOSIS+"\nEl valor de Ω no se puede caracterizar geométricamente, porque la muestra presenta más de una cumbre modal, o bien es una muestra que tiende a una distribución uniforme."; } else if (CU > 3 && Ds!=0) { CURTOSIS=CURTOSIS+$"\nMuestra con tendencia leptocúrtica, con un exceso (pico de cumbre) de \nΩ - 3 = {Math.Round(CU - 3, 3)}, por encima de la curva Normal."; if (CU - 3 < 0.2 & CU - 3 >= 0.1) { CURTOSIS=CURTOSIS+"\nAunque el exceso es mínimo, pudiendo considerarse 'cuasinormal' "; } } else if (Math.Abs(CU - 3) < 0.1 && Ds!=0) { CURTOSIS=CURTOSIS+"\nMuestra con tendencia Mesocúrtica o de curva Normal(Ω = 3)."; } else if (CU < 3 && Ds != 0) { CURTOSIS=CURTOSIS+$"\nMuestra con tendencia flaticúrtica, con una disminución de cumbre \n3 - Ω = {Math.Round(3 - CU, 3)}, por debajo de la curva Normal."; if (3 - CU < 0.2 && 3 - CU >= 0.1) { CURTOSIS=CURTOSIS+"\nAunque la disminución es mínima, pudiendo considerarse 'cuasinormal'."; } } //STURGES-D: Agrupación Discreta AgrupD="AGRUPACION DISCRETA SUGERIDA"; double Inicial = Datos[0]; double Final = 0; int Fam=0; AgrupD=AgrupD+$"\nLONGITUD DE INTERVALO I = {Interval}"; if(N<8) { AgrupD=AgrupD+$"\nLa agrupación es inpropia para N < 8"; await Task.Delay(15); await DisplayAlert("La agrupación es impropia para \nN < 8", "","Aceptar"); } AgrupD=AgrupD+"\nClase → Marca → f → F → f%"; do { Final = Inicial + Interval; Final = Math.Round(Final, dec); double Xm = (Inicial + Final) / 2; int Fm = 0; for (int t = 0; t < N; t++) { if (Datos[t] >= Inicial && Datos[t] <= Final) { Fm++; } } Fam = Fam + Fm; double Fp = Math.Round(Convert.ToDouble(Fm) * 100 / Convert.ToDouble(N), 2); AgrupD=AgrupD+$"\n{Inicial} - {Final} | {Xm} | {Fm} | {Fam} | {Fp}"; Inicial = Math.Round(Final + unit, dec); } while (Final < Datos[N - 1]); //STURGES-C: Agrupación Contínua AgrupC="AGRUPACION CONTINUA SUGERIDA"; AgrupC=AgrupC+$" LONGITUD DE INTERVALO:\n I + unity = {Interval + unit}"; if(N<8) { AgrupD=AgrupD+$"\nLa agrupación es inpropia para N < 8"; } double LRI = Datos[0] - 5 * Math.Pow(10, -dec - 1); double LRF = 0; double Fcam=0; double Xmr = 0; int Fmr = 0; AgrupC=AgrupC+"\nClase → Marca → f → F → f%"; do { LRF = LRI + Interval + 1 * unit; LRF = Math.Round(LRF, dec + 1); Xmr = (LRI + LRF) / 2; Fmr = 0; for (int t = 0; t < N; t++) { if (Datos[t] > LRI && Datos[t] < LRF) { Fmr++; } } Fcam = Fcam + Fmr; double Fpr = Math.Round(Convert.ToDouble(Fmr) * 100 / Convert.ToDouble(N), 2); AgrupC=AgrupC+$"\n{LRI} - {LRF} | {Xmr} | {Fmr} | {Fcam} | {Fpr}"; LRI = LRF; } while (LRF < Datos[N - 1]); marco.IsVisible=true; ResED.IsVisible=true; } catch(FormatException ex) { await DisplayAlert("El entero debe ser \nmayor que 1", ex.Message,"Salir"); } } private void BtOrdenClick(object sender, EventArgs e) { orden=""; ResED.Text=""; for (int i=0; i=4 && Datos[0]!=Datos[N-1]) { int nd1= N+ 1; double Pos = 0.25*nd1; double Q1; int PQ1; PQ1 = Convert.ToInt32(Math.Truncate(Pos)); Q1 = Datos[PQ1 - 1] + (Pos - PQ1) *(Datos[PQ1]-Datos[PQ1 - 1]); Cuartiles="CUARTIL Q1:"; Cuartiles= Cuartiles + $"\nPosición: (N+1)/4 = {nd1}/4 = {Pos}"; Cuartiles=Cuartiles+$"\nValor: Q1 = {Q1}; un 25% de los datos \nes menor o igual que {Q1}."; Cuartiles=Cuartiles+$"\n\nCUARTIL Q2 = {M} = Mediana."; double Pos3=0.75 * nd1; double Q3; int PQ3; PQ3=Convert.ToInt32(Math.Truncate(Pos3)); Q3 = Datos[PQ3 - 1] + (Pos3 - PQ3)*(Datos[PQ3]-Datos[PQ3 - 1]); Cuartiles=Cuartiles+"\n\nCUARTIL Q3:"; Cuartiles=Cuartiles+$"\nPosición: 3(N+1)/4 = 3 x {nd1}/4 = {Pos3}"; Cuartiles=Cuartiles+$"\nValor: Q3 = {Q3}; un 75% de los datos \nes menor o igual que {Q3}."; } else if(N==0) { Cuartiles=""; } else { Cuartiles="No es posible determinar cuartiles para \n\tN < 4 \nNi para muestras que constan de un solo valor repetido."; } ResED.Text=$"{Cuartiles}"; marco.IsVisible=true; } } }