C#: Bosquejo de un ActiveRecord con Insert y Select

•11 Junio 2009 • Dejar un comentario

Aburrido en una noche de primavera comence a escribir un pequeño programa que era el bosquejo básico pero bien básico un ActiveRecord llegando sólo a implementar las funciones Insert y Select, aun tengo pendiente las funciones Update y Delete.

Este código se conecta a un base de datos Postgres a la tabla test con los campos id, nombre, apellidos y edad, primero inserta y luego lista el dato ingresado.

Antes de probar el código, deben crear la tabla y las columnas en minuscula.

Program.cs


using System;
using System.Collections.Generic; 

namespace MiActiveRecord
{
 public class Program
 {
 static void Main(string[] args)
 {
 Test test = new Test() {Nombre="Alexis", Apellidos="Nuñez Riquelme"}; 

 test.Save(); 

 IList<Test> tests = Test.GetAll(); 

 foreach (Test item in tests)
 {
 Console.WriteLine("{0,2} - {1, 10} - {2, 15} - {3, 2}", item.Id, item.Nombre, item.Apellidos, item.Edad);
 }
 } 

 public class Test : Base<Test>
 {
 public string Nombre { get ; set; } 

 public string Apellidos { get; set; } 

 public int? Edad { get; set; }
 }
 }
}

Base.cs


using System;
using System.Collections.Generic;
using System.Configuration;
using System.Reflection;
using System.Text;
using Npgsql; 

namespace MiActiveRecord
{
 public class Base<T> : BaseSQL<T>
 {
 public long Id { get; set; } 

 public static IList<T> GetAll()
 {
 IList<T> lst = new List<T>(); 

 using (NpgsqlConnection sqlCnn = new NpgsqlConnection("User ID=postgres; Password=postgres; Host=localhost; Port=5432; Database=MiActiveRecord"))
 {
 sqlCnn.Open(); 

 StringBuilder sql = GetSelect(); 

 NpgsqlDataReader reader = new NpgsqlCommand(sql.ToString(), sqlCnn).ExecuteReader(); 

 while (reader.Read())
 {
 T item = (T)typeof(T).Assembly.CreateInstance(typeof(T).FullName); 

 (item as Base<T>).LoadValues(reader); 

 lst.Add(item);
 } 

 reader.Close();
 sqlCnn.Close();
 } 

 return lst;
 } 

 public void LoadValues(NpgsqlDataReader reader)
 {
 for (int i = 0; i < reader.FieldCount; i++)
 {
 foreach (PropertyInfo property in (this).GetType().GetProperties())
 {
 if (property.Name.ToUpper() == reader.GetName(i).ToUpper())
 {
 if (reader[reader.GetName(i).ToUpper()] is DBNull)
 property.SetValue(this, null, null);
 else
 property.SetValue(this, reader[reader.GetName(i).ToUpper()], null); 

 break;
 }
 }
 }
 } 

 public void Save()
 {
 using (NpgsqlConnection sqlCnn = new NpgsqlConnection("User ID=postgres; Password=postgres; Host=localhost; Port=5432; Database=MiActiveRecord"))
 {
 StringBuilder strSQL = GetInsert(); 

 sqlCnn.Open(); 

 NpgsqlCommand sqlcmd = new NpgsqlCommand(strSQL.ToString(), sqlCnn); 

 sqlcmd.ExecuteNonQuery(); 

 sqlCnn.Close();
 }
 }
 }
}

BaseSQL.cs


using System.Text;
using System.Reflection;
using System.Collections.Generic;
using System; 

namespace MiActiveRecord
{
 public class BaseSQL<T>
 {
 internal StringBuilder GetInsert()
 {
 StringBuilder sql = new StringBuilder("INSERT INTO ")
 .AppendFormat("{0} (", this.GetType().Name); 

 foreach (PropertyInfo property in Base<T>.GetProperties(this.GetType(), true))
 {
 if (property.GetValue(this, null) != null)
 sql.AppendFormat("{0}, ", property.Name);
 } 

 sql.Remove(sql.Length - 2, 2); 

 sql.Append(") VALUES ("); 

 foreach (PropertyInfo property in Base<T>.GetProperties(this.GetType(), true))
 {
 if (property.GetValue(this, null) != null)
 {
 if (property.PropertyType == typeof(string) || property.PropertyType == typeof(char))
 sql.AppendFormat("'{0}', ", property.GetValue(this, null));
 else
 sql.AppendFormat("{0}, ", property.GetValue(this, null));
 }
 } 

 sql.Remove(sql.Length - 2, 2); 

 sql.Append(")"); 

 return sql;
 } 

 internal static StringBuilder GetSelect()
 {
 StringBuilder sql = new StringBuilder("SELECT "); 

 foreach (PropertyInfo property in Base<T>.GetProperties(typeof(T), false))
 {
 sql.AppendFormat("{0}, ", property.Name);
 } 

 sql.Remove(sql.Length - 2, 2); 

 sql.AppendFormat(" FROM {0}", typeof(T).Name);
 return sql;
 } 

 private static IList<PropertyInfo> GetProperties(Type type, bool skipBase)
 {
 IList<PropertyInfo> properties = new List<PropertyInfo>(); 

 bool exist; 

 foreach (PropertyInfo proItem in type.GetProperties())
 {
 exist = false; 

 if (skipBase)
 {
 foreach (PropertyInfo proBase in typeof(Base<T>).GetProperties())
 {
 if (proBase.Name == proItem.Name)
 {
 exist = true;
 break;
 }
 }
 } 

 if (!exist)
 properties.Add(proItem);
 } 

 return properties;
 }
 }
}

C#: Añandiendo descripciones a un Enum

•24 Enero 2009 • 2 comentarios

Este código muy simple y nos permite añadir descripciones a nuestros Enum:

using System;  
using System.Reflection;  

namespace Enum  
{  
class Program  
{  
static void Main(string[] args)  
{  
Console.WriteLine(EnumDes.Descripcion(Navegadores.Firefox));
Console.WriteLine(EnumDes.Nombre(“Mozilla Firefox”));

Navegadores valor = (Navegadores)EnumDes.Valor(“Mozilla Firefox”);

if (valor == Navegadores.Firefox)
{
Console.WriteLine(“Es Firefox… :) “);
}
}  
}  

public enum Navegadores  
{  
[EnumDes("Mozilla Firefox")]  
Firefox,  
[EnumDes("Opera Browser")]  
Opera  
}  

// Esta clase se crea como Atributo para insentar descripciones en cualquier enum  
public class EnumDes : Attribute  
{  
private string _descripcion;  

// Constructor  
public EnumDes(string descripcion)  
{  
_descripcion = descripcion;  
}  

// Este método recupera la descripción del enum utilizando Reflection.  
public static string Descripcion(T _enum)  
{  
FieldInfo info = typeof(T).GetField(_enum.ToString(), BindingFlags.Public |  
BindingFlags.Static);  

foreach (object obj in info.GetCustomAttributes(false))
{
if (obj.GetType() == typeof(EnumDes))
{
return obj.ToString();
}
}

return “No se encontró la descripción”;  
}

public static FieldInfo Buscar(string descripcion)
{
FieldInfo[] infos = typeof(T).GetFields(BindingFlags.Public |
BindingFlags.Static);

foreach (FieldInfo item in infos)
{
foreach (object attribute in item.GetCustomAttributes(false))
{
if (attribute.ToString() == descripcion)
{
return item;
}
}
}

return null;
}

public static string Nombre(string descripcion)
{
FieldInfo info = Buscar(descripcion);

return (info == null ? “No se encontró el valor” : info.Name);
}

public static object Valor(string descripcion)
{
FieldInfo info = Buscar(descripcion);

return (info == null ? null : info.GetValue(typeof(T)));
}

/* Se sobrescribe el método ToString() para retornar la descripción
* ingresada a través de su constructor.
*/  
public override string ToString()  
{  
return _descripcion;  
}  
}  
}

Cuando no aceptar un Proyecto

•24 Enero 2009 • Dejar un comentario

En mi poca experiencia como desarrollador puedo rescatar algunos puntos que uno debe analizar para no aceptar un proyecto:

  1. Es la herencia de alguien más (Persona o Empresa), si es la herencia de otra empresa atente a las consecuencias.
  2. El sistema tiene un framework propietario/cerrado con nula documentación. Peor es si el framework pertenece a la empresa que anteriormente desarrollaba el proyecto.
  3. El sistema no tiene documentación/auto-documentación.
  4. El sistema tiene abundante código spaguetti.
  5. No tengas contacto con la persona o empresa que desarrollaba el proyecto.
  6. O si tienes contacto no sepan lo que hicieron.
  7. El proyecto venga con el regalo de un Jefe de Proyecto y/o Analista(s) incompetente(s).
  8. Al aceptar el proyecto puedas quedar amarrado eternamente a este.

Python: Mi propia versión de Mario Bros.

•22 Enero 2009 • Dejar un comentario

Quede con gusto a poco después de realizar mi primer juego en python y pygame, así pasaron varias semanas hasta que navegando por Internet me entere que alguien había desarrollado un Mario Bros. en javascript, el cuál lo había encontrado genial, con este hecho encontré mi inspiración para crear mi propia versión de Mario Bros.

Durante 3 semanas me dedique a programar mi propia versión. Obtuve los sprites desde Internet y con lo aprendido programando mi primer juego empece mi odisea.

Al finalizar las 3 semanas pude realizar lo siguiente:

  1. Crear una parte del primer nivel.
  2. Añadir un tipo de enemigo.
  3. Logre mover el fondo, lo cuál me costo mucho trabajo.
  4. Realizar los movimientos de Mario.
  5. Lograr que Mario aplaste a su enemigo
  6. Hacer que Mario interactue con su ambiente.

No es mucho lo que pude hacer pero trabajando sólo de noche y cansado. Bueno acá les dejo una imagen de como quedo el juego y un enlace con los fuentes.

Mario Bros. en Python

Fuente Mario Bros.

P.D.: Si tienen algún problema para descar el código fuente me avisan.

Python: Mi primer juego

•19 Enero 2009 • Dejar un comentario

Mi primer acercamiento a la informática fue hace unos 17 años aproximadamente, en esa época sólo tenía un computador atari con el Basic como lenguaje de programación. Lo único que me interesaba más que jugar con los juegos que tenía era programar mis propios juegos, pasaba días enteros programando mis juegos, mientras soñaba con trabajar como programador de juegos, pero la realidad fue otra y termine haciendo aburridos sistemas para empresas.  :(

Pero no fue hasta hace unos meses atrás que empece a interesarme en Python y toda su filosofía de vida, y leyendo algunos blogs mostraban la simplicidad que tenia el lenguaje para desarrollar juegos, sólo debía instalar la librería pygame y manos a la obra.

Así que le dedique varias noches a programar mi primer juego y al cabo de 2 semanas ya lo tenía armado. Es un  simple juego de naves donde uno se puede mover por toda la pantalla disparando y tratando de matar a las naves enemigas mientras van apareciendo desde arriba de la pantalla.

shipspace1

Si lo quieren probar acá les dejo el código fuente comprimido.

ShipSpace.rar

C#: Ordenando una lista genérica

•19 Enero 2009 • Dejar un comentario

El siguiente código muestra el ordenamiento de una lista generica, siendo necesario que los objetos implementen la interfaz Icomparable.

using System;
using System.Collections.Generic;

namespace nitrogeno
{
class Program
{
static void Main(string[] args)
{
IList list1 = new List();

list1.Add(“Casa”); // 1
list1.Add(“Auto”); // 2
list1.Add(“Arbol”); // 3
list1.Add(“Sapo”); // 4
list1.Add(“Nuevo”); // 5

SortList.Bubble(list1);

foreach (string item in list1)
Console.WriteLine(“{0}”, item);

Console.WriteLine();

IList list2 = new List();

list2.Add(5); // 1
list2.Add(2); // 2
list2.Add(3); // 3
list2.Add(1); // 4
list2.Add(4); // 5

SortList.Bubble(list2);

foreach (int item in list2)
Console.WriteLine(“{0}”, item);
}
}

public class SortList
{
public static IList Bubble(IList list) where T : IComparable
{
T tmp;

for (int i = 0; i < list.Count; i++)
{
for (int x = 0; x < list.Count - (i + 1); x++)
{
if (list[x].CompareTo(list[x + 1]) > 0)
{
tmp = list[x + 1];
list[x + 1] = list[x];
list[x] = tmp;
}
}
}

return list;
}
}
}

C#: Árbol Binario Genérico

•19 Enero 2009 • Dejar un comentario

Este árbol binario lo desarrolle en un momento de aburrimiento  en el trabajo y nunca lo temine, por eso me faltó implementar el método eliminar, asi que espero añadirlo en un futuro próximo.

Lo interesante de este código es que permite utilizar los tipos de datos char, string, datetime, int, decimal, o cual  otro objeto que tenga implementado la interfaz Icomparable. Porque el árbol binario hace uso del método CompareTo de la interfaz Icomparable, para ir comparando el nuevo nodo con los nodos existentes y asi saber que camino debe tomar.

using System.Collections.Generic;

namespace ArbolBinarioGenerico
{
class Program
{
static void Main(string[] args)
{
ArbolBinario arbol = new ArbolBinario(8); // 1

arbol.Insertar(ref arbol, 7); // 2
arbol.Insertar(ref arbol, 5); // 3
arbol.Insertar(ref arbol, 3); // 4
arbol.Insertar(ref arbol, 4); // 5
arbol.Insertar(ref arbol, 0); // 6
arbol.Insertar(ref arbol, 2); // 7
arbol.Insertar(ref arbol, 6); // 8
arbol.Insertar(ref arbol, 9); // 9
arbol.Insertar(ref arbol, 1); // 10

foreach(int valor in arbol.Listar(arbol, new List()))
Console.WriteLine(valor);
}
}

public class ArbolBinario where T : IComparable
{
private T valor;
private ArbolBinario nodoIzq = null; // nodo derecho
private ArbolBinario nodoDer = null; // nodo izquierdo

public ArbolBinario(T valor) // constructor
{
this.valor = valor;
}

public void Insertar(ref ArbolBinario nodo, T valor)
{
if (nodo == null)
nodo = new ArbolBinario(valor);
else
{
if (nodo.valor.CompareTo(valor) > 0)
Insertar(ref nodo.nodoIzq, valor);
else
Insertar(ref nodo.nodoDer, valor);
}
}

public List Listar(ArbolBinario nodo, List arbol)
{
if (nodo.nodoIzq != null)
Listar(nodo.nodoIzq, arbol);

arbol.Add(nodo.valor);

if (nodo.nodoDer != null)
Listar(nodo.nodoDer, arbol);

return arbol;
}
}
}