domingo, 6 de octubre de 2013

Respuesta al reto 3

Reto 3.

Ya me pique, pero me han salido en el trabajo dia a dia estas situaciones que sirven para probar mi ingenio al resolverlos. Espero que a ustedes tambien los motive, sobre todo a los nuevos programadores. Hacer una funcion que dado el numero de columna de una matriz, me regrese el nombre de la columna en Excel. Usar una funcion que se llame ASC que recibe como parametro un numero y regresa una cadena con el caracter del codigo ascii. Esto es para que al llamar a ASC(65) me regrese la letra A como cadena. Como ustedes saben las columnas en excel se referencian con letras, comenzando con la letra A, hasta la Z y de alli sigue la combinacion AA. Yo se que pueden usar funciones o codigos de internet, pero traten de resolverlo solo con el manejo de cadenas, usando la funcion basica ASC. Eso lo hara mas divertido. Aqui esta mi propuesta al reto 3. Esta en C#:

private string RegresaColumna(int Columna)
{
    Stack<string> Pila1 = new Stack<string>();
    string Regresa = "";
    int Residuo;
    int Resultado;
    Resultado = Columna;
    do
    {
        Residuo = Resultado % 26;
        if (Residuo == 0)
            Residuo = 26;
        Resultado = Resultado / 26;
        Pila1.Push(Char.ConvertFromUtf32(Residuo + 64));
    } while (Resultado > 26);
    if (Resultado > 0)
        Pila1.Push(Char.ConvertFromUtf32(Resultado + 64));
    foreach (string cad in Pila1)
    {
        Regresa += cad;
    }
    return Regresa;
}
Como lo menciona el Master Ariel Lopez, la idea es utilizar el operador % (módulo) para obtener el residuo de la división. El ciclo comienza a dividir entre 26 (que es el total de letras a generar) hasta que el resultado sea menor a 26. El problema es que el primer residuo que me regresa es la letra mas significativa (la que debe estar mas a la izquierda), es por ello que utilizo una pila para ir almacenandola, para despues sacarlas e irlas agregando a la cadena resultante. La función Char.ConvertFromUtf32 me sirve para convertir el valor numerico ASCII a una cadena. Al residuo le sumo 64, para que me de la letra deseada (el valor Ascii de A es 65). Finalmente lo que atinadamente comento en su solucion Ariel, si el residuo me da cero, tengo que ponerle el maximo valor, si no, no sale la letra Z. Esto solo se da en la ultima letra. Comenten y si encuentran algun error mejor.

viernes, 6 de septiembre de 2013

Respuesta al reto 1

Se tiene una base de datos con las tablas: Ventas, Clientes, DetalleVentas y SeriesDetalleVentas que contienen los datos de las ventas de equipos de computo y accesorios. La tabla SeriesDetalleVentas contiene los numero de serie de los productos vendidos.

Una consulta para obtener las ventas con sus clientes, detalles y series de ls detalles seria el siguiente:

SELECT Ventas.idVenta, FolioVenta, FechaVenta, Ventas.idCliente, Clientes.NombreCompleto, 
DetalleVentas.idDetalleVenta, Productos.idProducto,
Productos.DescripcionProd, DetalleVentas.Cantidad, DetalleVentas.Precio,
Serie
FROM Ventas
INNER JOIN Clientes
ON Ventas.idCliente = Clientes.idCliente
INNER JOIN DetalleVentas
ON Ventas.idVenta = DetalleVentas.idVenta
INNER JOIN Productos
ON DetalleVentas.idProducto = Productos.idProducto
INNER JOIN SeriesDetalleVenta
ON DetalleVentas.idDetalleVenta = SeriesDetalleVenta.idDetalleVenta
ORDER BY Ventas.idVenta, DetalleVentas.idDetalleVenta

Aqui lo interesante es que la ventas pueden tener solo un cliente, varios detalles y los detalles pueden tener varios numeros de serie.

Un ejemplo del resultado seria el siguiente:


El codigo para llenar todos los objetos de la consulta anterior en c# seria:

        public static void RecuperaVentas()
        {
            clsVentas Venta = new clsVentas();
            clsProductosMovs Producto;
            SqlDataReader dr;

            // Lo importante es definir un id anterior, para que en el momento que cambie, se cree
            // un nuevo objeto y se agregue el anterior a la coleccion
            int idVenta, idVentaAnterior = -1;
            int idDetalleVenta, idDetalleVentaAnterior = -1;

            while (dr.Read())
            {
                idVenta = Convert.ToInt32(dr["idVenta"]);

                // Si la venta es diferente a la anterior, se crea el objeto venta 
                // y se agrega a la coleccion
                if (idVenta != idVentaAnterior)
                {
                    Venta = new clsVentas();
                    Venta.idVenta = Convert.ToInt32(dr["idVenta"]);
                    Venta.FechaVenta = Convert.ToDateTime(dr["FechaVenta"]);
                    Venta.FolioVenta = Convert.ToInt32(dr["FolioVenta"]);
                    Venta.Cliente.idCliente = Convert.ToInt32(dr["idCliente"]);
                    Venta.Cliente.NombreCompleto = dr["NombreCompleto"].ToString();
                    Ventas.Agregar(Venta);
                }

                // Si el detalle de la venta es diferente a la anterior, se crea el objeto
                // detalle y se agrega a la coleccion
                if (idDetalleVenta != idDetalleVentaAnterior)
                {
                    Producto = new clsProductosMovs();
                    Producto.idDetalleVenta = Convert.ToInt32(dr["CantDetVenta"]);
                    Producto.Cantidad = Convert.ToInt32(dr["CantDetVenta"]);
                    Producto.idProducto = Convert.ToInt32(dr["idProducto"]);
                    Producto.Precio = Convert.ToSingle(dr["Precio"]);
                    Producto.DescripcionProd = dr["DescripcionProd"].ToString();
                    Venta.Detalle.Agregar(Producto);
                }

                // Finalmente se agrega la serie
                Producto.Series.Agregar(dr["Serie"].ToString();

                // Se actualizan los indices anteriores para el siguiente ciclo
                idVentaAnterior = idVenta;
                idDetalleVentaAnterior = idDetalleVenta;
            }
        }

Espero que tenga algun error para que comenten este codigo

jueves, 29 de agosto de 2013

Reto 1
Una de las principales tareas en cualquier programa es la de llenar una serie de objetos con los datos obtenidos de una matriz de resultados de una consulta a una base de datos. Por ejemplo, traer una venta con los datos de la venta, del cliente y de su detalle incluyendo los productos. Hacer una función en cualquier lenguaje, que obtenga los datos de una consulta y llene los objetos necesarios en un solo ciclo. No necesariamente una venta, puede ser una compra, un grupo con su maestro y alumnos, propongan. Igualmente ustedes propondrán los datos que tendrá cada objeto. Entre mas reutilizable sea mejor.

Si es pequeño el codigo, ponganlo aqui. Si no mandamelo a mi correo marclinux@yahoo.com. No me interesa mucho la consulta, en tu funcion puedes pasar como parametro un objeto del lenguaje que ya esta lleno, un dataset, un resultset o un array. Los campos tampoco son importantes, puede ser uno o dos datos por cada objeto. Lo importante es el ciclo que llena tres o mas objetos.

Tambien es importante que en la matriz que regresa la consulta se tenga un encabezado con mas de un detalle. Si es una venta, mas de un producto, si es un grupo, mas de un alumno

domingo, 31 de marzo de 2013

Inicio del blog de expea

Hola, por fin un mayor espacio para escribir. Es dificil explicar las cosas que me encuentro en internet en espacios tan pequeños como el twitter y el facebook.

Espero poder expresarme en este espacio sobre las cosas que me gustan, como lenguajes de programación, herramientas de desarrollo, metodologías de desarrollo de software y procesos de desarrollo.

Atte.

Ing. Marcos Hernandez