Blog de programación, donde ademas de encontrar pequeños programas en C# tambien publicaré pequeñas ayudas para SQL Server

Vladimir Miranda - vladivirus666@gmail.com. Con la tecnología de Blogger.

miércoles, 5 de abril de 2017

Desarrollo en Capas (Asp.NET) Parte II


En esta segunda parte del desarrollo en capas vamos a ver el código que tendrá nuestra capa de Acceso a Datos (proyecto AccesoDatos).

Si aún no has visto la primera parte de este artículo; puedes revisarlo dando Clic aquí.

En esta capa, vamos a todas las consultas que realizamos hacia la BD, para lo cual vamos a utilizar LINQ el cual nos ayudará a escribir consultas contra el método conceptual (Entity Framework) mediante Visual C# (más información aquí).

[sourcecode language='csharp'  padlinenumbers='true']
namespace AccesoDatos { public class AEC_DAL_Trabajador { } }
[/sourcecode]

Una vez realizado esto, voy a empezar creando un metodo del tipo “ConsultarTrabajador” que me va a devolver un List<> del tipo Trabajador, el primer problema que se me presenta al crear este método es que VS me genera un error ya que, de acuerdo al mensaje exacto:

“No se puede encontrar el tipo o el nombre de espacio de nombres ‘Trabajador’".

Para solucionar este inconveniente tenemos dos formas:

En la parte superior incluimos un using que haga referencia a nuestro proyecto Entidades

[sourcecode language='csharp' ]
using Entidades;
[/sourcecode]

Nos colocamos sobre el error y damos clic para que Intellisense nos muestre un pequeño “guión” de color azul (que en la imagen esta rodeado de rojo)

 https://lh6.googleusercontent.com/iSAmwg530NtB7lppe7VLuVqinpYiG_SQyqo7eitOFkVKkiiOnJeO1X2_JmG19aP0Ux90IqNodyqJfJmKuRHg=w1440-h789

Al colocarnos sobre el "guión" nos muestra un icono de color plomo, damos clic en el y nos despliega la ayuda, en mi caso voy a dar clic en using Entidades;

https://lh5.googleusercontent.com/unk8_L56iHdIcxKphpj7EyQag25w-CLIrZjSt8o-vQ7X776zhI-B1nY64-N9FOHgcX2AM1aKL-Tm7x-5dTt2=w1440-h789

Una vez terminada mi clase quedará de esta forma:

[sourcecode language='csharp' ]
using Entidades; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace AccesoDatos 
{ 
   public class AEC_DAL_Trabajador 
   { 
      public List ConsultaTrabajador() 
      { 
         using (TrabajadorEntities db = new TrabajadorEntities()) 
         { 
            return db.Trabajador.ToList(); 
         } 
      }
   }
}
[/sourcecode]

Para continuar, vamos a generar por cada Entidad en nuestro proyecto Entidades una clase independiente en nuestro proyecto AccesoDatos, voy a empezar con una clase a la que llamaré AEC_DAL_Trabajador; tambien cambiaré su atributo a pública, quedando de esta manera.

[sourcecode language='csharp' ]
using Entidades; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace AccesoDatos 
{ 
   public class AEC_DAL_Departamento 
   { 
      public List<Departamento> ConsultarDepartamento() 
      { 
         using(TrabajadorEntities db = new TrabajadorEntities()) 
         { 
            return db.Departamento.ToList(); 
         } 
      } 
      
      public Departamento ConsultarDepartamentoPorCodigo(decimal codigoPrincipal) 
      { 
         using (TrabajadorEntities db = new TrabajadorEntities()) 
         { 
            var query = (from dep in db.Departamento where dep.DEP_CODIGO == codigoPrincipal select dep).SingleOrDefault(); 
            return query; 
         } 
      } 

      public Departamento InsertarDepartamento(Departamento objetoDepartamento) 
      { 
         using (TrabajadorEntities db = new TrabajadorEntities()) 
         { 
             db.Departamento.Add(objetoDepartamento); 
             db.SaveChanges(); 
             return objetoDepartamento; 
          } 
      } 

		public List<Departamento> InsertarListaDepartamento(List<Departamento> listaDepartamento) 
		{ 
			using (TrabajadorEntities db = new TrabajadorEntities()) 
			{ 
				db.Departamento.AddRange(listaDepartamento); 
				db.SaveChanges(); 
				return listaDepartamento; 
			} 
		} 

		public Departamento ActualizarDepartamentoPorCodigo(Departamento objetoDepartamento) 
		{ 
			using (TrabajadorEntities db = new TrabajadorEntities()) 
			{ 
				var query = (from dep in db.Departamento where dep.DEP_CODIGO == objetoDepartamento.DEP_CODIGO select dep).SingleOrDefault(); 
				query.DEP_ESTADO = objetoDepartamento.DEP_ESTADO; 
				query.DEP_NOMBRE = objetoDepartamento.DEP_NOMBRE; 
				db.SaveChanges(); 
				return query; 
			} 
		} 

		public string EliminarDepartamento(decimal codigoPrincipal) 
		{ 
			try 
			{ 
				using (TrabajadorEntities db = new TrabajadorEntities()) 
				{ 
					var query = (from dep in db.Departamento where dep.DEP_CODIGO == codigoPrincipal select dep).SingleOrDefault(); 
					db.Departamento.Remove(query); 
					db.SaveChanges(); 
					return "Eliminado"; 
				} 
			} 
			catch (Exception err) 
			{ 
				return err.Message; 
			} 
		} 
	} 
}
[/sourcecode]
Una vez realizado este proceso, lo que deseo es consultar un Trabajador y que me indique el departamento y el cargo. lo que se haria en SQL (en mi caso) es generar una vista que me permita traer esa información:
[sourcecode language='sql' ]
elect TRA_CODIGO, DEP_CODIGO, CAR_CODIGO, TRA_NOMBRE, TRA_APELLIDO, TRA_IDENTIFICACION, TRA_TELEFONO, DEP_NOMBRE, CAR_NOMBRE from Trabajador TR INNER JOIN Departamento DP ON TR.DEP_CODIGO = DP.DEP_CODIGO INNER JOIN Cargo CG ON TR.CAR_CODIGO = CG.CAR_CODIGO
[/sourcecode]

Pero, la idea de utilizar Entity Framework y LINQ es ahorrarnos este paso y poderlo generar desde el mismo VS; para ello, voy a crearme una clase en el proyecto Entidades, la cual voy a llamar TrabajadorDepartamentoCargo

[sourcecode language='csharp' ]
namespace Entidades 
{ 
   public class TrabajadorDepartamentoCargo 
   { 
      public decimal TRA_CODIGO { get; set; } 
      public Nullable<Decimal> DEP_CODIGO { get; set; } 
      public Nullable<Decimal> CAR_CODIGO { get; set; } 
      public string TRA_NOMBRE { get; set; } 
      public string TRA_APELLIDO { get; set; } 
      public string TRA_IDENTIFICACION { get; set; } 
      public string TRA_TELEFONO { get; set; } 
      public string DEP_NOMBRE { get; set; } 
      public string CAR_NOMBRE { get; set; } 
   } 
}
[/sourcecode]

Una vez con la clase creada el proyecto hasta el momento debe quedarnos de la siguiente manera:

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtwNOb0updOQx_gTMUFnEfTV7dfBZVtnwr6oxSgu8StqCorU4-ruP1tkMF38j2lbQI3NSDctasd_qqxvae-YxO3iQVv5J33t07Ea-GKUjwQzlWbBE0LQAXS08D7a4GNU00Zt-8ZOwaxkE/s1600/image%25255B15%25255D.png

Ahora volvemos al proyecto AccesoDatos, en el vamos a crear una clase AEC_DAL_TrabajadorDepartamentoCargo y vamos a incluir un método ConsultarTrabajadorPorIdentificacion el cual tendrá una pequeña modificacion en relación a las consultas realizadas en las otras clases.

[sourcecode language='csharp'  padlinenumbers='true']
using Entidades; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
namespace AccesoDatos 
{ 
   public class AEC_DAL_TrabajadorDepartamentoCargo 
   { 
      public TrabajadorDepartamentoCargo ConsultarTrabajadorPorIdentificacion(string identificacion) 
      { 
         using(TrabajadorEntities db = new TrabajadorEntities()) 
         { 
            var query = (from tra in db.Trabajador where tra.TRA_IDENTIFICACION == identificacion 
                                  select new TrabajadorDepartamentoCargo 
                                  { 
                                     CAR_CODIGO = tra.CAR_CODIGO, 
                                     CAR_NOMBRE = tra.Cargo.CAR_NOMBRE, 
                                     DEP_CODIGO = tra.DEP_CODIGO, 
                                     DEP_NOMBRE = tra.Departamento.DEP_NOMBRE, 
                                     TRA_APELLIDO = tra.TRA_APELLIDO, 
                                     TRA_CODIGO = tra.TRA_CODIGO, 
                                     TRA_IDENTIFICACION = tra.TRA_IDENTIFICACION, 
                                     TRA_NOMBRE = tra.TRA_NOMBRE, 
                                     TRA_TELEFONO = tra.TRA_TELEFONO
                                   }).SingleOrDefault(); 
                                   return query; 
          } 
      }   
   } 
}
[/sourcecode]

Como pueden ver, en la ahora hacemos uso de las propiedades de navegación al solicitar CAR_NOMBRE de la tabla Cargo que esta relacionada con el trabajador y DEP_NOMBRE de la tabla Departamento que esta relacionada con el trabajador.

Y eso sería todo, lo que hicimos en esta parte es agregar una clase por cada entidad (4 clases) en el proyecto AccesoDatos, dentro de cada clase creamos métodos que realizan las consultas a la BD.

En los proximos días continuo con la capa de Negocio

Descargar Proyecto

martes, 28 de marzo de 2017

¿Por que hay tantos Pythons?


Python es asombroso.
Sorprendentemente, esa es una declaración bastante ambigua. ¿A qué me refiero con ‘Python’?, ¿Me refiero a la interfaz abstracta de Python?, ¿Me refiero a CPython, la implementación común de Python (y no confundir con Cython, que son similares en sus nombres)?, ¿O me refiero a algo completamente distinto? Tal vez me esté refiriendo indirectamente a Jython, o IronPython, o PyPy. O tal vez me he ido al extremo y estoy hablando de RPython o RubyPython (los cuales son cosas muy, muy distintas).
Mientras las tecnologías mencionadas anteriormente son llamadas de formas parecidas y referenciadas de la misma manera, algunas de ellas sirven para propósitos completamente distintos (o, al menos, operan de maneras completamente distintas).
A lo largo de mi tiempo trabajando con Python, me topé con toneladas de estas herramientas .*ython. Pero no hasta hace poco me tomé el tiempo de entender qué es lo que son, cómo funcionan y por qué son necesarias (a sus maneras).
En este artículo, voy a empezar desde cero y recorreré varias implementaciones de Python, concluyendo con una introducción detallada a PyPy, el cual creo es el futuro del lenguaje.
Todo empieza con entender que es lo que ‘Python’ realmente es.
Si tienes un buen entendimiento sobre código binario, máquinas virtuales y parecidos, siéntete libre de saltarte esta parte.

“Python es interpretado o compilado?”

Este es un punto común de confusión para principiantes en Python.
La primera cosa que hay que saber es que ‘Python’ es una interfaz. Existe una especificación sobre lo que Python debería hacer y cómo debería comportarse (cómo con cualquier interfaz). Y hay múltiples implementaciones (como en cualquier interfaz).
Lo segundo que hay que saber es que ‘interpretado’ y ‘compilado’ son propiedades de una implementación, no de una interfaz.
Entonces, la pregunta no está realmente bien formada.

¿Python es interpretado o compilado? La pregunta no está realmente bien formada.

Dicho esto, para la implementación más común (CPython: escrito en C, usualmente llamado simplemente ‘Python’, y seguramente lo que estás usando si no tienes idea de lo que estoy hablando), la respuesta es: interpretado, con algunas partes compiladas. CPython compila** el código fuente de Python a *bytecode, y en ese momento interpreta ese bytecode, ejecutándolo sobre la marcha.
* Nota: no es una ‘compilación’ en sentido tradicional de la palabra. Normalmente, decimos que ‘compilar’ es tomar el código de alto nivel y convertirlo en código binario. Pero es un tipo de ‘compilación’.
Veamos la respuesta un poco más de cerca, ya que nos permitirá entender algunos de los conceptos que surgirán más adelante en el artículo.

Bytecode vs. código binario

Es muy importante entender la diferencia entre bytecode y código binario (o nativo), tal vez mejor ilustrada con ejemplos:
  • C compila a código binario, que luego es ejecutado directamente en tu procesador. Cada instrucción le indica a tu CPU que mueva cosas alrededor.
  • Java compila a bytecode, que luego es ejecutado en la máquina virtual de Java(Java Virtual Machine, ó JVM), una abstracción de una computadora que ejecuta programas. Cada instrucción es entonces manejada por la JVM, que interactúa con tu computadora.
En términos breves: código binario es más rápido, pero bytecode es más portable y seguro.
El código binario se ve distinto, dependiendo de tu máquina, pero bytecode se ve igual en todas las maquinas. Se podría decir que el código binario está optimizado para tu configuracion.
Volviendo a CPython, el proceso en el conjunto de herramientas sucede de la siguiente manera:
  1. CPython compila tu código Python a bytecode
  2. Ese bytecode es entonces ejecutado en la Máquina Virtual CPython

 

Maquinas virtuales alternativas: Jython, IronPython, y más

Cómo mencioné anteriormente, Python tiene varias implementaciones. De vuelta, como mencioné antes, la más común es CPython. Ésta es una implementación de Python escrita en C y es considerada la implementación ‘por defecto’.
¿Pero, qué pasa con las alternativas? Una de las más prominentes es Jython, una implementación en Java que utiliza la JVM. Mientras CPython produce bytecode para ser corrido en la VM de CPython, Jython produce bytecode de Java para correr en la JVM (esto es lo mismo que es producido cuando se compila un programa en Java).
 

“¿Por qué usaría alguna vez una implementación alternativa?”, podrías preguntar. Bueno, para empezar, esas diferentes implementaciones juegan muy bien con diferentes conjuntos de tecnologías.
CPython hace muy fácil el escribir extensiones C para tu código Python porque al final es ejecutado por un intérprete de C. Por otro lado, Jython, facilita trabajar con otros programas en Java: puedes importar cualquier clase de Java sin mayor esfuerzo, evocando y utilizando tus clases Java dentro tus programas Jython. (Nota aparte: si no pensaste en esto detalladamente, es una locura. Estamos en un punto donde puedes mezclar y triturar diferentes lenguajes y compilarlos todos en una misma esencia. Como fue mencionado por Rostin, los programas que mezclan código Fortran y C están desde hace un tiempo. Así que, por supuesto que esto no es algo necesariamente nuevo. Pero sigue siendo genial.)
Cómo ejemplo, esto es código Jython válido:
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_51
>>> from java.util import HashSet
>>> s = HashSet(5)
>>> s.add("Foo")
>>> s.add("Bar")
>>> s
[Foo, Bar]
IronPython es otra implementación popular de Python, escrita enteramente en C# y apuntando a la tecnología .NET. En particular, corre con lo que se podría llamar la Máquina Virtual .NET,Common Language Runtime (CLR)de Microsoft, comparable con la JVM.
Podrías decir que Jython : Java :: IronPython : C#. Corren en sus respectivas VMs, puedes importar clases C# en tu código IronPython y clases Java desde tu código Jython, etc.
Es totalmente posible sobrevivir sin tocar alguna vez una implementación de Python no-CPython. Pero hay ventajas que se obtienen desde el cambio, muchas de ellas son dependientes de la tecnología que uses. ¿Usas muchos lenguajes basados en la JVM? Jython puede ser para tí. ¿Todo lo que haces es sobre la tecnología .NET? Tal vez debas probar IronPython (y tal vez ya lo hayas hecho).
Por cierto: mientras que esto no sería una razón para usar una implementación diferente, nota que estas implementaciones sí difieren en comportamiento más allá de como tratan tu código fuente en Python. Sin embargo, esas diferencias son comúnmente menores, y se disuelven o emergen con el tiempo mientras estas implementaciones se encuentran bajo un activo desarrollo. Por ejemplo, IronPython usa cadenas Unicode por defecto; Sin embargo, CPython, por defecto usa ASCII para versiones 2.x (fallando con un error de codificación UnicodeEncodeError para caracteres no-ASCII), pero sí soporta cadenas Unicode por defecto para las versiones 3.x.

Compilación Justo-a-Tiempo: PyPy y el futuro

Por lo tanto, tenemos una implementación de Python escrita en C, una en Java una en C#. El próximo paso lógico: una implementación de Python escrita en… Python. (El lector educado encontrará esta notación levemente engañosa).
Aquí es donde las cosas se ponen confusas. Primero, discutamos sobre compilación Justo-a-Tiempo (Just-in-Time, ó JIT).

JIT: El por qué y el cómo

Recordemos que el código binario es mucho más rápido que bytecode. Bueno, ¿y si pudiéramos compilar algunas partes de nuestro bytecode y luego correrlo como código nativo? Tendríamos que pagar algún precio al compilar a bytecode (por ej., tiempo), pero si el resultado fuese más rápido, eso sería genial! Esa es la motivación de la compilación JIT, una técnica híbrida que mezcla los beneficios de los interpretadores y los compiladores. En términos básicos, JIT quiere utilizar compilación para acelerar un sistema interpretado.
Por ejemplo, un enfoque común tomado por la compilación JIT:
  1. Identificar bytecode que es ejecutado frecuentemente.
  2. Compilar a código binario.
  3. Almacenar el resultado en memoria caché.
  4. Siempre que el mismo bytecode sea encontrado para ejecutar, en vez de usarlo, ejecutar el código binario precompilado y cosechar los beneficios (por ej., aumentos de velocidad)
De esto se trata PyPy: llevar JIT a Python (mira el Apéndice para ver esfuerzos anteriores). Hay, por supuesto, otros objetivos: PyPy apunta a ser multiplataforma, bajo en consumo de memoria e independiente del conjunto de tecnologías. Pero JIT realmente se vende por si solo. Como promedio de un puñado de pruebas de tiempo, se dice que mejora el rendimiento a un factor de 6.27. Para un mayor análisis, véase este cuadro del PyPy Speed Center:

PyPy es difícil de entender

PyPy tiene un gran potencial, y a estas alturas es muy compatible con CPython (así que puede correr Flask, Django, etc.).
Pero hay mucha confusión alrededor de PyPy (véase, por ejemplo, esta propuesta sin sentido para crear un PyPyPy…). En mi opinión, eso es principalmente porque PyPy es actualmente dos cosas:
  1. Un intérprete de Python escrito en RPython (no Python (he mentido antes). RPython es un subconjunto de Python con tipos estáticos. En Python, es “prácticamente imposible” razonar rigurosamente acerca de tipos (¿Por que es tan difícil? Bueno, considera el hecho que:
     x = random.choice([1, "foo"])
    
    sería código Python válido (créditos a Ademan). ¿De qué tipo es x? ¿Cómo podemos razonar acerca de tipos de variables cuando los tipos ni siquiera son estrictamente forzados?). Con RPython, sacrificas algo de flexibilidad, pero a cambio es muchísimo más fácil razonar sobre manejo de memoria y demás, lo cual permite optimizaciones.
  2. Un compilador que compila código RPython para varios objetivos y agrega JIT. La plataforma por defecto es C, por ej., un compilador RPython-a-C, pero también puedes apuntar a JVM y otros.
Únicamente para mayor claridad, me referiré a ellos como PyPy (1) y PyPy (2).
¿Por qué necesitarías esas dos cosas, y por qué bajo el mismo techo? Piénsalo de esta manera: PyPy(1) es un intérprete escrito en RPython. Entonces toma el código Python del usuario y lo compila a bytecode. Pero el interpretador en sí (escrito en RPython) tiene que ser interpretado por otra implementación de Python para poder correr, ¿Verdad?
Bueno, podríamos simplemente usar CPython para correr el intérprete. Pero eso no sería lo suficientemente rápido.
En cambio, la idea es que usemos PyPy(2) (también conocido cómo RPython Toolchain)-Set de herramientas RPython) para compilar al interpretador de PyPy a código que otra plataforma (por ej., C, JVM o CLI) pueda correr en nuestra máquina, agregando también JIT. Es mágico: PyPy agrega dinámicamente JIT a un interpretador, generando su propio compilador! (De vuelta, esto es una locura: estamos compilando un interpretador y agregando otro compilador independiente por separado).
Al final, el resultado es un ejecutable independiente que interpreta el código fuente Python y explota las optimizaciones de JIT. Que es lo que justamente queríamos! Es un gran bocado, pero tal vez este diagrama ayude:

Reiterando, la verdadera belleza de PyPy es que podemos escribir nosotros mismos un puñado de interpretadores Python distintos en RPython sin preocuparnos por JIT (salvo algunas sugerencias). PyPy entonces implementaría JIT por nosotros usando el set de herramientas de RPython/PyPy(2).
De hecho, si nos ponemos aún más abstractos, podrías, teóricamente, escribir un interpretador para cualquier lenguaje, alimentar a PyPy con él, y obtener un JIT para ese lenguaje. Esto es porque PyPy se enfoca en optimizar el interpretador actual, en vez de los detalles del lenguaje que está interpretando.

Podrías, teóricamente, escribir un interpretador para *cualquier* lenguaje, alimentar a PyPy con él, y obtener un JIT para ese lenguaje.

Divagando un poco, me gustaría mencionar que JIT en sí mismo es absolutamente fascinante. Usa una técnica llamada tracing (ó seguimiento), la cual se ejecuta de la siguiente manera:
  1. Correr el interpretador e interpretar todo (sin agregar nada de JIT)
  2. Perfilar levemente el código interpretado.
  3. Identificar operaciones que hayas realizado antes.
  4. Compilar esos pedazos a código binario.
Para más información, este documento es altamente accesible y muy interesante.
Para ir concluyendo: usamos el compilador RPython-a-C de PyPy (u otra plataforma) para compilar el interpretador implementado RPython de PyPy.

Concluyendo

¿Por qué es tan genial? ¿Por qué vale la pena perseguir esta idea tan loca? Creo que Alex Gaynor lo describió muy bien en su blog: “[PyPy es el futuro] porque ofrece mejor velocidad, más flexibilidad y es una mejor plataforma para el crecimiento de Python.”
En resumen:

Apéndice: Otros nombres que tal vez hayas oído

  • Python 3000 (Py3k): nombre alternativo para Python 3.0, un mayor, compatible-con-versiones-anteriores lanzamiento de Python que alcanzó la escena en 2008. El equipo de Py3k predijo que llevaría alrededor de cinco anos para que esta versión sea completamente adoptada. Y mientras que la mayoría (cuidado: se dice que es anecdótico) de los desarrolladores de Python siguen usando Python 2.x, la conciencia de Py3k entre la gente está incrementándose.
  • Cython: un super set de Python que incluye bindings (ó enlaces)para llamar funciones de C.
    • Objetivo: permitirte escribir extensiones en C para tu código Python
    • Además te permite agregar tipos de variables estáticos a tu código Python, permitiéndole que sea compilado y alcanzar rendimiento parecido al de C.
    • Es similar a PyPy, pero no es lo mismo. En este caso, estás forzado a escribir el código del usuario antes de pasarlo al compilador. Con PyPy, escribes simplemente código Python, y el compilador maneja cualquier optimización.
  • Numba: : un “compilador especializado justo-a-tiempo” que agrega JIT a código Python anotado. En términos más básicos, le das algunas indicaciones y acelera partes de tu código. Numa viene como parte de la distribución Anaconda,un set de paquetes para manejo y análisis de datos.
  • IPython: muy diferente a todo lo que hemos discutido hasta ahora. Es un ambiente de procesamiento para Python. Interactivo y con soporte para herramientas gráficas y experiencia de navegador, etc.
Enlaces de lenguaje
  • RubyPython: un puente entre las máquinas virtuales de Ruby y Python. Permite embeber código de Python dentro de tu código de Ruby. Defines donde Python comienza y termina, y RubyPython calcula los datos entre las VMs.
  • PyObjc: enlaces de lenguaje entre Python y Objetive-C, actuando como un puente entre ellos. Prácticamente, eso significa que puedes utilizar librerías de Objective-C (incluyendo todo lo que necesitas para crear aplicaciones de OS X) desde tu código Python, y módulos de Python desde tu código Objective-C. En este caso, es conveniente que CPython esté escrito en C, el cual es un subconjunto de Objective-C.
  • PyQt: mientras PyObjc te ofrece una interfaz para los componentes gráficos de OS X, PyQt hace lo mismo para el framework de QT, permitiendote crear completas interfaces gráficas, acceso a bases de datos SQL, etc. Otra herramienta dirigida a traer la simplicidad de Python a otros frameworks.
Frameworks JavaScript
  • pyjs (Pyjamas): un framework para crear aplicaciones web y de escritorio en Python. Incluye un compilador Python-a-Javascript, un conjunto de widgets, y algunas herramientas más.
  • Brython: una máquina virtual de Python escrita en JavaScript para permitir que el código de Py3k sea ejecutado en navegadores.
Este artículo fue tomado de Toptal https://www.toptal.com/python/por-que-hay-tantos-pythons/es














































lunes, 15 de agosto de 2016

Desarrollo en Capas (Asp.NET)


El día de hoy empiezo con este tema de desarrollo de aplicaciones en capas; para iniciar esta serie de articulos debemos tener estos puntos a considerar:
  1. Se utilizará Visual Studio 2013
  2. Se utilizará el lenguaje C# (aunque tambien se puede aplicar a Vb.NET)
  3. Se utilizará la versión 6 de Entity Framework
Para este artículo, lo primero que haremos es generar nuestro modelo de Datos *.edmx con Entity Framework (más información aquí). como habia mencionado antes, voy a utilizar Entity Framework 6, puesto que este framework (en comparación con versiones anteriores) viene cargado de nuevas características y mejoras; algunas a nivel de código y otras a nivel de rendimiento (más información aquí)..
La siguiente imagen, muestra como quedaría nuestro proyecto al final de la implementación y la comunicación que cada una de las capas tendrán entre si. La ventaja de realizar esta división será en mayor parte la reutilización de código, mejor rendimiento de la aplicación entre otros.
image
Para el ejemplo voy a utilizar una Base de Datos (BD) “Trabajador” la cual contiene las siguientes tablas:
image
Para empezar crearemos una Solución en blanco para despues añadir un nuevo proyecto de tipo Biblioteca de Clases al cual lo vamos a nombrar AccesoDatos y vamos a eliminar la clase que se genera por defecto; al final tendremos nuestra aplicación de esta manera:
image
Ahora vamos a generar nuestro modelo desde la base de datos; para ello damos clic derecho en el proyecto vamos a Agregar->Nuevo Elemento (Ctrl+Mayús.+A)
image
Una vez seleccionado, nos muestra una ventana con el asistente para Entity Data Model, en mi caso optaré por Generar desde la base de datos, ya que previamente he creado mi BD.
image
Ahora especificamos la cadena de conexión para la BD
image
Ahora escogemos la versión de Entity Framework que deseamos utilizar:
image
Ahora vamos a seleccionar las tablas que queremos incluir en el modelo
image
Al dar clic en finalizar, podremos ver nuestro diagrama de la BD y es momento de verificar que se haya generado el archivo *.tt ya que es ahi donde se encuentran las clases separadas por cada tabla.
image
image
Ahora vamos a añadir un nuevo proyecto del tipo biblioteca de clases al cual lo vamos a nombrar Entidades y lo que haremos es mover la plantilla ModeloTrabajador.tt hacia este proyecto. Para poder realizar este procedimiento, tendre que dirigirme a la carpeta donde se encuentra el Proyecto AccesoDatos y moveré todos los elementos que son parte de la plantilla ModeloTrabajador.tt hacia la carpeta donde se encuentra en proyecto Entidades
image
Actualizamos el proyecto dando clic en el botón actualizar en el Explorador de Soluciones (image). En este punto en el proyecto se nos mostrará la plantilla ModeloTrabajador.tt con una marca de color amarillo; esto nos está indicando que VS no pudo encontrar los archivos en la ruta, esto es normal.
Ahora vamos al proyecto Entidades y damos clic en Mostrar todos los archivos en el Explorador de Soluciones (image). Ahora el proyecto debe verse de la siguiente manera:
image
Eliminamos los archivos en ModeloTrabajador.tt e incluimos los archivos que movimos al proyecto Entidades; damos doble clic en la plantilla ModeloTrabajador.tt en el proyecto Entidades.
Como hemos movido la plantilla a un proyecto diferente, debemos configurar la línea que esta apuntando al modelo *.edmx, buscamos la ruta string inputFile para que apunte hacia el modelo que se encuentra en el proyecto AccesoDatos
image
Al grabar las clases que representan a las tablas volverán a quedar dentro de la plantilla ModeloTrabajador.tt
image
Ahora, vamos a regresar al proyecto AccesoDatos, y cambiaremos el espacio de nombres de la plantilla ModeloTrabajador.Context.tt y ModeloTrabajador.Context.cs, ya que, las entidades ahora se encuentran en el proyecto Entidades, abrimos la ventana de propiedades (F4 sobre la plantilla) de la plantilla ModeloTrabajador.Context.tt y establecemos el espacio de nombres en Entidades (realizamos los mismos pasos para ModeloTrabajador.Context.cs).
image
Ahora para que el proyecto AccesoDatos pueda comunicarse con el proyecto Entidades tenemos que agregar una referencia del proyecto Entidades hacia el proyecto AccesoDatos. Damos clic derecho en References y damos clic en Agregar Referencia. Vamos al apartado Solución->Proyectos y selecionamos Entidades.
image
Y esta sería la parte final de esta parte del proyecto, hasta el momento hemos creado el modelo de nuestra base de datos, el contexto y las clases de entidad; separamos las entidades en un proyecto diferente para que estas puedan ser usadas en todas las capas de acuerdo a la estructura presentada.
En los próximos días continuaré con el código que tendrá la capa de Acceso a Datos.
Descargar proyecto

miércoles, 3 de agosto de 2016

Incluir código en tu post de blogger


Cuando quieres escribir un post que incluye ciertos fragmentos de código, si bien es cierto, sabes acerca de html (o deberías saberlo),; pero en mi caso busco lo mas rápido posible de utilizar. Hace unos años atrás (no recuerdo fechas exactas) Microsoft puso en nuestras manos una herramienta extraordinaria (criterio personal Winking smile) ; Windows Live Writer era un editor de blog muy completo; incluso tenia algunos plugins que se podían aplicar.

El problema radica cuando, se descontinuó en el mercado; en ese momento y al haber formateado mi computador con W10 no tenia manera de tener la misma facilidad con otras herramientas para que los fragmentos de código se muestren diferentes al formato “standard” del blog.

Por suerte, trasteando un poco por el codigo html del blog; encontre una solución práctica para realizar este proceso; a continuación los pasos:

Encontrar la plantilla

El primer paso para realizar este proceso es buscar la plantilla que queremos editar en blogger, en mi caso escogeré este blog dando clic en el nombre para que se muestre todas las opciones que se pueden manejar.

image

En lap arte izquierda iré a buscar la opción de “Plantilla” y despues dando clic en “Editar Html” que se encuentra bajo el recuadro de la vista previa del blog.

image

Editar el HTML

Una vez que hemos dado clic en el botón Editar HTML nos abrira una serie de código html; debemos buscar (CTRL+F) ]]></b:skin>

una vez encontrado esto debemos insertar el siguiente codigo antes code{
   background:#FFFFFF;
   font-family: Courier New;
   display:block;
   border:1px solid #999999;
   padding:10px;
}

En mi caso el resultado final quedo de esta forma body.mobile .AdSense {
   margin: 0 -10px;
}
code {
   background:#FFFFFF;
   font-family: Courier New;
   display:block;
   border:1px solid #999999;
   padding:10px;
}
]]></b:skin>

Guardamos los cambios en la plantilla y eso sería todo.

Utilizando el codigo

Ahora, al momento que queramos incluir un codigo en el blog; solo debemos rodearlos con el tag <code></code> y eso sería todo, el resultado final lo pueden ver en las lineas de este post.

Saber la fecha de modificacion de un objeto (SQL Server)


El día de hoy estuve revisando unos procedimientos almacenados que se encuentran en mibase de Datos debido a un error en los registros en las tablas, vi que el error fue corregido en el procedimiento almacenado; pero, el inconveniente era que necesitaba saber en que fecha se realizo la correcion del error para compararlo con la fecha de los registros y poder identificar si existía un error adicional.

Para i suerte recordé, que se puede saber esta informacion con una “herramienta” integrada en SQL, se trata de sys.all_objects (Mas informacion aquí) el cual nos puede entregar esa información y algunas otras mas; en mi caso lo unico que necesitaba era la fecha de creacion y la de modificacion. Mi consulta quedo de esta manera:

SELECT
   [name],
   [object_id],
   [create_date],
   [modify_date]
FROM sys.all_objects
WHERE [type] = 'P'
AND [object_id] > 0
AND [name] like '%sp_cons%'
ORDER BY [modify_date] DESC

De esta consulta podemos destacar lo que colocamos en la cláusula WHERE, he puesto como condicion: [type] = 'P' lo que hace esto es definirme el tipo de objeto que quiero; en mi caso Procedimiento Almacenado.

En este link se puede encontrar el listado de todos los tipos que existen, en esta lista también pueden encontrarlos:

type char(2) Tipo de Objeto
    AF = Función de agregado (CLR)
    C = Restricción CHECK
    D = DEFAULT (restricción o independiente)
    F = Restricción FOREIGN KEY
    FN = Función escalar de SQL
    FS = Función escalar del ensamblado (CLR)
    FT = Función con valores de tabla de ensamblado (CLR)
    IF = Función SQL insertada con valores de tabla
    IT = Tabla interna
    P = Procedimiento almacenado de SQL
    PC = Procedimiento almacenado del ensamblado (CLR)
    PG = Guía de plan
    PK = Restricción PRIMARY KEY
    R = Regla (estilo antiguo, independiente)
    RF = Procedimiento de filtro de replicación
    S = Tabla base del sistema
    SN = Sinónimo
    SQ = Cola de servicio
    TA = Desencadenador DML del ensamblado (CLR)
    TF = Función con valores de tabla SQL
    TR = Desencadenador DML de SQL
    TT = Tipo de tabla
    U = Tabla (definida por el usuario)
    UQ = Restricción UNIQUE
    V = Vista
    X = Procedimiento almacenado extendido