Tengo el placer de anunciaros que ya tenemos abierto el registro para el megaevento informático del año en España.
más información en http://www.gusenet.org y registro en la misma web.
Blog con trucos y utilidades para desarrollo de aplicaciones. Desde SQL Server, C#, LINQ, Visual Basic, WPF, VSTO, Office, Silverlight y todo lo que pasa por mis manos en el día a día.
martes, marzo 25, 2014
lunes, enero 13, 2014
woff, Azure e IIS Express en Visual Studio 2013.
Un pequeño TIP para hoy...
Resulta que uso una plantilla bootstrap para un front-end SPA que usa un fichero WOFF (Web Open Font Format) sin problemas en mi máquina con VS2013 e IISExpress pero cuando lo subo a Azure la fuente no me la carga y me da un error al intentar abrir el archivo para leer la fuente.
(Si queréis más información en http://es.wikipedia.org/wiki/Web_Open_Font_Format lo explica de maravilla.)
Investigando encontré que me faltaba una entrada en el web.config que indicara el tipo de fichero y así que me puse manos a la obra para añadir lo siguiente:
Fantástico, como diría el grupo LOL, ya me funciona en Azure, así que maravilloso, a seguir trabajando... pero no, que pasa ahora?, pues muy sencillo que en local IISExpress me da error en esta línea de que este mimeType no se puede cargar dos veces. ¿dos veces?, no, si sólo está una en web.config, pues nada a seguir investigando, así que me encuentro que existe el siguiente archivo de configuración:
%USERPROFILE%\Documents\IISExpress\config\applicationhost.config
y dentro de él:
la línea maldita, así que decido borrarla y listo, ya puedo trabajar y desplegar sin preocuparme.
Puede que existan más soluciones como la de modificar el web.config en el despliegue, pero en fin, esta ha sido la más cómoda y rápida para mi, además veo interesante saber que existe el applicationhost.config que hasta ahora no lo sabía, pero si alguien propone otra que lo comente please.
Un saludo
Resulta que uso una plantilla bootstrap para un front-end SPA que usa un fichero WOFF (Web Open Font Format) sin problemas en mi máquina con VS2013 e IISExpress pero cuando lo subo a Azure la fuente no me la carga y me da un error al intentar abrir el archivo para leer la fuente.
(Si queréis más información en http://es.wikipedia.org/wiki/Web_Open_Font_Format lo explica de maravilla.)
Investigando encontré que me faltaba una entrada en el web.config que indicara el tipo de fichero y así que me puse manos a la obra para añadir lo siguiente:
<staticContent> <mimeMap fileExtension=".woff" mimeType="application/x-font-woff" /> </staticContent> </system.webServer>
Fantástico, como diría el grupo LOL, ya me funciona en Azure, así que maravilloso, a seguir trabajando... pero no, que pasa ahora?, pues muy sencillo que en local IISExpress me da error en esta línea de que este mimeType no se puede cargar dos veces. ¿dos veces?, no, si sólo está una en web.config, pues nada a seguir investigando, así que me encuentro que existe el siguiente archivo de configuración:
%USERPROFILE%\Documents\IISExpress\config\applicationhost.config
y dentro de él:
<mimeMap fileExtension=".woff" mimeType="font/x-woff" />
la línea maldita, así que decido borrarla y listo, ya puedo trabajar y desplegar sin preocuparme.
Puede que existan más soluciones como la de modificar el web.config en el despliegue, pero en fin, esta ha sido la más cómoda y rápida para mi, además veo interesante saber que existe el applicationhost.config que hasta ahora no lo sabía, pero si alguien propone otra que lo comente please.
Un saludo
domingo, diciembre 01, 2013
Como empezar con aplicaciones web SPA (Simple Page Application)
Hola amig@s,
hace poco me interesé por las aplicaciones web y su forma de trabajar (sólo la parte front-end), que tecnologías, frameworks y herramientas se utilizan en este mundo nuevo, y ayyyy Dios mío, ¿pero esto que lo que es?, como dirían en Murcia, ay pobre de mi, aquí hay miles de conceptos nuevos, varios frameworks, etc. y lo que es peor, hay varios navegadores con distintas versiones y comportamientos distintos, uyyyyy, palabra mayores.
Así que mediante esta entrada no pretendo establecer una norma o directriz de trabajo, ni tiene que ser utilizada como referencia para la creación de aplicaciones web, ni SPA ni nada de nada. Esta entrada es solo para transmitir mi experiencia con ellas y que es lo que más me ha gustado a título personal.
Herramientas.
Mi herramienta de trabajo hasta este momento era VS2010, así que decidí comprobar que tal iba VS2012 con las apps webs y me encontré con la creación de proyectos ASP.NET, pero uff hay varios tipos, ¿cuál de ellos?,:
seleccioné MVC 4 (Model View Controller), sonaba bien y además el patrón lo conozco, y aquí viene la pregunta de nuevo, motor de vistas? que aplicación? "razor?", que es razor?, ah sí, es nuevo y Scott Guthrie dice que es "Easy to Learn", pues nada a por razor:
Pero "oh my God", si ha salido el VS2013, que trae de nuevo? nooooooo, cambia todo a una aplicación ASP.NET? un sólo punto de partida??:
Sí, parece que ahora ya sólo tenemos un punto de entrada y luego podremos seleccionar más opciones a gusto del consumidor.
Así que adelante, ya podemos empezar.
Patrón en el front-end
Lo del patrón es un cachondeo, y digo un cachondeo por las conversaciones en el bar con unas cervezas, que si angular es MVC, que no lo es que es MVW, que si es mejor usar uno MVVM, bueno, en definitiva, hay varios frameworks y se implementan varios patrones, de lo que he podido averiguar es esto:
angularjs es MVC pero ellos lo llaman MVW (Model View Wathever)
knockout es MVVM, o sea como el que usamos en las aplicaciones SL5, WPF o XAML de W8/8.1 y WP8.
También tenemos Durandal que dice que es un patrón MV* es decir, MV y lo que quieras, pero no lo conozco y no puedo opinar.
Vistas
Pues lo dicho anteriormente: Razor más HTML5 y CSS, con Bootstrap. Más cosas?, sí más, mucho más, a ver, HTML5 me lo dejo para el final, CSS y Bootstrap, pues vamos a ver un poco de código:
BootStrap en HTML
aghhhhh me da algo!!! cuanta class y nombre raro,,,,,
Pues sí, Bootstrap es http://en.wikipedia.org/wiki/Bootstrap_%28front-end_framework%29, un front-end para construir y mantener aplicaciones web y websites de una forma fácil y consistente (no quiero ni saber como era antes) y puedes intentar entender sus tripas en: http://getbootstrap.com/css/ y adaptártelo o mejor te pasas por aquí y te compras una plantilla que te facilite las cosas.
CSS de Bootstrap
Pues iba a mostrar algo de código CSS pero como creo que nunca voy a tratarlo o investigar porque es de lo más enrevesado que he visto prefiero ni verlo. Con esto quiero decir que si tienes una buena plantilla o un buen equipo de diseño no tienes que tener mayores problemas.
Controladores
El tema de controladores he decidido usar angular como pieza fundamental de comunicación front-end<>back-end, siguiendo los consejos del amigo Pedro, que aunque el blog esté en Geeks, es de los que se puede leer.
Reflexión:
HTML5 , sí, sí, HTML5, eso es como los titulares del periódico, una vez lo leas ponte a leerte el artículo con todo lo demás, bootstrap, angular, css y sus clases, puffff, hay mucha materia.
¿Porqué SPA?, porque está de moda, así de fácil, luego ya indagas y te das cuenta de la comodidad de un framework como angularjs y como me gustan los comics pues eso:
y te vas a ver algo, ¿unos primeros pasos? y te compras un libro para completar el aprendizaje y ya tienes el lío montado y unas semanas de pelea con todo.
Y como no podía ser de otra manera todo esto que explico en este post se lo debo al gran @_pedrohurtado que me tiene entretenido siempre con cosas así.
Blogs que sigo
martes, noviembre 05, 2013
Peleando con CORS en WEB API 2 y el Middleware OWIN
Una entrada breve de mis aventuras con CORS.
Antes de nada explicar que el API y mi cliente WEB van a trabajar separadamente por lo que el navegador no va a permitir que desde el cliente acceda al API por cuestiones de seguridad que se explican estupendamente en esta página:
https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
(para mí lo más importante de este link es entender que se manda en el header del request y en el del response, ya que esa es la clave de que todo funcione y si funciona es porque esas headers están bien formadas y si no lo están no funcionan, y eso es algo que puedes comprobar y simular con Fiddler)
Por otro lado me encuentro con el problema de implementar algo de seguridad y para ello configuro el API para Cuentas Individuales ya que de momento no necesito nada más sofisticado como el OAuth, aunque puede que en el futuro sí, pero eso es otra historia y puede que esta solución te venga al pelo también.
Como configurar Cuentas Individuales en ASP.NET Web API 2 lo tienes aquí:
http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api
Pero si lo haces con dos proyectos separados no te olvides de usar SSL o estarás vendido, tus contraseñas volarán a la vista de cualquiera que capture los paquetes http.
Y ahora viene el problema, y el problema es que hay que configurar CORS para que nuestra API devuelva la cabecera correcta en el RESPONSE y el navegador la acepte. Configurar CORS en Web API no es difícil, lo puedes hacer siguiendo estos pasos:
http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
pero personalmente no me gusta, he preferido seguir los consejos de Unai en:
http://geeks.ms/blogs/unai/archive/2012/03/05/implementando-cors-en-asp-net-web-api.aspx
porque así consigo manejar los mensajes request y response a mi antojo, y eso me lo recomienda el gran @_PedroHurtado (que haría yo sin él), en fin, creo que el problema se resuelve así, no?
NO!!!, Microsoft ha decidido usar OWIN para la seguridad ¿y que significa eso?, que OWIN actúa como un middleware, middle, middle, middle, sí, middle, estoy en medio y sólo dejo pasar a tu API lo que me venga al pairo, y en nuestro caso no te paso la petición de \Token porque me la como yo. Y aquí empiezan las vueltas y más vueltas, hasta que te das cuenta que este middleware necesita también CORS, porque el CORS que has configurado en el WEB API en este caso no te sirve nada.
Asi que manos a la obra y a ver que hace OWIN:
¿Nada más?, nada más, así que aquí habrá que decirle que me permita CORS, y se lo digo añadiendo el paquete Microsoft.Owin.Cors que encontrarás en NUGET perfectamente, poniendo el using Microsoft.Owin.Cors; correspondiente y añadiendo esta línea:
Pues ojito, que existe un problema de dependencia de Microsoft.Owin.Cors con Microsoft.AspNet.Cors y que está arreglado en la 2.0.2, así que si esa dependencia no la quieres asegúrate que te instalas la 2.0.2, en mi caso me da igual y tengo la 2.0.1, (a día de hoy no se ha liberado la 2.0.2, así que a joderse).
Ahora cuidadín, que has configurado 2 CORS y eso no es bueno, porque los 2 te van a tocar la cabecera del response y te vas a encontrar que lo que funcionaba antes no funciona ahora, así que toca quitar el CORS del WEB API para que funcione la api o tendrás errores de "headers con sintaxis incorrecta".
Y por otro lado puff, que peligro tiene esa línea, estás abriendo tu \Token al diablo, así que te aconsejo que mires en la carpeta Providers el archivo ApplicationOAuthProvider.cs y le pegues un vistazo a :
Porque recuerda que un AllowAll no es recomendable, y aquí me quedé, no quiero un AllowAll, quiero un AllowElSitioQueYoQuiera, y en eso estamos.
Para ello estoy siguiendo la serie de Owin y Katana de José M. Aguilar:
http://www.variablenotfound.com/2013/11/owin-y-katana-v-map-y-run.html?widgetType=BlogArchive&widgetId=BlogArchive1&action=toggle&dir=open&toggle=MONTHLY-1380578400000&toggleopen=MONTHLY-1383260400000
Cualquier comentario o aclaración os la agradezco, supongo que iré modificando el post conforme vaya aprendiendo, para mí todo esto es nuevo y me ha llevado muuuuuucho tiempo, así que si sirve para que otro no lo pierda, satisfecho me quedo.
Un saludo
Oscar
Antes de nada explicar que el API y mi cliente WEB van a trabajar separadamente por lo que el navegador no va a permitir que desde el cliente acceda al API por cuestiones de seguridad que se explican estupendamente en esta página:
https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
(para mí lo más importante de este link es entender que se manda en el header del request y en el del response, ya que esa es la clave de que todo funcione y si funciona es porque esas headers están bien formadas y si no lo están no funcionan, y eso es algo que puedes comprobar y simular con Fiddler)
Por otro lado me encuentro con el problema de implementar algo de seguridad y para ello configuro el API para Cuentas Individuales ya que de momento no necesito nada más sofisticado como el OAuth, aunque puede que en el futuro sí, pero eso es otra historia y puede que esta solución te venga al pelo también.
Como configurar Cuentas Individuales en ASP.NET Web API 2 lo tienes aquí:
http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api
Pero si lo haces con dos proyectos separados no te olvides de usar SSL o estarás vendido, tus contraseñas volarán a la vista de cualquiera que capture los paquetes http.
Y ahora viene el problema, y el problema es que hay que configurar CORS para que nuestra API devuelva la cabecera correcta en el RESPONSE y el navegador la acepte. Configurar CORS en Web API no es difícil, lo puedes hacer siguiendo estos pasos:
http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
pero personalmente no me gusta, he preferido seguir los consejos de Unai en:
http://geeks.ms/blogs/unai/archive/2012/03/05/implementando-cors-en-asp-net-web-api.aspx
porque así consigo manejar los mensajes request y response a mi antojo, y eso me lo recomienda el gran @_PedroHurtado (que haría yo sin él), en fin, creo que el problema se resuelve así, no?
NO!!!, Microsoft ha decidido usar OWIN para la seguridad ¿y que significa eso?, que OWIN actúa como un middleware, middle, middle, middle, sí, middle, estoy en medio y sólo dejo pasar a tu API lo que me venga al pairo, y en nuestro caso no te paso la petición de \Token porque me la como yo. Y aquí empiezan las vueltas y más vueltas, hasta que te das cuenta que este middleware necesita también CORS, porque el CORS que has configurado en el WEB API en este caso no te sirve nada.
Asi que manos a la obra y a ver que hace OWIN:
public void ConfigureAuth(IAppBuilder app)
{
//....
}
dentro de la clase Startup en el fichero Startup.Auth.cs de la carpeta App_Start.¿Nada más?, nada más, así que aquí habrá que decirle que me permita CORS, y se lo digo añadiendo el paquete Microsoft.Owin.Cors que encontrarás en NUGET perfectamente, poniendo el using Microsoft.Owin.Cors; correspondiente y añadiendo esta línea:
app.UseCors(CorsOptions.AllowAll);
Pues ojito, que existe un problema de dependencia de Microsoft.Owin.Cors con Microsoft.AspNet.Cors y que está arreglado en la 2.0.2, así que si esa dependencia no la quieres asegúrate que te instalas la 2.0.2, en mi caso me da igual y tengo la 2.0.1, (a día de hoy no se ha liberado la 2.0.2, así que a joderse).
Ahora cuidadín, que has configurado 2 CORS y eso no es bueno, porque los 2 te van a tocar la cabecera del response y te vas a encontrar que lo que funcionaba antes no funciona ahora, así que toca quitar el CORS del WEB API para que funcione la api o tendrás errores de "headers con sintaxis incorrecta".
Y por otro lado puff, que peligro tiene esa línea, estás abriendo tu \Token al diablo, así que te aconsejo que mires en la carpeta Providers el archivo ApplicationOAuthProvider.cs y le pegues un vistazo a :
public override Task TokenEndpoint(...)
Porque recuerda que un AllowAll no es recomendable, y aquí me quedé, no quiero un AllowAll, quiero un AllowElSitioQueYoQuiera, y en eso estamos.
Para ello estoy siguiendo la serie de Owin y Katana de José M. Aguilar:
http://www.variablenotfound.com/2013/11/owin-y-katana-v-map-y-run.html?widgetType=BlogArchive&widgetId=BlogArchive1&action=toggle&dir=open&toggle=MONTHLY-1380578400000&toggleopen=MONTHLY-1383260400000
Cualquier comentario o aclaración os la agradezco, supongo que iré modificando el post conforme vaya aprendiendo, para mí todo esto es nuevo y me ha llevado muuuuuucho tiempo, así que si sirve para que otro no lo pierda, satisfecho me quedo.
Un saludo
Oscar
miércoles, julio 03, 2013
Acceder a las propiedades del Scrollbar de un Listbox en SilverLight 5.
¿Cómo se pueden saber los elementos visibles en un ListBox de Silverlight?.
Con el código siguiente se podrían hacer los cálculos necesarios al suscribirse al evento que salta al mover la barra de scroll. En definitiva se trata de añadir funcionalidad al propio listbox de Silverlight creando un nuevo control que acceda al ScrollBar que vienen implementado en el ListBox y del que no he conseguido acceder de cualquier otra manera.
Un saludo
Oscar
Con el código siguiente se podrían hacer los cálculos necesarios al suscribirse al evento que salta al mover la barra de scroll. En definitiva se trata de añadir funcionalidad al propio listbox de Silverlight creando un nuevo control que acceda al ScrollBar que vienen implementado en el ListBox y del que no he conseguido acceder de cualquier otra manera.
using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Media; public class ccListBox: ListBox { public delegate void MyEventsEventHandler(object sender, ScrollBarChangedArgs e); public event MyEventsEventHandler ScrollBarChanged; private double _lastValue; public override void OnApplyTemplate() { base.OnApplyTemplate(); base.LayoutUpdated += new System.EventHandler(ccListBox_LayoutUpdated); } void ccListBox_LayoutUpdated(object sender, System.EventArgs e) { base.LayoutUpdated -= new System.EventHandler(ccListBox_LayoutUpdated); ScrollViewer viewer = GetTemplateChild("ScrollViewer") as ScrollViewer; if (viewer != null) { if (viewer.GetVisualChildren().Count() > 0) { FrameworkElement viewerRoot = (FrameworkElement)VisualTreeHelper.GetChild(viewer, 0); ScrollBar horizontal = ((ScrollBar)viewerRoot.FindName("HorizontalScrollBar")); if (horizontal != null) { horizontal.ValueChanged += ScrollBar_ValueChanged; } } } } void ScrollBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { ScrollBar bar = sender as ScrollBar; if (e.NewValue != _lastValue) { ScrollBarChangedArgs args = new ScrollBarChangedArgs(); args.Maximum = bar.Maximum; args.ViewPortSize = bar.ViewportSize; args.NewValue = e.NewValue; args.OldValue = e.OldValue; OnScrollBarChanged(this, args); } _lastValue = e.NewValue; } protected virtual void OnScrollBarChanged(object sender, ScrollBarChangedArgs e) { if (ScrollBarChanged != null) { ScrollBarChanged(sender, e); } } } public class ScrollBarChangedArgs : RoutedEventArgs { public double OldValue { get; set; } public double NewValue { get; set; } public double Maximum { get; set; } public double ViewPortSize { get; set; } }
Un saludo
Oscar
lunes, enero 21, 2013
Alineamientos globales y locales en Bioinformática II - Proyecto Windows 8
Bueno, parece que va tomando forma la aplicación, la estructura la estoy pensando todavía, pero ya puedo ir subiendo un algo de como va a ser:
No se ve con mucha claridad pero ya iré explicando las diferentes partes conforme lo vaya planificando y diseñando.
jueves, enero 17, 2013
Alineamientos globales y locales en Bioinformática I- C Benchmark
Hola, cuanto tiempo no?, sí, tengo el blog descuidado, me gustaría actualizar más el blog pero debido a los proyectos en los que estoy inmerso y a la firma de un contrato de confidencialidad no puedo publicar nada que esté relacionado con esos proyectos, pero como tengo el hobby de estudiar, lo que voy a hacer es publicar cosas relacionadas con lo que estudio, así que aquí está el primer "post":
Acabo de empezar en el mundillo de la bioinformática y he realizado una versión en C del conocido algoritmo de Needleman y Wunsch para alineamientos globales de secuencias de nucleótidos y proteínas. La decisión de subir el trabajo a la web es por un empujón que me ha dado David Salgado para que lo haga.
Como me ha gustado bastante este mundillo me he planteado migrarlo a C# pero mejorando la primera versión, que la verdad sea dicha, con las prisas me ha salido un poco churro porque no conozco apenas el lenguaje C. (He perdido más tiempo aprendiendo la sintaxis de C que realizando el algoritmo de una manera aceptable.)
Como meta inicial tengo que mejorar estos tiempos:
Que cómo véis tiene un problemilla para secuencias largas, o problemón, 1200 aminoácidos/nucleótidos no son muchos, son más bien pocos si partimos de que un virus puede tener entre 5000 y 800.000 pares de bases, en nuestro caso podríamos tener que comparar un gen de una secuencia de 100.000 letras con otra de 100.000, y eso ya empieza a ser problemático.
Con esto me pongo manos a la obra y pienso. ¿qué necesito?, ¿qué puedo hacer?
La idea que estoy implementando es la siguiente.
-El proyecto está alojado en tfs.visualstudio.com (así de paso lo pruebo y en cuanto tenga algo consistente lo abro a algunos amigos o colegas de profesión como a @xavipaper).
-Lo estoy haciendo en Windows 8 con C# y XAML (lo mismo, probar y aprender).
-Me he bajado MVVM Light para Windows 8 porque lo conozco de Silverlight y me parece un muy buen Framework que me ahorra mucho tiempo.
-Tengo que estudiar todo el tema de paralelismo que puedo encontrar en el blog de Lluis Franco, que es todo un crack en este tema.
-El tratamiento de cadenas tan largas creo que lo tengo más o menos claro creando buffers/doble buffers de entrada.
-Me faltaría estudiar el tratamiento de matrices que se requiere para el algoritmo,
Ya he empezado y estoy haciendo cosas, pero poco a poco, según disponga de tiempo libre, así que para el próximo "post" espero ya poner algo de código.
Un saludo
Oscar
Acabo de empezar en el mundillo de la bioinformática y he realizado una versión en C del conocido algoritmo de Needleman y Wunsch para alineamientos globales de secuencias de nucleótidos y proteínas. La decisión de subir el trabajo a la web es por un empujón que me ha dado David Salgado para que lo haga.
Como me ha gustado bastante este mundillo me he planteado migrarlo a C# pero mejorando la primera versión, que la verdad sea dicha, con las prisas me ha salido un poco churro porque no conozco apenas el lenguaje C. (He perdido más tiempo aprendiendo la sintaxis de C que realizando el algoritmo de una manera aceptable.)
Como meta inicial tengo que mejorar estos tiempos:
Que cómo véis tiene un problemilla para secuencias largas, o problemón, 1200 aminoácidos/nucleótidos no son muchos, son más bien pocos si partimos de que un virus puede tener entre 5000 y 800.000 pares de bases, en nuestro caso podríamos tener que comparar un gen de una secuencia de 100.000 letras con otra de 100.000, y eso ya empieza a ser problemático.
Con esto me pongo manos a la obra y pienso. ¿qué necesito?, ¿qué puedo hacer?
La idea que estoy implementando es la siguiente.
-El proyecto está alojado en tfs.visualstudio.com (así de paso lo pruebo y en cuanto tenga algo consistente lo abro a algunos amigos o colegas de profesión como a @xavipaper).
-Lo estoy haciendo en Windows 8 con C# y XAML (lo mismo, probar y aprender).
-Me he bajado MVVM Light para Windows 8 porque lo conozco de Silverlight y me parece un muy buen Framework que me ahorra mucho tiempo.
-Tengo que estudiar todo el tema de paralelismo que puedo encontrar en el blog de Lluis Franco, que es todo un crack en este tema.
-El tratamiento de cadenas tan largas creo que lo tengo más o menos claro creando buffers/doble buffers de entrada.
-Me faltaría estudiar el tratamiento de matrices que se requiere para el algoritmo,
Ya he empezado y estoy haciendo cosas, pero poco a poco, según disponga de tiempo libre, así que para el próximo "post" espero ya poner algo de código.
Un saludo
Oscar
lunes, septiembre 10, 2012
Silverlight 5, depurando un Binding
Aloha!!!, este fin de semana estuve cómo mentor en el Megathon Windows 8, en concreto en Murcia, comentábamos como depurar los bindings y no encontrábamos una solución entre los allí presentes, en fin, que buscando por el mundillo aunque algunos se empeñen en llamarlo la nube, encontré lo siguiente:
Para comprobar un binding que nos está volviendo locos, lo que tenemos que hacer es poner un punto de ruptura o breakpoint, en la línea del binding. Luego ejecutamos la aplicación y cuando llegue a ese punto la aplicación se parará, en la ventana de variables locales tendremos el BindingState de la línea en la que hemos parado. Podéis verlo mejor en la imagen.
No sé si funcionará en el XAML de Metro, si alguien lo sabe que lo diga, un saludo y hasta otra.
Para comprobar un binding que nos está volviendo locos, lo que tenemos que hacer es poner un punto de ruptura o breakpoint, en la línea del binding. Luego ejecutamos la aplicación y cuando llegue a ese punto la aplicación se parará, en la ventana de variables locales tendremos el BindingState de la línea en la que hemos parado. Podéis verlo mejor en la imagen.
No sé si funcionará en el XAML de Metro, si alguien lo sabe que lo diga, un saludo y hasta otra.
domingo, diciembre 11, 2011
Silverlight 5
Buena noticia para todos los que usamos Silverlight en nuestros desarrollos, desde hoy tenemos Silverlight 5 disponible para descargar en:
http://www.silverlight.net/downloads
para saber más en:
http://www.silverlight.net/learn/overview/what%27s-new-in-silverlight-5
y para conocer las novedades en:
http://msdn.microsoft.com/en-us/library/gg986857%28v=VS.95%29.aspx
http://www.silverlight.net/downloads
para saber más en:
http://www.silverlight.net/learn/overview/what%27s-new-in-silverlight-5
y para conocer las novedades en:
http://msdn.microsoft.com/en-us/library/gg986857%28v=VS.95%29.aspx
viernes, diciembre 02, 2011
Algoritmo extendido de Euclides
Haciendo algunos ejercicios criptográficos tenía que firmar digitalmente con elGamal los mensajes a enviar y para ello necesitaba calculo el inverso de a módulo n, así que:
os dejo un algoritmo para encontrar el inverso de a módulo n cuando mcd(a,n)=1.
os dejo un algoritmo para encontrar el inverso de a módulo n cuando mcd(a,n)=1.
/// <summary>
/// Algoritmo extendido de Euclides
/// </summary>
/// <returns>devuelve x tal que ax mod n=1, donde "0<a<n" ></returns>
static private int algoritmo(int a, int n)
{
List<int> g=new List<int>();
g.Add(n); g.Add(a);
List<int> u = new List<int>();
List<int> v = new List<int>();
u.Add(1); v.Add(0);
u.Add(0); v.Add(1);
int i = 1;
while (g[i] != 0)
{
//g[i] = u[i] * n + v[i] * a;
int y = g[i - 1] / g[i];
g.Add(g[i - 1] - y * g[i]);
u.Add(u[i - 1] - y * u[i]);
v.Add(v[i - 1] - y * v[i]);
i++;
}
int x = v[i - 1];
if (x > 0)
{ return x; }
else { return x + n; }
}
viernes, noviembre 04, 2011
Silverlight 4 OOB evento Closing
Existe un problema con el evento Closing en Silverlight 4. El problema es que el evento Closing a veces se dispara y a veces no,
Application.Current.MainWindow.Closing -= MainWindow_Closing;
¿y por qué?, parece ser que antes del evento, el objeto Application.Current.MainWindow
se larga a papelera y es destruido por el Garbage Collector.
No me he resistido a subir la solución al blog ya que me he pasado un buen rato esta mañana buscando la causa del problema para solucionarlo, al final la he encontrado y comparto una posible solución con ustedes.
La solución es crear un objeto estático (static object _mainWindow;) que almacene esta ventana y así conseguimos cancelar el cierre de la ventana si por ejemplo, queremos que ésta esté bloqueada al mostrar una ChildWindow, estemos haciendo un upload, un download o reproduciendo una canción:
if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions)
{
_mainWindow = Application.Current.MainWindow; // con esto queda solucionado.
Application.Current.MainWindow.Closing += MainWindow_Closing;
}
Application.Current.MainWindow.Closing -= MainWindow_Closing;
¿y por qué?, parece ser que antes del evento, el objeto Application.Current.MainWindow
se larga a papelera y es destruido por el Garbage Collector.
No me he resistido a subir la solución al blog ya que me he pasado un buen rato esta mañana buscando la causa del problema para solucionarlo, al final la he encontrado y comparto una posible solución con ustedes.
La solución es crear un objeto estático (static object _mainWindow;) que almacene esta ventana y así conseguimos cancelar el cierre de la ventana si por ejemplo, queremos que ésta esté bloqueada al mostrar una ChildWindow, estemos haciendo un upload, un download o reproduciendo una canción:
if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions)
{
_mainWindow = Application.Current.MainWindow; // con esto queda solucionado.
Application.Current.MainWindow.Closing += MainWindow_Closing;
}
sábado, mayo 07, 2011
Traductor catalán-castellano con "scraping"
Si tenéis problemas con el catalán por algún motivo y necesitáis un traductor en tiempo real "by the face", aquí os dejo un extracto de un programilla que traduce del catalán al castellano a partir del traductor de google. Si os fijáis bien en la técnica, se puede modificar para traducir cualquier idioma que soporte el traductor de google ("esta técnica la saqué de un lector "by the face" de cotizaciones de bolsa en tiempo real de yahoo").
Llamada al servicio:
private string llamarServicio(string palabra,string sourceLanguage, string targetLanguage)
{
//palabra: abat
//sourceLanguage: ca
//targetLangauge: es
ASCIIEncoding encoding = new ASCIIEncoding();
string postData = "hl=" + targetLanguage;
postData += ("&sl=" + sourceLanguage);
postData += ("&tl=" + targetLanguage);
postData += ("&q=" + palabra);
WebRequest request = WebRequest.Create(
"http://translate.google.es/?" + postData);
// If required by the server, set the credentials.
request.Credentials = CredentialCache.DefaultCredentials;
// Get the response.
WebResponse response = request.GetResponse();
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("Windows-1252"), true);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Clean up the streams and the response.
reader.Close();
response.Close();
return responseFromServer;
}
y ahora la llamada la búsqueda del resultado con la expresión regular:
internal string scrapeIdioma(string texto, string cadenaABuscar)
{
//texto es el código fuentes de la página web que nos devuelve la
//función anterior
//cadenaABuscar es la expresión regular:
//"(this.style.backgroundColor='#fff'\">(\\w+))"
Regex _regex;
_regex = new Regex(cadenaABuscar, RegexOptions.Compiled | RegexOptions.IgnoreCase);
Match match = _regex.Match(texto);
if (match.Success && match.Groups.Count>1)
{
return match.Groups[2].Value.ToString();
}
return "";
}
Pues eso, cualquier duda os la resolveré sin problemas.
Llamada al servicio:
private string llamarServicio(string palabra,string sourceLanguage, string targetLanguage)
{
//palabra: abat
//sourceLanguage: ca
//targetLangauge: es
ASCIIEncoding encoding = new ASCIIEncoding();
string postData = "hl=" + targetLanguage;
postData += ("&sl=" + sourceLanguage);
postData += ("&tl=" + targetLanguage);
postData += ("&q=" + palabra);
WebRequest request = WebRequest.Create(
"http://translate.google.es/?" + postData);
// If required by the server, set the credentials.
request.Credentials = CredentialCache.DefaultCredentials;
// Get the response.
WebResponse response = request.GetResponse();
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("Windows-1252"), true);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Clean up the streams and the response.
reader.Close();
response.Close();
return responseFromServer;
}
y ahora la llamada la búsqueda del resultado con la expresión regular:
internal string scrapeIdioma(string texto, string cadenaABuscar)
{
//texto es el código fuentes de la página web que nos devuelve la
//función anterior
//cadenaABuscar es la expresión regular:
//"(this.style.backgroundColor='#fff'\">(\\w+))"
Regex _regex;
_regex = new Regex(cadenaABuscar, RegexOptions.Compiled | RegexOptions.IgnoreCase);
Match match = _regex.Match(texto);
if (match.Success && match.Groups.Count>1)
{
return match.Groups[2].Value.ToString();
}
return "";
}
Pues eso, cualquier duda os la resolveré sin problemas.
domingo, abril 10, 2011
Windows Phone 7, Android e IOS (I)
Hace poco más de un mes y ante la posibilidad de disponer de algún recurso más en la oficina, me he tirado al ruedo y he puesto en marcha un proyecto para "Mobile", que ofrezca un valor añadido a nuestros clientes de "algo" que ya disponemos. Este proyecto tan sólo se hace por curiosidad y para unirme al tren de las aplicaciones para los llamados "smartphones".
Análisis
Antes de nada y ante la variedad de los distintos dispositivos con sus distintos SO tuve que tomar una decisión de por donde empujar y como afrontar un proyecto tan variopinto y con tantas diferencias de implementación.
Lo primero es informarme del "cómo" y para eso busqué en la red para encontrar estos links que me han parecido los más interesantes para empezar:
Windows Phone 7
http://channel9.msdn.com/Blogs/channel9spain/Windows-Phone-7-herramientas-de-desarrollo-y-vender-en-MarketPlace
http://create.msdn.com/es-ES/
http://msdn.microsoft.com/en-us/WP7TrainingCourse
Análisis
Antes de nada y ante la variedad de los distintos dispositivos con sus distintos SO tuve que tomar una decisión de por donde empujar y como afrontar un proyecto tan variopinto y con tantas diferencias de implementación.
Lo primero es informarme del "cómo" y para eso busqué en la red para encontrar estos links que me han parecido los más interesantes para empezar:
Windows Phone 7
http://channel9.msdn.com/Blogs/channel9spain/Windows-Phone-7-herramientas-de-desarrollo-y-vender-en-MarketPlace
http://create.msdn.com/es-ES/
http://msdn.microsoft.com/en-us/WP7TrainingCourse
Android
http://jonsegador.com/2010/02/tutorial-android-paso-a-paso-desarrollo-aplicacion-notepad/
ttp://geeks.ms/blogs/jorge/archive/2011/03/01/instalando-monodroid-aplicaciones-android-con-net.aspx
http://jonsegador.com/2010/02/tutorial-android-paso-a-paso-desarrollo-aplicacion-notepad/
ttp://geeks.ms/blogs/jorge/archive/2011/03/01/instalando-monodroid-aplicaciones-android-con-net.aspx
IOS
http://developer.apple.com/devcenter/ios/index.action
http://www.maclatino.com/tutoriales-iphone-sdk-y-%C2%A1en-espanol/
http://www.migueldiazrubio.com/2010/11/08/desarrollo-ios-10-sencillos-pasos-para-desarrollar-un-proyecto-para-iphone/
http://www.codeproject.com/KB/iPhone/iOSGetStarted00.aspx
Una vez que conozco las distintas tecnologías y terminado el análisis empezamos con el diseño de la aplicación, pero antes de nada hay que investigar con las distintas herramientas y la facilidad de desarrollo que me ofrecen.
http://developer.apple.com/devcenter/ios/index.action
http://www.maclatino.com/tutoriales-iphone-sdk-y-%C2%A1en-espanol/
http://www.migueldiazrubio.com/2010/11/08/desarrollo-ios-10-sencillos-pasos-para-desarrollar-un-proyecto-para-iphone/
http://www.codeproject.com/KB/iPhone/iOSGetStarted00.aspx
Una vez que conozco las distintas tecnologías y terminado el análisis empezamos con el diseño de la aplicación, pero antes de nada hay que investigar con las distintas herramientas y la facilidad de desarrollo que me ofrecen.
Windows Phone 7
Personalmente y siendo un SO de Microsoft, me supone la herramienta más fácil para desarrollar ya que conozco como funciona porque la uso en el día a día en mi trabajo. Para desarrollar una aplicación para WP7 necesitaremos Visual Studio 2010 y el SDK de Windows Phone que podemos descargar desde la plataforma de desarrollo MSDN, tenemos un sin fin de recursos para empezar con él. También recomiento el tutorial de Oskar Alvarez, que es muy completo y lo va publicando en su blog de geeks.
Mencionar que WP7 nos permite 2 formas de desarrollo para su plataforma: Silverlight para WP7 y XNA para desarrollo de videojuegos. El lenguaje con el que trabajo es C# por lo que Silverlight me viene de perlas porque además conozco algo del framework, pero ojo aquí hay que conocer también algo de XAML que no supondrá muchos problemas porque en el sdk también nos incorpora la aplicación Expression Blend 4 para el diseño grafico.
Por estas facilidades, el diseño de la aplicación y los algoritmos de cálculo (capa lógica) se han realizado con UML den MagicDraw y se han pasado a C# en VS2010 con su correspodiente proyecto de test.
Android
Con Android he empezado a tener problemas, trabajo normalmente con tecnologías Microsoft y claro, plataforma nueva, lenguaje nuevo, problemas nuevos... Tengo la suerte (y el dinero que me sangran) de estudiar en la UOC y en la UOC casi el 100% de la práctica se desarrolla con Java y Eclipse, por lo que conozco esta plataforma de antemano.
Para Android hay que bajarse Eclipse y las SDK de desarrollo para Android. Un consejo, la versión 2.2 es la más estable (la 3.0 es una locura y de la 2.3 no he visto mucho smartphone). Empezamos el desarrollo con la 3.0 y nos encontramos con muchos problemas, cuelgues, lentitud, errores raros, etc... Cuando queríamos intentamos buscar un smartphone razonable y estándar para hacer pruebas nos encontramos con que la versión más extendida era la 2.2, por lo que bajamos hasta la 2.2 con muy pocas adaptaciones para seguir con el proyecto.
Android ha sido el seleccionado para la primera implementación.
IOS
Poco, muy poco puedo contar de IOS y su desarrollo, la implementación la he dejado para el final, sobre todo cuando he visto que el SDK para Windows está por detrás del de Apple, así que he empezado por lo primordial, conseguir un portátil MAC e informarme un poco sobre la plataforma de desarrollo, que según tengo entendido se llama XCode y pose un framework para IOS llamado Cocoa Touch y que el lenguaje de desarrollo es con Objective-C aunque permite otros lenguajes pero ahora mismo ni idea
Esta semana es la elegida para empezar con la implementación, así que en los próximas días tendré más información.
miércoles, marzo 02, 2011
MAP 2011
Bueno, me ha llegado el mail nombrándome MAP, doy gracias a los que lo han hecho posible. LLevo muchos años con tecnologías Microsoft y apoyando el grupo de usuarios, colaborando con el que me solicita ayuda y divulgando lo que sé mediante este blog, y ahora me ha llegado este renocimiento, así que muchas gracias.

http://image.email.microsoftemail.com/lib/fec4157370600275/m/3/ESP11076_03_Webversion.html

http://image.email.microsoftemail.com/lib/fec4157370600275/m/3/ESP11076_03_Webversion.html
domingo, noviembre 14, 2010
Microsoft SQL Server codename Denali
Esta entrada es para dar a conocer algunas de las novedades de la futura versión de SQL Server llamada Denali, la cuál ya está disponible desde hace unos días para descarga en la MSDN.
-Se esperan varias betas a lo largo del 2011, la versión final no tiene fecha definitiva, pero no es muy probable que salga en el 2011.
-Se podrá usar un IDENTITY a lo largo de varias tablas con (NEXT VALUE FOR schema.table)
-Las consultas podrán tener paginación (OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY)
-Se han añadido 20 nuevas DMV en Denali. (dm_db_objects_disabled_on_compatibility_level_change, dm_exec_describe_first_result_set, etc..)
-Nuevos eventos en el profiler: Database Suspect Date Page, Plan Guide Successful and Plan Guide Unsuccessful, etc...)
Es pronto para profundizar en el tema, pero no viene mal tener presentes estas "features" del nuevo SQL para próximos proyectos...
Un saludo.
-Se esperan varias betas a lo largo del 2011, la versión final no tiene fecha definitiva, pero no es muy probable que salga en el 2011.
-Se podrá usar un IDENTITY a lo largo de varias tablas con (NEXT VALUE FOR schema.table)
-Las consultas podrán tener paginación (OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY)
-Se han añadido 20 nuevas DMV en Denali. (dm_db_objects_disabled_on_compatibility_level_change, dm_exec_describe_first_result_set, etc..)
-Nuevos eventos en el profiler: Database Suspect Date Page, Plan Guide Successful and Plan Guide Unsuccessful, etc...)
Es pronto para profundizar en el tema, pero no viene mal tener presentes estas "features" del nuevo SQL para próximos proyectos...
Un saludo.
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
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;
}
}
}
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
///
/// distancias euclideas entre los objetos
static public double[,] distanciaEuclidea(List
{
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
///
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
///
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
///
static public string dendrograma(double[,] matriz)
{
try
{
string result="";
List
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
///
static private List
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
///
/// emparejamiento
static private int buscarLLaveAbrir(List
{
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
///
/// emparejamiento
static private int buscarLLaveCerrar(List
{
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
///
static private int buscarLLaveAbriryCierreParaComa(List
{
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;
}
}
}
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.
///
///
///
static public List
{
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;
}
}
}
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
///
static public List
{
string texto;
string[] filas;
List
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();
}
}
}
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
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();
}
}
}
Suscribirse a:
Entradas (Atom)
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)








