Acerca de:

Este blog contiene los códigos, ejemplos y bases de datos que he usado cuando aprendía acerca de algún tema específico. En lugar de borrarlos (una vez dominado ya el tema), he decidido publicarlos :)

sábado, 19 de diciembre de 2015

Cómo mostrar la fecha completa en un DataGridView cuando es exactamente medianoche

Hice la pregunta originalmente en StackOverflow.

Tengo este DataGridView:


El problema está en la fila seleccionada: en realidad tiene el valor "07/10/2015 12:00:00 am", pero en el DataGridView sólo se muestra "07/10/2015". La siguiente fila tiene el valor de " 07/10/2015 12:00:26 am ". Este problema sólo ocurre cuando los valores DateTime son exactamente medianoche. Cuando paso ese valor al de texto a la izquierda con el siguiente código, el valor DateTime se muestra correctamente (los valores DateTime están en la columna con índice 2):

text1.Text = dgView.SelectedRows[0].Cells[2].Value.ToString();

No quiero cambiar el valor de DefaultCellStyle.Format porque quiero mostrar los valores tipo DateTime en el formato de la configuración regional del sistema operativo (en mi caso es es-pe).

La solución me la dio Jon Skeet. Si se está usando Visual Studio, se debe seleccionar el DataGridView e ir a la ventana Propiedades->DefaultCellStyle e ingresar "G" en "Format":

 
Con esto el DataGridView mostrará las horas exactamente a medianoche y sin cambair la configuración regional.

martes, 3 de noviembre de 2015

Cómo instalar Gnome en Centos 7 Minimal

En mi Centos 7 Minimal (el que no tiene manejador de ventanas), virtualizado con Virtual Box, quise instalar Gnome; pero cuando ingresaba los comandos de yum para descargar e instalar los paquetes, me tiraba que las direcciones de los repositorios estaban mal configuradas y no era capaz de encontrarlas.

Rebuscando en internet hallé la raiz del problema, mi conexión Ethernet no estaba activa. Para activarla se debe ingresar en la terminal:

nmcli & nmtui

lo cual abrirá un menú al mejor estilo DOS donde se podrá activar la conexión Ethernet.

Ya conectado, se puede invocar al instalador de Gnome con este comando:

sudo yum groupinstall "GNOME Desktop"

"sudo" es opcional si ya se está logueado con un usuario con suficientes privilegios.
Con esto, yum descargará los 650 megas de Gnome y los instalará (hay que tenerle un poco de paciencia pues incluye Firefox y LibreOffice).

Luego de descargr los 650 megas de paquetes, yum nos pedirá confirmar un par de veces si se desea incluir una clave con el hash de las descargas, y continuar. Si por error se presiona algo que nos haga salir de la instalación, sólo se debe volver a ingresar el comando yum groupinstall "Gnome Desktop", como los paquetes ya están descargados, esta vez el instalador revisará las dependencias e iniciará la instalación después de pedirnos confirmación.

Para iniciar Gnome (no es necesario reiniciar el sistema) se ingresa:

sudo systemctl start graphical.target

Agradezco el tutorial a nixCraft :D

jueves, 15 de octubre de 2015

Cómo obtener los items seleccionados de un CheckedListBox

Pregunta original en StackOverflow.

Mi respuesta:
En una sola línea de C# Linq:

string[] miList = chkList.CheckedItems.OfType<object>().Select(li => li.ToString()).ToArray();

Devuelve en un array de strings los textos de los items seleccionados.

jueves, 20 de agosto de 2015

Cómo arrancar una aplicación en Java Swing desde C#

Después de probar las respuestas en este enlace, descubrí una detalle importante:

Si no se establece la propiedad WorkingDirectory en el objeto ProcessStartInfo y se quiere arrancar un jar de Swing, éste arrancará, pero con el ícono por defecto de Java y sin imágenes.

El código mínimo para que se ejecute bien una aplicación en Swing con íconos personalizados e imágenes en los jPanels es (en mi caso, los íconos e imágenes están en una subcarpeta en el WorkingDirectory):

ProcessStartInfo psi = new ProcessStartInfo("java.exe", " -jar \"C:\\Program Files\\Installed Shiny Swing jar app\\Myjar.jar\"");
psi.WorkingDirectory = "C:\\Program Files\\Installed Shiny Swing jar app\\"; // Do not miss this line so you awesome Swing app will show default java icon and no images
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
Process p = new Process();
p.StartInfo = psi;
p.Start();


Basado en mi respuesta aquí.

sábado, 18 de julio de 2015

Cómo copiar una lista en Prolog

Por ejemplo, tengo una lista X = [a, b, c] y quiero copiarla a otra variable Y. Para hacerlo en una sola línea de Prolog basta usar la función append de la forma:

append(X, [], Y).

He aquí un pequeño ejemplo en SWI-Prolog:


sábado, 20 de junio de 2015

Calculando el MCD de dos números de forma recursiva en Prolog

El mismo algoritmo de esta entrada, pero esta vez en Prolog!

La lógica de Prolog es la siguiente: devuelve el valor de retorno en la variable del extremo derecho. Si no se declara la tercera variable en este caso, devolverá True pues estará comparando las dos variables de entrada solamente. El signo de exclamación es para detener el backtracking, la coma es el AND lógico, y el punto y coma el OR lógico. Cada declaración de la función "mcd" equivale a un if.


mcd(1, 1, 1):-!. % Func<int, int, int>mcd;
mcd(0, 0, 0):-!.
mcd(X, Y, Z):- X =:= Y, Z is X,!.
mcd(X, Y, Z):- X > Y, X1 is X-Y, mcd(X1, Y, Z1), Z is Z1.
mcd(X, Y, Z):- X < Y, X1 is Y-X, mcd(X1, X, Z1), Z is Z1.


Este código está basado en esta función, que calcula el factorial de un número:

fact(0, 1):-!.
fact(X, Y):- X > 0, X1 is X-1, fact(X1, Y1), Y is X*Y1.


Estoy usando SWI Prolog 7.2.

miércoles, 17 de junio de 2015

Calculando el MCD de dos números de forma recursiva en C#

El algoritmo que estoy usando es bastante simple (nos lo dio un profesor durante una clase):

Se tienen dos números, "x" e "y", si son iguales retornar cualquiera de ellos.
Si x > y, hacer x = x-y;
Si x< y hacer x = y-x; y =x;
repetir hasta que x=y.

Creo que está basado en el algoritmo de Euclides. En lugar de implementarlo como un bucle, creé una función lambda recursiva:

Func<int, int, int> MCD = null;
       
        MCD = (x, y) =>
        {
            if (x == y) return x;
           
            if (x > y) return MCD(x - y, y);
            if (
x < y) return MCD(y - x, x);
           
            return 1;
        };


La forma de llamarla es:

Console.WriteLine(MCD(15,45));

sábado, 18 de abril de 2015

Calculando los números de la serie Fibonacci de forma recursiva en Python 2.7

Una función que calcule los números de Fibonacci es el ejemplo clásico para aprender recursividad:

def fibs(x):
    if x <= 1:
        return x
    return fibs(x - 1) + fibs(x - 2)



Lo malo de esta función es que calcula un número de la serie Fibonacci específico, no calcula toda la serie hasta una cantidad determinada.

La siguiente función sí devuelve la lista de los números de Fibonacci hasta la cantidad de elementos en la lista que se le indique:

def fibList (x, limit):
    if len(x) < 2:
        return fibList([1, 2], limit)

    if len(x) > limit:
        return x

    h = x[-1] + x[-2]
    x.append(h)
    return fibList(x, limit)


La forma de llamarla es:

x = fibList([], 10)

for c in x:
    print(c)



El primer parámetro puede ser una lista vacía o los primeros valores de la serie:

x = fibList([1, 2], 10)

En ambos casos el resultado es:




La lista tiene 11 valores en lugar de 10 debido a que primero inserta el elemento con la función append y después evalúa el tamaño de la lista.

sábado, 11 de abril de 2015

Listar los archivo en una carpeta y sus subcarpetas de forma recursiva

Un día necesité listar los archivos existentes en una carpeta y sus subcarpetas. Como reto, quise implementar mi propia función y aquí está :D

Los algoritmos que recorrer árboles de directorios son recursivos, no se usan bucles debido a que el algoritmo ignora la profundidad que alcanzarán los subdirectorios en el árbol.

import os
from os import listdir
from os.path import isfile, isdir, join

def listdir_recurd(files_list, root, folder, checked_folders):

    if (folder != root):
        checked_folders.append(folder)

    for f in listdir(folder):

        d = join(folder, f)       

        if isdir(d) and d not in checked_folders:
            listdir_recurd(files_list, root, d, checked_folders)
        else:
            if isfile(d):  # si no hago esto, inserta en la lista el nombre de las carpetas ignoradas
                files_list.append(f)

    return files_list



La forma de usar esta función es:

if __name__ == "__main__":
    filez = listdir_recurd([], 'D:\Sample', 'D:\Sample', ['D:\\Sample\\Uno']) # esto omite la subcarpeta 'D:\\Sample\\Uno'

    filez = listdir_recurd([], 'D:\Sample', 'D:\Sample', ['D:\\Sample\\Uno', 'D:\\Sample\\Dos']) # esto omite la subcarpeta 'D:\\Sample\\Uno' y la subcarpeta 'D:\\Sample\\Dos'

    filez_ = listdir_recurd([], 'D:\Sample3', 'D:\Sample3', []) # esto no omite ninguna subcarpeta

La función recibe los siguientes parámetros:

"files_list": es el acumulador. Siempre es una lista vacía.

"root" y "folder": carpeta raíz y carpeta con los archivos que se va a listar, estas dos rutas deben ser la misma. La carpeta con los archivos a listar es la carpeta actual cuyos archivos se están listando, su valor lo controla el algoritmo y va recorriendo las subcarpetas que se van hallando.

"checked_folders": lista las subcarpetas en la carpeta del parámetro "root" que se desean omitir. Si se desea listar todos los archivos, se ingresa una lista vacía.

Python permite ingresar el separador de rutas como \ ó \\.

Esta función sólo ha sido probada en Windows, y ejecutada con Python Tool for Visual Studio usando Python 2.7

lunes, 30 de marzo de 2015

Recorrer todos los controles en un contenedor: .Net y Java Swing

En este ejemplo, se quiere habilitar los controles de un contenedor en función al valor de selección de un checkbox.

En el caso de Java, el contenedor es un jPanel:

En Java 7:

for (Component c : jPanel1.getComponents())
    c.setEnabled(jcheckBox1.isSelected());
   
En Java 8:

Arrays.stream(jPanel1.getComponents()).forEach(c -> c.setEnabled(jcheckBox1.isSelected()));

Si sólo se quiere procesar los controles que sean cajas de texto:

Arrays.stream(jPanel1.getComponents()).forEach(c -> { if (c instanceof JTextField) c.setEnabled(jcheckBox1.isSelected()); } );

En el caso de .Net, el contenedor es un GroupBox:

foreach (Control c in groupBox1.Controls) 
       c.Enabled = checkBox1.Checked;

Usando Linq será:
groupBox1.Controls.Cast<Control>().ToList().ForEach(c => c.Enabled = checkBox1.Checked);

Si sólo se quiere procesar los controles que sean cajas de texto:
groupBox1.Controls.Cast<Control>().ToList().ForEach(c => { if (c is TextBox) c.Enabled = checkBox1.Checked; });

viernes, 6 de marzo de 2015

Cómo separar el nombre de un archivo y la carpeta donde está almacenado (y otras cosillas de la clase Path)


Basta usar el espacio de nombres System.IO y hacer:

string filePath = "C:\\una Carpeta\\un archivo.txt";

Console.WriteLine(Path.GetFileName(filePath));

Console.WriteLine(Path.GetDirectoryName(filePath));


El resultado es:


De forma inversa, si tengo:

string miarchivo = "un archivo.txt";

string miCarpeta = "C:\\mi Carpeta";

Console.WriteLine(Path.Combine(miCarpeta, miarchivo));

El resultado es:



Path.Combine ya añade el caracter de separación entre miarchivo y miCarpeta.

Por otro lado, si se hace:

Console.WriteLine(Path.DirectorySeparatorChar);

Console.WriteLine(Path.PathSeparator);

El resultado será:


Path.DirectorySeparatorChar devuelve el separador de rutas a archivos y carpetas, Path.PathSeparator devuelve el separador de las rutas de las variables de entorno.

viernes, 6 de febrero de 2015

Comparación entre C# Linq y Java 8 streams

El siguiente código en C# declara un array de strings, filtra aquellos que tengan la cadens "am" y le añade tres puntos al final:


using System;
using System.Linq;

class Program
{
     static void Main()
    {
         string[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
         string[] filteredNames = names.Where(c => c.Contains("am")).Select(c => c + "...").ToArray();
         for (int i = 0; i < filteredNames.Length; i++)
               Console.WriteLine(filteredNames[i]);       
   }
}

El siguiente código en Java 8 hace exactamente lo mismo:

import static java.util.Arrays.stream;

public class HelloWorld
{
     public static void main(String []args)
     {
          String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
          String[] filteredNames = stream(names).filter(c -> c.contains("am")).map(c-> c + "...").toArray(String[]::new);
          for (int i = 0; i < filteredNames.length; i++)
                  System.out.println(filteredNames[i]);
     }
}


El código en C# corre sobre Mono v3.10 y a partir del .Net Framework 3.5. El código en Java corre a partir del JDK 1.8.

En comparación con Linq, los streams en Java son un poquitillo más complicados de usar, especialmente por la cantidad de casteos que deben hacerse. La ventaja de Linq es que sus métodos como "Select" y "Where" recuerdan a los de SQL. La ventana de los streams de Java es que sus métodos como "map" y "filter" recuerdan a los de Python.

miércoles, 7 de enero de 2015

Código para borrar todos los archivos de una carpeta en Python

El siguiente script recibe como parámetro la carpeta a la que se le quieren eliminar los archivos:

import sys
import os
from os import listdir
from os.path import isfile, join

def delete_Files(folder):
      files_dump = [join(folder, c) for c in listdir(folder)]
      files_dump = filter(lambda c: isfile(c), files_dump)
      [os.remove(c) for c in files_dump]

if __name__ == "__main__":
# sys.argv[0] contiene el nombre del script
# sys.argv[1] contiene el primer parámetro: 
# la carpeta que se desea vaciar
      delete_Files(sys.argv[1])
      print 'Files Deleted!!'


Lo he probado con Python 2.7.8 desde Python Tools for Visual Studio 2013. Se debe tener cuidado porque los archivos son eliminados de forma definitiva, no van a la papelera de reciclaje.

La funcion __name__ puede modificarse para que elimine los archivos de todas las carpetas que se le pasen como argumentos, y sólo en caso de que éstas existan:

if __name__ == "__main__":
      [delete_Files(c) for c in sys.argv[1:] if os.path.exists(c)]
      print 'Files Deleted!!'


Para ingresar los argumentos del script en Visual Studio, se debe ir a Proyecto->Propiedades: