Datos personales

Mostrando entradas con la etiqueta Visual Studio 2008. Mostrar todas las entradas
Mostrando entradas con la etiqueta Visual Studio 2008. Mostrar todas las entradas

sábado, julio 10, 2010

Algoritmo C# para dendrograma VI (Datos)

Los datos para hacer pruebas los he sacado de un repositorio público de datos de la UCI: http://archive.ics.uci.edu/ml/ por mediación de la UOC: http://www.uoc.edu para hacer la práctica.

Descripción de los datos:
Title: Acute Inflammations

Abstract: The data was created by a medical expert as a data set to test
the expert system, which will perform the presumptive diagnosis of two
diseases of the urinary system.

----------------------------------------------------------------------------

Data Set Characteristics: Multivariate
Attribute Characteristics: Categorical, Integer
Associated Tasks: Classification
Number of Instances: 120
Number of Attributes: 6
Missing Values? No
Area: Life
Date Donated: 2009-02-11

----------------------------------------------------------------------------

Source:

Jacek Czerniak, Ph.D., Assistant Professor
Systems Research Institute
Polish Academy of Sciences
Laboratory of Intelligent Systems
ul. Newelska 6, Room 218
01-447 Warszawa, Poland
e-mail: jacek.czerniak 'at' ibspan.waw.pl or jczerniak 'at' ukw.edu.pl

----------------------------------------------------------------------------


Data Set Information:

The main idea of this data set is to prepare the algorithm of the expert
system, which will perform the presumptive diagnosis of two diseases of
urinary system. It will be the example of diagnosing of the acute
inflammations of urinary bladder and acute nephritises. For better
understanding of the problem let us consider definitions of both
diseases given by medics. Acute inflammation of urinary bladder is
characterised by sudden occurrence of pains in the abdomen region and
the urination in form of constant urine pushing, micturition pains and
sometimes lack of urine keeping. Temperature of the body is rising,
however most often not above 38C. The excreted urine is turbid and
sometimes bloody. At proper treatment, symptoms decay usually within
several days. However, there is inclination to returns. At persons with
acute inflammation of urinary bladder, we should expect that the illness
will turn into protracted form.

Acute nephritis of renal pelvis origin occurs considerably more often at
women than at men. It begins with sudden fever, which reaches, and
sometimes exceeds 40C. The fever is accompanied by shivers and one- or
both-side lumbar pains, which are sometimes very strong. Symptoms of
acute inflammation of urinary bladder appear very often. Quite not
infrequently there are nausea and vomiting and spread pains of whole
abdomen.

The data was created by a medical expert as a data set to test the
expert system, which will perform the presumptive diagnosis of two
diseases of urinary system. The basis for rules detection was Rough Sets
Theory. Each instance represents an potential patient.

The data is in an ASCII file. Attributes are separated by TAB. Each line
of the data file starts with a digit which tells the temperature of patient.

-- Attribute lines:
For example, '35,9 no no yes yes yes yes no'
Where:
'35,9' Temperature of patient
'no' Occurrence of nausea
'no' Lumbar pain
'yes' Urine pushing (continuous need for urination)
'yes' Micturition pains
'yes' Burning of urethra, itch, swelling of urethra outlet
'yes' decision: Inflammation of urinary bladder
'no' decision: Nephritis of renal pelvis origin

----------------------------------------------------------------------------

Attribute Information:

a1 Temperature of patient { 35C-42C }
a2 Occurrence of nausea { yes, no }
a3 Lumbar pain { yes, no }
a4 Urine pushing (continuous need for urination) { yes, no }
a5 Micturition pains { yes, no }
a6 Burning of urethra, itch, swelling of urethra outlet { yes, no }
d1 decision: Inflammation of urinary bladder { yes, no }
d2 decision: Nephritis of renal pelvis origin { yes, no }

----------------------------------------------------------------------------

Relevant Papers:

J.Czerniak, H.Zarzycki, Application of rough sets in the presumptive
diagnosis of urinary system diseases, Artifical Inteligence and Security
in Computing Systems, ACS'2002 9th International Conference Proceedings,
Kluwer Academic Publishers,2003, pp. 41-51

----------------------------------------------------------------------------

Citation Request:

Please cite:

J.Czerniak, H.Zarzycki, Application of rough sets in the presumptive
diagnosis of urinary system diseases, Artifical Inteligence and Security
in Computing Systems, ACS'2002 9th International Conference Proceedings,
Kluwer Academic Publishers,2003, pp. 41-51

Algoritmo C# para dendrograma V

El algoritmo por fin:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PR_IA2_2010_Clases
{
static public class Algoritmos
{
///
/// Algoritmo para el cálculo de la distancia Euclidea entre los
/// objetos a partir de los distintos atributos.
///

/// Lista de arrays de strings que representan
/// los atributos de los objetos
/// Una matriz en el intervalo [0,1] de las
/// distancias euclideas entre los objetos

static public double[,] distanciaEuclidea(List datos)
{
try
{
double[,] matriz = null;
//creamos la matriz de distancias en el intervalo [0,1]
//con la distancia media según el nº de atributos (6):
if (datos.Count>0)
{
matriz = new double[datos.Count, datos.Count];
for (int i = 0; i < datos.Count; i++)
{
for (int j= 0; j < datos.Count ; j++)
{
double suma = 0;
for (int k = 0; k < datos[i].Count() - 2; k++)
{
suma+=Math.Pow(double.Parse(datos[i][k])-double.Parse(datos[j][k]),2);
}
double result = Math.Sqrt(suma);
matriz[i, j] = 1-(result/6);
}
}
}
return matriz;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return null;
}
///
/// Algoritmo que calcula la matriz de semejanzas transitiva a partir
/// de una no transitiva.
///

/// Matriz de semejanzas no transitiva
/// Matriz de semejanzas transitiva
static public double[,] clausuraTransitiva(double[,] S)
{
try
{
double[,] R;
do
{
R = (double[,])S.Clone();
S = composicion(R, (double[,])R.Clone());
}while (!iguales(S,R));
return S;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return null;
}
///
/// composición de las semejanzas de una clausura transitiva
///

/// matriz de semejanzas
/// matriz de semejanzas
/// Una matriz de semejanzas
static private double[,] composicion(double[,] R1, double[,] R2)
{
try
{
double[,] S=new double[R1.GetLength(0),R1.GetLength(0)];
for (int x = 0; x < R1.GetLength(0); x++)
{
for (int y = 0; y < R1.GetLength(0); y++)
{
S[x,y] = 0;
for (int z = 0; z < R1.GetLength(0); z++)
{
S[x, y] = Math.Max(S[x,y], Math.Min(R1[x,z],R2[z,y]));
}
}
}
return S;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return null;
}
///
/// Determina si 2 matrices son iguales
///

///
///
///
static private bool iguales(Double[,] S, Double[,] R)
{
try
{
for (int i = 0; i < S.GetLength(0); i++)
{
for (int j = 0; j < S.GetLength(1); j++)
{
if (S[i, j] != R[i, j])
return false;
}
}
}
catch (Exception ex)
{
return false;
}
return true;
}
///
/// Crea un dendrograma a partir de una matriz de semejanzas
/// transitiva.
///

/// matriz de datos
/// Una cadena con el dendrograma
static public string dendrograma(double[,] matriz)
{
try
{
string result="";
List alfa = new List();
List emparejamientos = new List();
//añade los datos alfa de la matriz (resultados).
for (int i = 0; i < matriz.GetLength(0); i++)
{
for (int j = i; j < matriz.GetLength(1); j++)
{
if (!alfa.Contains(matriz[i,j]))
{
alfa.Add(matriz[i, j]);
}
}
}
//ordenamos los datos alfa para ver
//los objetos relacionados.
alfa.Sort();
//recorremos toda la matriz.
for (int x=alfa.Count-1;x>=0;x--)
{
for (int i = 0; i < matriz.GetLength(0); i++)
{
for (int j = i+1; j < matriz.GetLength(1); j++)
{
//Si coincide el valor de la semejanza con
//el valor alfa que estamos tratando,
//añadimos la relación a la cadena final.
if (alfa[x] == matriz[i, j])
{
string strI = "x"+ (i+1).ToString()+" ";
string strJ = "x"+ (j+1).ToString()+" ";
bool existeI = result.Contains(strI);
bool existeJ = result.Contains(strJ);
//sólo añadimos el emparejamiento si
//no existe una relación de emparejamiento
//anterior directa o derivada de otra relación
//de emparejamiento
if (!emparejamientos.Contains(strI + "," + strJ) &&
!emparejamientos.Contains(strJ+","+strI))
{
//se trabaja con 4 supuestos a continuación
//al tratar la relación entre 2 objetos:
if (!existeI && existeJ)
{
emparejamientos = anyadirEmparejamientos(emparejamientos, strI, strJ,
result.Substring(buscarLLaveAbrir(emparejamientos, result, strJ)));
if (result.IndexOf("{" + strJ) > -1)
{
result = result.Replace("{" + strJ, "{{" + strJ);
result += "," + strI + "}";
}
if (result.IndexOf(strJ + "}") > -1)
{
result = result.Insert(buscarLLaveAbrir(emparejamientos,result, strI), "{");
result += "," + strI + "}";
}
}
if (existeI && !existeJ)
{

emparejamientos = anyadirEmparejamientos(emparejamientos, strJ, strI,
result.Substring(buscarLLaveAbrir(emparejamientos,result, strI)));
result = result.Insert(buscarLLaveAbrir(emparejamientos,result, strI), "{");
result += "," + strJ + "}";
}
if (existeI && existeJ)
{
if (result.IndexOf(strI) > result.IndexOf(strJ))
{
emparejamientos = anyadirEmparejamientos(emparejamientos, strI, strJ,
result.Substring(buscarLLaveAbrir(emparejamientos, result, strJ)));
result = result.Insert(buscarLLaveAbrir(emparejamientos, result, strJ), "{");
result = result.Insert(buscarLLaveCerrar(emparejamientos, result, strJ), "}");
result = result.Insert(buscarLLaveAbriryCierreParaComa(emparejamientos, result, strJ) + 1, ",");
}
else
{
emparejamientos = anyadirEmparejamientos(emparejamientos, strI, strJ,
result.Substring(buscarLLaveAbrir(emparejamientos,result, strI)));
result = result.Insert(buscarLLaveAbrir(emparejamientos, result, strI), "{");
result = result.Insert(buscarLLaveCerrar(emparejamientos, result, strI), "}");
result = result.Insert(buscarLLaveAbriryCierreParaComa(emparejamientos, result, strI) + 1, ",");
}
}
if (!existeI && !existeJ)
{
emparejamientos.Add(strI + "," + strJ);
result += ("{" + strI + "," + strJ + "}");
}
}
}
}
}
}
return result.Replace(" ","");
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return "";
}
///
/// Crea una lista de emparejamientos para no duplicar
/// los emparejamientos en el dendrograma final.
///

/// Lista de emparejamientos
/// nuevo objeto
/// objeto existente
/// cadena que engloba los objetos que se emparejan
/// con todos los objetos que se relacionan con ellos
/// Devuelve la lista de emparejamientos
static private List anyadirEmparejamientos(List emparejamientos,string nuevo, string J,
string trozo)
{
try
{
char[] caracteresDelimitadores = { '{','}',',' };
string[] filas;
filas = trozo.Split(caracteresDelimitadores, StringSplitOptions.RemoveEmptyEntries);
//mediante una array añado todos los objetos relacionados
//a lista de emparejamientos.
for (int i = 0; i < filas.Count(); i++)
{
if (!emparejamientos.Contains(nuevo+','+filas[i])
&& nuevo!=filas[i])
{
emparejamientos.Add(nuevo + ',' + filas[i]);
}
for (int j = 0; j < filas.Count(); j++)
{
if (!emparejamientos.Contains(filas[i] + ',' + filas[j])
&& !emparejamientos.Contains(filas[j] + ',' + filas[i]) &&
filas[i]!=filas[j])
{
emparejamientos.Add(filas[i] + ',' + filas[j]);
}
}
}
return emparejamientos;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return null;
}
///
/// Busca la llave de abrir para hacer un emparejamiento
///

/// Lista de emparejamientos
/// dendrograma final
/// Objeto a buscar
/// La posición de la primera llave para el
/// emparejamiento

static private int buscarLLaveAbrir(List emparejamientos,string result, string I)
{
try
{
int min = result.Length;
var lista= from e in emparejamientos
where e.IndexOf(I)>-1
select e;
//dentro de todos los emparejamientos de un objeto, obten-
//dremos el que esté en el lado más izquierdo del dendrograma
foreach (string str in lista)
{
if (result.IndexOf(str.Substring(0, str.IndexOf(","))) < min &&
result.IndexOf(str.Substring(0, str.IndexOf(","))) > -1)
min = result.IndexOf(str.Substring(0, str.IndexOf(",")));
if (result.IndexOf(str.Substring(str.IndexOf(","))) < min &&
result.IndexOf(str.Substring(str.IndexOf(","))) > -1)
min = result.IndexOf(str.Substring(str.IndexOf(","))) - str.Substring(0, str.IndexOf(",")).Length;
}
return min;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return 0;
}
///
/// Busca la llave de cerrar para hacer un emparejamiento
///

/// Lista de emparejamientos
/// dendrograma final
/// Objeto a buscar
/// La posición de la última llave para el
/// emparejamiento

static private int buscarLLaveCerrar(List emparejamientos, string result, string I)
{
try
{
int max =0;
var lista = from e in emparejamientos
where e.IndexOf(I) > -1
select e;
//dentro de todos los emparejamientos de un objeto, obten-
//dremos el que esté en el lado más derecho del dendrograma
foreach (string str in lista)
{
if (result.IndexOf(str.Substring(0,str.IndexOf(","))) > max)
max = result.IndexOf(str.Substring(0, str.IndexOf(","))) + str.Substring(0, str.IndexOf(",")).Length;
if (result.IndexOf(str.Substring(str.IndexOf(",")+1)) > max)
max = result.IndexOf(str.Substring(str.IndexOf(",") + 1)) + str.Substring(0, str.IndexOf(",")).Length;
}
return max;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return 0;
}
///
/// Dentro de cada emparejamiento, busca la posición intermedia de la
/// relación para insertar la coma de separación que deja el dendrograma
/// más claro de entender.
///

/// Lista de emparejamientos
/// dendrograma final
/// Objeto a buscar
/// La posición intermedia del emparejamiento
static private int buscarLLaveAbriryCierreParaComa(List emparejamientos, string result, string I)
{
try
{
int min = buscarLLaveAbrir(emparejamientos,result,I);
int numLlaveAbrir=1;
for (int i = min; i >= 0; i--)
{
if (result.Substring(i, 1) == "{")
numLlaveAbrir++;
else
break;
}
for (int i = min; i < result.Length; i++)
{
if (result.Substring(i, 1) == "}")
numLlaveAbrir--;
if (numLlaveAbrir == 0)
return i;
}
return min;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return 0;
}
}
}

Algoritmo C# para dendrograma IV

La parte Datos.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PR_IA2_2010_Clases
{
static public class Datos
{
///
/// Normalizamos los datos aplicando ranging a la primera
/// columna y un valor binario a las posteriores.
///

///
/// Una lista normalizada de arrays de strings
static public List Normalizar(List datos)
{
try
{
//normalizamos los datos:
if (datos != null && datos.Count > 0)
{
//sumamos la primera fila para aplicar ranging.
float maximo = float.MinValue;
float minimo = float.MaxValue;
for (int i = 0; i < datos.Count; i++)
{
float result;
if (float.TryParse(datos[i][0].Replace('.', ','), out result))
{
if (result < minimo)
minimo = result;
if (result > maximo)
maximo = result;
}
}
foreach (string[] fila in datos)
{
//ranging a la primera columna:
float result;
if (float.TryParse(fila[0].Replace('.', ','), out result))
{
fila[0] = ((result - minimo) / (maximo - minimo)).ToString();
}
for (int i = 1; i < fila.Count(); i++)
{
//comprobamos si hay valores binarios
if (fila[i].ToUpper() == "YES" || fila[i].ToUpper() == "SÍ")
{
fila[i] = "1";
}
if (fila[i].ToUpper() == "NO")
{
fila[i] = "0";
}
}
}
}
return datos;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return null;
}
}
}

Algoritmo C# para dendrograma III

Aquí la parte de código de IO.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PR_IA2_2010_Clases
{
static public class IO
{
///
/// Lectura de los datos de un fichero dado de tipo CVS que
/// transforma en una lista de arrays de tipo string.
///

/// fichero
/// Devuelve una lista de arrays de tipo string
static public List leerDatos(string fichero)
{
string texto;
string[] filas;
List datos=null;
try
{
System.IO.StreamReader sr =
new System.IO.StreamReader(fichero, System.Text.Encoding.Default, true);
texto = sr.ReadToEnd();
string[] caracteresDelimitadores = {"\r\n"};
//Creamos un lista de arrys de una forma rápida para
//tener cada dato por separado para su posterior tratamiento.
filas=texto.Split(caracteresDelimitadores,StringSplitOptions.RemoveEmptyEntries);
if (filas.Count()>0)
{
datos=new List();
for (int i = 0;i< filas.Count(); i++)
{
datos.Add(filas[i].Split(','));
}
}
sr.Close();
return datos;
}
catch (System.IO.IOException ex)
{
throw new Exception(ex.Message);
}
catch (System.Exception ex)
{
throw new Exception(ex.Message);
}
return null;
}
}
}

jueves, junio 24, 2010

Algoritmo C# para dendrograma II

//El código del proceso principal para testear los algoritmos:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using PR_IA2_2010_Clases;

namespace PR_IA2_2010
{
class Program
{
static void Main(string[] args)
{
List datos;
if (args.Count() == 0)
{
//sin parámetros
Console.WriteLine("Por defecto se analiza diagnosis3.csv");
Console.WriteLine("Si quiere otro fichero debe escribir:");
Console.WriteLine("PR_IA2_2010.EXE nombre_fichero_con_datos");
datos =
IO.leerDatos("diagnosis3.csv");
}
else
{
//Si ponemos un parémetro es el nombre del fichero.
datos =
IO.leerDatos(args[0]);
}
DateTime tiempoInicio = DateTime.Now;
//normalizamos:
datos = Datos.Normalizar(datos);
//calculamos la media de las distancia euclidea entre
//los objetos
double[,] R = Algoritmos.distanciaEuclidea(datos);
//Calculamos la semejanza entre ellos
double[,] semejanza = Algoritmos.clausuraTransitiva(R);
Console.WriteLine("El resultado es: ");
//creamos el dendrograma con el resultado obtenido.
Console.WriteLine(Algoritmos.dendrograma(semejanza));
Console.WriteLine("Tiempo= " + DateTime.Now.Subtract(tiempoInicio));
Console.ReadKey();
}
}
}

jueves, junio 17, 2010

Algoritmo C# para dendrograma I

He creado un algoritmo para el cálculo de dendrogramas según el método de clausura transitiva para la asignatura de Inteligencia Artificial II de la carrera de Ingeniería Informática en el Universitat Oberta de Catalunya. Como no me gusta quedármelo para mí solo y supongo que los profes no se mosquearán, aquí os escribo una serie de artículos dónde expongo una breve explicación: artículo I y los fuentes: artículos siguientes.

Tanto el algoritmo como el programa de prueba lo he realizado con C# y Framework 3.5 con el entorno de desarrollo Visual Studio 2008.

Para realizar el algoritmo y probarlo he creado 2 proyectos diferentes englobados en una solución que me permite probar , ejecutar y modificar el código.

Los proyectos son:
• PR_IA2_2010
Proyecto de inicio que usa la librería PR_IA2_2010_Clases para el cálculo del problema propuesto. Este proyecto presenta el resultado final:
o Program.cs: es el módulo principal donde se encuentra Main. Desde este módulo se llaman a los distintos algoritmos para la resolución del problema.

• y PR_IA2_2010_Clases
Conjunto de clases dónde se encuentran los algoritmos desarrollados para la resolución del problema. He creados 3 partes distintas entre sí para que la lectura del código se más clara.
o IO.cs: Tiene los métodos de lectura de los datos.
static public List leerDatos(string fichero)
Lectura de los datos de un fichero dado de tipo CVS que transforma los atributos de los objetos en una lista de arrays de tipo string
o Datos.cs: Tiene los métodos de transformación de los datos (normalización)
static public List Normalizar(List datos)
Normalización de lso datos aplicando ranging a la primera columna y un valor binario a los posteriores atributos.
o Algoritmos.cs: Algoritmos de la aplicación.
static public double[,] distanciaEuclidea(List datos)
Algoritmo para el cálculo de la distancia Euclidea entre los objetos a partir de los distintos atributos.
static public double[,] clausuraTransitiva(double[,] S)
Algoritmo que calcula la matriz de semejanzas transitiva a partir de una matriz no transitiva.
static private double[,] composicion(double[,] R1, double[,] R2)
Composición de las semejanzas de una clausura transitiva.
static private bool iguales(Double[,] S, Double[,] R)
Determina si 2 matrices de semejanzas son iguales.
static public string dendrograma(double[,] matriz)
Crea un dendrograma a partir de una matriz de semejanzas transitiva.
static private List anyadirEmparejamientos(List emparejamientos,string nuevo, string J, string trozo)
Crea una lista de emparejamientos para no duplicar los emparejamientos en el dendrograma final.
static private int buscarLLaveAbrir(List emparejamientos,string result, string I)
Busca la llave de abrir para hacer un emparejamiento.
static private int buscarLLaveCerrar(List emparejamientos, string result, string I)
Busca la llave de cerrar para hacer un emparejamiento
static private int buscarLLaveAbriryCierreParaComa(List emparejamientos, string result, string I)
Dentro de cada emparejamiento, busca la posición intermedia de la relación para insertar la coma de separación que deja el dendrograma más claro de entender.

En el próximo artículo empezaré a mostrar el código.

jueves, diciembre 03, 2009

Oferta empleo Programador Junior

Hola a todos, se oferta un puesto de trabajo “programador junior?” con las siguientes características.

-Necesitamos una persona dinámica, con ganas de aprender y en continúo reciclaje y que considere que pueda con las siguientes tareas a desarrollar en el dpto. de programación:
-Asistencia telefónica con el cliente en 2ª línea. (la primera es al que recibe la llamada y si no sabe resolverla la pasa a la 2ª).
-Mantenimiento de aplicaciones VB6, SQL Server 2000/2005, C#, VB9, Visual Studio 2008, Framework 3.5 (normalmente la llamada es por algún error de programación que hay que detectar, debido a las continuas modificaciones en las aplicaciones, ahora se contabilizan unas 8 llamadas diarias por personas e incluso menos)
-Posibilidad de viajar al menos una vez al mes (es raro que se viaje, pero existe la posibilidad de testear nuevas aplicaciones, arreglar errores in situ, etc..)
-Cómo requisito imprescindible es coche propio con carnet de conducir, residencia en la provincia de Alicante, que sea organizada y al menos que tenga el título de DAI, esté cursando o similar.

Si queréis más información podéis mandarme un mail.

Un saludo a todos.

miércoles, septiembre 23, 2009

Menú con lista de ventanas

Algo que parece tan complicado a simple vista como es la de gestionar un menú de formularios hijos abiertos (MDI-MDIChild), se convierte en una tarea fácil con nuestro querido .NET framework, pero ojo, no publico este post porque sea algo tan sencillo, no!!!, lo publico porque he encontrado una notable diferencia entre .NET framework 2.0 y .NET framework 3.5 que puede liar la madeja durante un buen rato (por cierto que buena está la madeja de cordero).

Ahora al grano, para Framework 2.0 tenemos que añadir un menú del cuadro de herramientas llamado MainMenu (obsoleto) y añadir sus correspondientes MenuItems, en el que uno de ellos sería por ejemplo "Ventanas", y al que tenemos que poner la propiedad MDIList a true.

Para Framework 3.5 la cosa ha cambiado, ya no tenemos el menú MainMenu, y como habréis podido leer en el link que os he puesto en MainMenu, Microsoft nos aconseja que usemos MenuStrip en vez de MainMenu. Y ahora ya nos podríamos volver locos buscando lo de MDIList porque aquí esa propiedad no existe. En este control lo que nos han puesto es una propiedad llamada MdiWindowsListItem que nos permite seleccionar un ToolStripMenuItem que hayamos creado en el Menú ToolStrip.

Y con esto nada más por ahora, y que malo es no saber, porque he perdido un poquillo de tiempo por esta chorrada, casi me creo yo mismo el gestor del menú de ventanas y eso no me sale rentable.

Un saludo
Oscar Montesinos

martes, julio 21, 2009

Proyecto e-Dni

Os dejo el link con los screenshots del proyecto e-DNI que estoy a punto de terminar. Ya está en fase de pruebas:

http://www.facebook.com/photo.php?pid=30324446&l=2fb71f0f08&id=1592291277

El proyecto está hecho en C#, Framework 3.5 contra una bd en SQL Server compatible con 2000.

Un saludo
Oscar Montesinos.

martes, enero 06, 2009

Lector RSS en C# 3.5 y LINQ

(Este artículo tiene otro punto de vista en este otro que creo mejora este sistema: http://oscarmontesinos.blogspot.com/2009/08/lector-rss-con-framework-35-sin-linq.html)

Retomando mi actividad normal diaria, me he encontrado con una clase para leer RSS que tenía por ahí guardada y que he retocado para usar LINQ.

Primero he creado una clase con los atributos que necesito y a la que he llamado Articulo:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class Articulo
{
public DateTime Fecha;
public string Titulo;
public string Contenido;
public string Enlace;
public Articulo()
{
}
public Articulo(DateTime pFecha, string pTitulo, string pContenido, string pEnlace)
{
Fecha = pFecha;
Titulo = pTitulo;
Contenido = pContenido;
Enlace = pEnlace;
}
}

Luego he creado una clase para leer las RSS y que consta de 2 métodos:
  • uno público que es el punto de entrada y dónde le pasamos una lista de cadenas que representa cada una de ellas una dirección de subscripción a una RSS
  • uno privado que es el que se encarga de ir leyendo cada servidor de noticias.
Aquí el código:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Xml;
using System.Xml.Linq;
using JPA.XML.Clases.Entidades;

public class LectorRSS
{
public List CargarRSS(List feeds)
{
//Ejemplos de links
//List feeds = new List
//{
// "http://noticiasjpa.blogspot.com/feeds/posts/default",
// "http://dnnotaword.blogspot.com/feeds/posts/default",
//};
List articulos = new List();
foreach (String sFeed in feeds)
{
leerRSS(articulos,sFeed);
}
return articulos;
}
private void leerRSS(List articulos, string sFeed)
{
try
{
//cargamos el XML a leer.
var feed = XDocument.Load(sFeed);
//la consulta en LINQ:
var result = from c in feed.Root.Elements()
where c.Name.LocalName == "entry" //Selecciono sólo las entradas
select new Articulo //por cada entrada creo un objeto Artículo.
{
Fecha = c.Elements().Where(Fecha => Fecha.Name.LocalName == "published").
Select(Fecha => DateTime.Parse(Fecha.Value)).First(),
Titulo = c.Elements().Where(Titulo => Titulo.Name.LocalName == "title").
Select(Titulo => Titulo.Value).First(),
Contenido = c.Elements().Where(Contenido =>Contenido.Name.LocalName == "content").
Select(Contenido => Contenido.Value).First(),
Enlace = c.Elements().Where(Enlace => Enlace.Name.LocalName=="link").
Select(Contenido => Contenido.Attribute("href").Value).Last()
};
articulos.AddRange(result);
//A continuación tenéis el código sustituído:
//foreach (XElement xElement in ListaArticulos)
//{
// if (xElement.Name.LocalName == "entry")
// {
// Articulo articulo = new Articulo();
// foreach (XElement xElement2 in xElement.Elements())
// {
// switch (xElement2.Name.LocalName)
// {
// case "title":
// articulo.Titulo = xElement2.Value;
// break;
// case "content":
// articulo.Contenido = xElement2.Value;
// break;
// case "published":
// articulo.Fecha = DateTime.Parse(xElement2.Value);
// break;
// case "link":
// foreach (XAttribute xAttribute in xElement2.Attributes())
// {
// if (xAttribute.Name == "href")
// {
// articulo.Enlace = xAttribute.Value;
// }
// }
// break;
// }
// }
// if (articulo.Contenido.Trim() != "")
// {
// articulos.Add(articulo);
// }
// }
//}
}
catch (Exception ex)
{
throw new Excepciones.LectorRSS(ex.Message);
}
}
}

lunes, octubre 20, 2008

Fotos Guille Comunity Tour

Os dejo las fotos que nos hicimos en la comida, previa charla del Guille en la Universidad de Murcia para el grupo de usuarios GUSENET dentro de la gira del Guille Comunity Tour 2008 (GTC 2008):

Guille Comunity Tour (GCT 2008)

jueves, octubre 16, 2008

Guille Comunity Tour (GCT 2008)

Mañana Viernes, 17 de Octubre, el grupo de usuarios GUSENET tenemos un gran evento preparado:el Guille dará una charla sobre las novedades de VB9 y sobre LINQ. La charla será en la Universidad de Murcia en la nueva Facultad de Informática a las 16:30.

El link del registro de Microsoft events dice que la sala está llena, pero no os preocupéis, en principio si hiciera falta un salón más grande supongo que no tendríamos problemas en conseguirlo y la re-ubicación sería andar unos pocos pasos más.

Si queréis estar informados sobre el tema podéis enviar un mail que os contestaré inmediatamente con lo que sepa.

viernes, septiembre 26, 2008

Serializar PrinterSettings

Siempre que he creado un aplicación me he encontrado con el mismo problema: ¿cómo me guardo los datos de la impresora activa o la impresora por la cual el cliente quiere imprimir, para no tener que pedírselo cada vez que imprimo?

La respuesta es: serializando el objeto printerSettings. Pero ojo, la serialización del objeto printerSettings sólo funciona con Framework 2.0 o superior, aunque no os podría asegurar si en el extraño 3.0 funcionará ya que creo que no es el mismo que del 3.5. Nosotros vamos a hablar de la clase System.Drawing.Printing.PrinterSettings que nos permiten serializar.

Para serializar las características de una impresora tenemos que hacer lo siguiente:

XmlSerializer serializer = new
XmlSerializer(typeof(System.Drawing.Printing.PrinterSettings));
System.IO.TextWriter writer = new System.IO.StringWriter();
//fineprint PDF no deja serializar los datos de impresión, capturamos el error
//para no serializarlo y guardar sólo el nombre o la propiedad que queramos:
try
{
serializer.Serialize(writer, Impresora);
}
catch (Exception ex)
{
writer.Close();
writer = new System.IO.StringWriter();
writer.WriteLine("");
writer.WriteLine(""+Impresora.PrinterName+"");
writer.WriteLine("
");
}
//En writer tenemos serializada la impresora en XML.
Console.WriteLine(writer.ToString());
writer.Close();

Pues ya está serializada y podemos hacer con ella lo que queramos, como por ejemplo guardarlo en una bd o en un fichero de configuración, etc.

Para deserializarla tendremos que hacer este proceso:
XmlSerializer serializer =
new XmlSerializer(typeof(System.Drawing.Printing.PrinterSettings));
System.IO.TextReader sImpresora =
new System.IO.StringReader(MiCadenaXMLGuardada);
System.Drawing.Printing.PrinterSettings printer=
((System.Drawing.Printing.PrinterSettings)serializer.Deserialize(sImpresoa);

Y voilá, con esto os evitaréis tener que crear vuestra propia clase de impresora.

sábado, septiembre 06, 2008

YIELD C#

En esta entrada vamos a ver un ejemplo de la nueva instrucción YIELD para C# 3.0 que podemos encontrar en Visual Studio 2008.

Como muchas de las nuevas características de C#, parece que todas estas vienen derivadas de las necesidades de nuevas instrucciones para LINQ, pero eso es harina de otro costal, ya sabrán los de Microsoft porqué está, yo sólo pretendo mostrar una utilidad de la misma.

Podemos comparar esta instrucción con la que nos encontramos en INFORMIX de RETURN x WITH RESUME; para procedimientos almacenados, ya que su función es parecida. Esta función nos devuelve un valor encubierto en un IEnumerable tantas veces como encuentre YIELD dentro de una iteración o bucle que a su vez se encuentre en una función.

Esto así, cuesta un poco de digerir si no se acompaña con un pequeño ejemplo:

El ejemplo mostrará de una lista de clientes, los clientes que superan la media de ventas del total de clientes. Este mismo ejemplo se puede hacer con LINQ, pero como lo que se pretende mostrar es YIELD pues omito cualquier alusión a LINQ.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EjemploYield
{
class Program
{
protected class Cliente
{
public int Codigo { get; set; }
public string Nombre { get; set; }
public double Ventas { get; set; }
public Cliente (int Codigo, string Nombre, double Ventas)
{
this.Codigo=Codigo;
this.Nombre=Nombre;
this.Ventas=Ventas;
}
}
static void Main(string[] args)
{
List clientes = new List {
new Cliente(1,"Pepe",100),
new Cliente(2,"Juan",12),
new Cliente(3,"Alfonso", 23),
new Cliente(4,"Pedro", 37),
new Cliente(5,"Martin",0),
new Cliente(6,"Antonio", 45)};
foreach (Cliente cli in ClientesSuperiorAMedia(clientes))
{
Console.WriteLine(cli.Nombre);
}
Console.ReadKey();
}
static IEnumerable ClientesSuperiorAMedia(List clientes)
{
double media = Media(clientes);
for (int i=0;i {
if (clientes[i].Ventas>=media)
{
yield return clientes[i];
}
}
}
static double Media(List clientes)
{
double suma = 0;
foreach (Cliente cli in clientes)
{
suma+=cli.Ventas;
}
return suma/clientes.Count;
}
}
}

domingo, junio 22, 2008

Truco CheckedListBox

Ayer se me planteó un problema de fácil y extraña solución. Necesitaba un CheckedListBox y lo tenía que llenar con los datos leídos de una tabla, así que me puse manos a la obra y voilà, el Intellisense de Visual Studio 2008 no me muestra ningún binding ni ningún DataSource, por lo que me puse a buscar en la red y encontré esto:

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=474442&SiteID=1

En resumen, aunque el intellisense no nos muestre algunas propiedades, podemos estar tranquilos, puede que existan si el control tiene como padre otro control como es en este caso el ListBox y que podemos poner sin problemas:

myCheckedListBox.DataSource=myDataSource;
myCheckedListBox.DisplayMember="Name";
myCheckedListBox.ValueMember="Code";

Os aconsejo que reviséis la documentación del control en la MSDN antes de utilizarlo:
http://msdn.microsoft.com/en-us/library/system.windows.forms.checkedlistbox_members.aspx

aunque no siempre sea correcto, ya que si buscáis en este link que también es de MSDN podéis ver que dice:
"Nota No es posible enlazar datos a CheckedListBox. Utilice ComboBox o ListBox en su lugar para esto. Para obtener más información, vea Cómo: Enlazar un control ComboBox o ListBox de formularios Windows Forms a datos."

¿Curioso no?

lunes, agosto 14, 2006

De tabla a TreeView en ASP NET 2.0 (versión 2)

Creamos la tabla donde tenemos la relación padre a hijo infinito para n nodos y con padres sin hijos:

CREATE TABLE [dbo].[Tabla](
[codigo] [int] IDENTITY(1,1) NOT NULL,
[nombre] [varchar](50) NOT NULL,
[padre] [int] NULL
) ON [PRIMARY]

GO

la rellenamos con datos:
INSERT Tabla (nombre)
VALUES('Luis')--sin padre
INSERT Tabla (nombre,padre)
VALUES('Pedro',1)
INSERT Tabla (nombre)
VALUES('Alfonso')
INSERT Tabla (nombre)
VALUES('Jose')
INSERT Tabla (nombre,padre)
VALUES('Fidel', 4)
INSERT Tabla (nombre,padre)
VALUES('Pepe', 2)


dentro de la etiqueta script de un formulario o página ASP incluyes este código:

Dim conex As String = "Data Source=OSCARVAIO;Initial Catalog=Pruebas;Integrated Security=True"
Sub Page_Load()
If Not Page.IsPostBack Then
FillNodes()
End If
End Sub
Sub FillNodes()
Dim ds As DataSet = GetData()
For Each masterRow As DataRow In ds.Tables("Padres").Rows
Dim masterNode As New TreeNode(masterRow("nombre").ToString(), masterRow("codigo").ToString())
If IsDBNull(masterRow("padre")) Then
TreeView1.Nodes.Add(masterNode)
Else
For Each node As TreeNode In TreeView1.Nodes
If node.Value.ToString() = masterRow("codigo").ToString() Then
masterNode = node
Exit For
End If
If node.ChildNodes.Count > 0 Then
Dim NodoEncontrado As TreeNode = BuscarNodo(node, masterRow("codigo").ToString())
If Not NodoEncontrado Is Nothing Then
masterNode = NodoEncontrado
Exit For
End If
End If
Next
End If
For Each childRow As DataRow In masterRow.GetChildRows("Hijo")
Dim childNode As New TreeNode(childRow("nombre").ToString(), childRow("codigo").ToString())
masterNode.ChildNodes.Add(childNode)
Next
Next
End Sub
Function BuscarNodo(ByVal arbol As TreeNode, ByVal codigo As String) As TreeNode
For Each node As TreeNode In arbol.ChildNodes
If node.Value.ToString() = codigo Then
BuscarNodo = node
Exit Function
End If
If node.ChildNodes.Count > 0 Then
BuscarNodo(node, codigo)
End If
Next
BuscarNodo = Nothing
End Function
Function GetData() As DataSet
Dim conn As SqlConnection = New SqlConnection(conex)
Dim sqlCat As StringBuilder = New StringBuilder()
sqlCat.Append("SELECT ISNULL(P1.Codigo,P2.Codigo) AS codigo, ")
sqlcat.Append("ISNULL(P1.nombre,P2.nombre) AS nombre, ")
sqlcat.Append("ISNULL(P1.padre,P2.padre) AS padre ")
sqlcat.Append("FROM ")
sqlCat.Append("(SELECT Tabla.codigo, Tabla.nombre, Tabla.padre ")
sqlcat.Append("FROM Tabla WHERE padre IS NULL) AS P1 ")
sqlcat.Append("FULL JOIN ")
sqlCat.Append("(SELECT T2.* ")
sqlcat.Append("FROM Tabla AS T1 INNER JOIN Tabla AS T2 ON ")
sqlcat.Append("T1.padre=T2.codigo) AS P2 ON ")
sqlcat.Append("P1.Codigo=P2.Codigo ")
sqlcat.Append("ORDER BY codigo ")
Dim sqlProd As String = "SELECT Codigo,Nombre,Padre FROM Tabla AS Hijos WHERE Padre<>''"
Dim daCat As SqlDataAdapter = New SqlDataAdapter(sqlCat.ToString(), conn)
Dim daProd As SqlDataAdapter = New SqlDataAdapter(sqlProd, conn)
Dim ds As DataSet = New DataSet()
daCat.Fill(ds, "Padres")
daProd.Fill(ds, "Hijos")
ds.Relations.Add("Hijo", _
ds.Tables("Padres").Columns("Codigo"), _
ds.Tables("Hijos").Columns("Padre"))
Return ds
End Function


Lo ejecutas y podrás ver como se rellena el treeView.

Esta entrada del blog la he cambiado para completarla para n jerarquías y para padres huérfanos según algunos comentarios recibidos a fecha del '06/09/2008'.

Etiquetas

.net (1) ALGORITMO (4) algoritmos (1) Android (1) angular (2) aplicaciones WEB (1) ARGENTINA (1) ASP (4) asp .NET (1) ASP .NET Identity (1) attach (1) Azure (1) base de datos (1) BINDING (1) BioInformática (2) bootstrap (1) C (2) C# (27) castellano (1) catalán (1) Charla (1) CheckedListBox (1) Clase (1) clausura transitiva (2) CLIENTES (1) Closing (1) Combobox (1) Comisiones (1) CONCURSO (1) condones (1) consultas (1) corrupta (1) CORS OWIN (1) CORS WEB API 2 (1) Criptografía (1) CUENTA NARANJA (1) Custom Control (1) Daniel Seara (1) DATAGRIDVIEW (1) David Salgado (2) dendrograma (6) depurar (1) desarrollo (1) Deserializar (1) DEVCAMP (2) durex (1) e-DNI (1) el Guille (2) Eladio Rincón (1) elGamal (1) encriptación (1) encuesta (1) Entidad (1) ERROR (2) error 3624 (1) España (1) España es nido de víboras. (1) Euclides (1) Euclides extendido (1) evento (1) eventos. (1) factorización (1) factorizar (1) física (1) Framework 2.0 (1) Framework 3.5 (5) Framework 4 (2) Francisco González (1) Francisco Ruiz (1) GO (1) google (1) gossip (1) Grupos de usuarios (1) Guadalajara (1) Guille Comunity Tour (2) Gusenet (9) GUSENET. (1) Huelga informáticos (1) IBEX 35 (1) Idioma (1) IFT (1) IISExpress (1) Indice de Fuerza Tecnica (1) informática (1) Informix (1) ING DIRECT (1) INGDIRECT (1) Ingeniería Informática (2) Inteligencia artificial (5) Intro (1) IOS (1) IPad (1) IPhone (1) IV Aniversario (1) JavaScript (2) JPA (2) keybd_event (1) LA CAIXA (1) La Pineda (1) ladroentidad (1) Lector RSS (2) LINQ (5) LINQ2XML (1) ListBox (1) Live Distributed Objects (1) llenar (1) LOG (1) Madrid .NET (1) MainMenu (1) MAP (1) MAP 2011 (1) MAR DEL PLATA (1) matemáticas (1) Matriculación (1) MDIList (1) MdiWindowsListItem (1) MenuItem (1) MenuStrip (1) Microsoft (18) Microsoft Active Professional (1) Miguel Egea (2) MSDE 2 (1) MSDE 2000 (1) MVVM Light (2) mysql (1) NAMESPACE (1) Needleman (2) NET (1) NS (1) Oferta empleo (1) Office 14 (1) Office 2007 (1) Office 2009 (1) ON ERROR (1) OOB (1) Oscar Montesinos (1) OWIN (1) OWIN Security middleware (1) Paginación (1) PDC (1) Pedro Hurtado (1) PINTARTECA (1) PrinterSettings (1) Process (1) ProcessStartInfo (1) Programador (1) Relacional (1) robo (1) RSS (1) Rubén Garrigós (1) Salvador Ramos (1) Santa Pola (1) scrape (1) scraping (1) ScrollBar (1) Secretaría (1) SendInput (1) SENDKEYS (1) Sergio Vázquez (1) Serializar (1) Silverlight 2.0 (2) Silverlight 4 (1) Silverlight 5 (3) Silverlight. (1) Sindicado (1) Sistema Personal de Trading (3) Sistemas Distribuidos (1) SOLID SUMMIT 2009 (1) SPT (2) SQL Server (3) SQL Server 2000 (2) SQL Server 2005 (2) SQL Server 2008 (3) SQL Server Denali (1) SQL Server Information Services. (1) SQLU (1) SSIS (1) SUMMIT SQL (1) Suspect (1) Syndication (1) TAB (1) Tablas (1) Tarragona (1) Token bearer (1) ToolStripMenuItem (1) ToString() (1) Traductor (1) transacciones (1) treeview (1) truco (1) TRY CATCH (1) UCI (1) Unience (2) Universad (1) Universidad Oberta Catalunya (2) UOC (8) Usuarios. (1) VB (1) VB6 (1) VB9 (1) VIAJAR (1) Vila-seca (1) VISUAL BASIC (3) Visual Basic. (1) visual studio (1) Visual Studio 2005 (1) Visual Studio 2008 (16) Visual Studio 2010 (2) Visual Studio 2013 (1) VS2010 (1) VSTA (1) VSTO (1) WCF (1) WEB API (1) web.config (1) WebClient (1) WF (1) windows (1) Windows 7 (3) Windows 8 (2) Windows Azure (1) Windows pone (1) Windows Server 2008 (1) Windows Vista (1) woff (1) WP7 (1) WPF (1) Wunsch (2) XAML (4) XDocument (1) XElement (1) XML (3) XNA (1) Yield (2)