Autor Tema: Duda sobre un ejercicio c# o csharp  (Leído 1530 veces)

javierx0246

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 7
    • Ver Perfil
Duda sobre un ejercicio c# o csharp
« en: 27 de Enero 2023, 12:20 »
Hola estoy haciendo un ejercicio y cuando lo ejecuto .Me sale que el calculo que he realizado esta fuera del array por eso necesito vuestra ayuda .Gracias


 
 

 
La aplicación permitirá recoger datos de una cuenta bancaria. Deberás crear los siguientes métodos y comprobar que funcionan correctamente. Prueba la aplicación con más de un número de cuenta y captura las posibles excepciones en el programa principal.

    El constructor NumeroCuenta recibirá un string con el número de cuenta completo y si este no se corresponde con un número de cuenta correcto se lanzara una excepción NumeroCuentaIncorrectoException. Esta excepción se puede lanzar por dos motivos:
        Porque no cumple el patrón de un número de cuenta (para ello llamará al método formatoCorrecto)
        Porque la cuenta no se corresponde con los dígitos de control (en este caso usara dcCorrecto).

    El método privado de NumeroDeCuenta, formatoCorrecto. Comprobará el formato del número de cuenta con expresiones regulares y si el formato es correcto rellenará los campos del objeto. En caso contrario lanzará una excepción NumeroCuentaIncorrectoException, indicando que el formato de la cuenta no cumple las condiciones necesarias.

    El método privado dcCorrecto, comprobará si el dígito de control corresponde a la cuenta, devolviendo false en caso contrario. Para ver como se hace esto, consulta la Nota y la Pista posterior.

    El método Reintegro, lanzará una exception SaldoInsuficienteException, cuando se intente retirar una cantidad y no haya suficiente saldo.

El código cuenta corriente es un número de 20 cifras. Las 4 primeras de la izquierda identifican a la Entidad, las 4 siguientes, la Sucursal, luego vienen 2 dígitos de control y las 10 últimas corresponden al número de la cuenta corriente.

    El primero es el dígito de control de Entidad/Sucursal.
    El segundo es el dígito de control del número de la cuenta corriente.

El siguiente ejemplo nos enseñará a calcularlos…

Supongamos ahora 2085 el código de una hipotética entidad y 0103 el código de una de sus sucursales.

Para calcular el dígito de control de Entidad/Sucursal:

    Realizaremos la operación:
    2*4 + 0*8 + 8*5 + 5*10 + 0*9 + 1*7 + 0*3 + 3*6 = 123

    Es decir, cada una de las cifras de la entidad, seguidas de la sucursal, se han ido multiplicando por los números del array de ponderaciones 4, 8, 5, 10, 9, 7, 3, 6 y luego se han sumado estos resultados.

    Ahora realizaremos la operación 11 – (resultado % 11)
    El resultado será un número entre 1 y 11. Si el número es menor que 10 será ya el valor del DC. Pero si es 10 el DC será 1 y si es 11 será 0. En este caso 11 – (123 % 11) = 9 que será el DC de Entidad/sucursal.

Para calcular el dígito de control de número de cuenta corriente:

    Si este es, por ejemplo, el 0300731702, para calcular su dígito de control se realiza la operación:
    0*1 + 3*2 + 0*4 + 0*8 + 7*5 + 3*10 + 1*9 + 7*7 + 0*3 + 2*6 = 141
    Es decir, cada una de las cifras del número de la cuenta, leídas de izquierda a derecha, se han ido multiplicando por 1, 2, 4, 8, 5, 10, 9, 7, 3, 6 y luego se han sumado estos resultados.
    Realizaremos la misma operación que antes 11 – (121 % 11) = 2 que será el DC de número de cuenta.
 





Mi codigo



Código: [Seleccionar]
using System.Text.RegularExpressions;
namespace ejercicio4;
class NumeroCuenta
{
    class NumeroCuentaIncorrectoException : Exception
    {
        public NumeroCuentaIncorrectoException(string message) : base("tu poblema es " + message)
        {

        }
    }
    private string entidad;
    private string sucursal;
    private string dcEntSuc;
    private string dcNumero;
    private string cuenta;
    public NumeroCuenta(string numero)
    {
        dcCorrecto(dcEntSuc, entidad + sucursal, new int[] { 4, 8, 5, 10, 9, 7, 3, 6 });
        dcCorrecto(dcNumero, cuenta, new int[] { 1, 2, 4, 8, 5, 10, 9, 7, 3, 6 });
    }
    private bool dcCorrecto(string dc, string digitos, int[] ponderaciones)
    {
        int sumaPonderacion = 0;
        int sumaTotal = 0;
        int operacion = 0;
        for (int i = 0; i < ponderaciones.Length; i++)
        {
            sumaPonderacion += (digitos[i] - 48) * ponderaciones[i];
        }
        sumaTotal += sumaPonderacion;
        operacion = 11 - (sumaTotal % 11);



        int dcCalculado;

        if (operacion < 10)
        {

            dcCalculado = operacion;
        }
        else if (operacion == 10)
        {

            dcCalculado = 1;
        }

        else dcCalculado = 0;

        if (dcCalculado.ToString() == dc)
        {
            return true;
        }
        return false;
    }
    public bool FormatoCorrecto(string numero)
    {

        string patron = @"^((?<entidad>\d{4) ?(?<sucursal>\d{4}) ?(?<dcEntSuc>\d)(?<dcNumero>\d) ?(?<dcNumero>\d{10})$";
        bool isMatch = Regex.IsMatch(numero, patron);
          Regex r = new Regex(patron);
        Match match = r.Match(numero);
        if (isMatch == false) //Si es falso
        {

            throw new NumeroCuentaIncorrectoException("Mensaje");

        }
        else
        {
            int[] ponderacion = new int[8] { 4, 8, 5, 10, 9, 7, 3, 6 };


        }
        if(match.Success)
        {
             entidad = match.Groups["entidad"].Value;
            sucursal = match.Groups["sucursal"].Value;
            dcEntSuc = match.Groups["dcEntSuc"].Value;
            dcNumero = match.Groups["dcNumero"].Value;
            dcNumero = match.Groups["dcNumero"].Value;
        }
        return match.Success;
    }

     public override string ToString()
        {
            return $"{entidad}-{sucursal}-{dcEntSuc}{dcNumero}-{cuenta}";
        }
}
Muchas gracias por intentar ayudarme  ;)
« Última modificación: 27 de Enero 2023, 17:22 por Amancio »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re: Duda sobre un ejercicio c# o csharp
« Respuesta #1 en: 27 de Enero 2023, 21:46 »
Hola.
C# no es lo mío, pero aún así veo un par de cosas raras.

Primero, este constructor recibe como argumento un string llamado numero, es decir, el numero de cuenta del usuario.
Pero no parece que hagas nada con ese valor.
En el constructor llamas dos veces al método dcCorrecto() sin que reciba ese dato.
Citar
public NumeroCuenta(string numero)
    {
        dcCorrecto(dcEntSuc, entidad + sucursal, new int[] { 4, 8, 5, 10, 9, 7, 3, 6 });
        dcCorrecto(dcNumero, cuenta, new int[] { 1, 2, 4, 8, 5, 10, 9, 7, 3, 6 });
    }

En cambio, la primera vez que llamas dcCorrecto(), le pasas como segundo argumento la concatenación de los string: entidad + sucursal

Pero esos string, que son atributos de la clase, en ese momento creo que están vacíos, ¿no?

En cualquier caso, estén vacíos o no, dentro del método haces algo muy "peligroso", que es la causa principal del error.
En el bucle, estás usando el mismo índice i para recorrer el string digitos (que es la suma de entidad + sucursal) y también para recorrer el array ponderaciones.

Citar
    private bool dcCorrecto(string dc, string digitos, int[] ponderaciones)
    {
        int sumaPonderacion = 0;
        int sumaTotal = 0;
        int operacion = 0; System.Console.WriteLine(ponderaciones.Length);
        for (int i = 0; i < ponderaciones.Length; i++)
        {
            sumaPonderacion += (digitos[i ] - 48) * ponderaciones[i ];
        }

Ese índice i va a aumentar su valor según ponderaciones.Length, así que para recorrer el array de ponderaciones no hay problema.
Pero recorrer también el string digitos es arriesgado, porque no tiene porque medir lo mismo que el array de ponderaciones.

Por tanto, ese índice puede quedarse corto si el string digitos es más largo que el array ponderaciones.
O peor aún, y es probablemente lo que está pasando, si digitos es más corto el índice i va a ser demasiado alto para recorrer el string digitos y te lanzará el error de que el índice está fuera de los límites del array (un string también es un array)

Tienes que repensar la lógica que estás siguiendo.
Los atributos están vacíos cuando llamas a esos métodos, por eso los string miden 0 y el bucle no puede recorrerlos, porque no hay nada que recorrer.

Así que:

- Mira a ver que se supone que deberías hacer con el argumento "numero" que recibe el constructor, de momento, no estás haciendo nada con él.

- Comprueba qué debe suceder primero para que los atributos reciban valores antes de operar con ellos con los métodos.

- Estás llamando dos veces al método dcCorrecto(). ¿Quizás primero deberías llamar a FormatoCorrecto()? Parece que es este método quien sí podría hacer algo con el argumento "numero" y parece que además da valores a los atributos.
Aunque en este método también veo algo raro así a primera vista. Hay un else donde se crea un nuevo array de ponderaciones, pero no se usa ni se guarda en ningún atributo.
Este array, "muere" y desaparece en cuanto se cierra la llave de ese if else

Citar
        if (isMatch == false) //Si es falso
        {

            throw new NumeroCuentaIncorrectoException("Mensaje");

        }
        else
        {
            int[] ponderacion = new int[8] { 4, 8, 5, 10, 9, 7, 3, 6 };


        }

- Comprueba que string deberías recorrer en el bucle donde también recorres el array de ponderaciones.
¿Qué pasa si el string no tiene el mismo tamaño que ponderaciones?
¿Quizás haya que recorrerlo con otro bucle?


Lamento no poder darte indicaciones más precisas, no tengo mucho tiempo ahora para mirar más a fondo.

Pero esos puntos que he mencionado, son los que por ahora deberías revisar.

Un saludo.
« Última modificación: 27 de Enero 2023, 21:47 por Kabuto »
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".