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;
}
}
}