jueves, 27 de diciembre de 2012

Nada en particular.

Hace ya poco más de un mes que comencé un proyecto Web personal, de esos en los que se suele invertir mucho y que seguramente nos dejara poca ganancia monetaria pero mucha, mucha intelectual, cuyo valor no es para nada despreciable.. :)

Comencé a hacer un juego de navegador. Siempre me llamaron la atención algunos juegos simples pero no por ello poco "enviciantes". Me preguntaba que es lo que habría detrás de esos juegos, que tanta estructura de personal y que tanto hardware sería necesario para hacer y mantener un juego on-line.
Por ahora el proyecto es unipersonal y lo vengo llevando bastante bien.. Creo que todo esta en el análisis y en saber hacia el lugar al que debe ir el proyecto.. Lo cual no se limita únicamente a los juegos, sino que es extensible a cualquier proyecto software.

Con este proyecto me estoy dando cuenta de algunas cosas bastante agradables. Por ejemplo:

  • Que no hace falta usar grandes framework para hacer un buen trabajo web con PHP. 
  • Que las formas de evitar los ataques de XSS, no son tan complejas como muchos nos quieren vender.
  • Y que se puede ser prolijo programando con PHP.. jeje

Si quieren que les di una mini receta para evitar los ataques de XSS, sería:


  1. Validar todos los datos de entrada, que puedan llegar a la Base de datos. Si son datos de tipo Entero, validar que nos hayan ingresado solo valores enteros. :).. con PHP asi como con la mayoria de lenguajes de programación de alto nivel, esto es muy sencillo y se resuelve en una sola linea.. 
  2. Si los campos que les pueden ingresar, son de tipo texto la validación es un poco mas complicada, porque siempre esta la posibilidad que nos quieran inyectar código si no dejamos controlados caracteres tales como las comillas simples (').
Si hacemos que a partir del ingreso de un formulario si ejecute algo similar a esto:

select * from tabla1 where nombreCampo = 'Valor ingresado desde el formulario';

estariamos dandole la posibilidad a algun usuario malicioso de ingresar en el formulario por ejemplo el valor.

' basura

Con lo cual fallaría la sentencia SQL si esto no esta controlado y quizas el error obtenido le daria pistas al usuario mal intencionado de obtener información acerca de la estructura de nuestra Base de datos que no queremos que sea pública.

Para hacer la validacion de campos de texto, lo que puedo recomendar es 

hacer la conexión con mysqli de la siguiente manera:

$conexion = new mysqli("<hostname>", nombreUsuario, password, nombreBaseDeDatos);

Esta forma de conexión nos brinca la posibilidad de utilizar las sentencias prepare y bind_param

Prepare sirve para "preparar" la consulta que luego querremos ejecutar en la base de datos, y nos permite dejar sin enlazar los parametros, son el uso de los signos de pregunta (?). 

$consulta=$conexion->prepare("insert into tabla
   (valorEntero1,  valorEntero2 , valorCadena,  valorEntero3) 
values 
(?, ?, ?, ?)");

Luego con la sentencia bind_param, bindeamos los signos de preguntas con los valores que le queremos pasar a la secuencia SQL. El primer parámetro de bind_param es una cadena con el formato de los parámetros que se insertaran a continuación. "iisi" significa que el primer parámetro es (i) (INTEGER), que el segundo parametro es (i) INTEGER que el tercer parámetros es (s) STRING y que el cuarto y último parámetro es (i) INTEGER. 
$res = $consulta->bind_param("iisi",$val1,$val2,$str1,$val3);
if($res){
$res = $consulta->execute();
        }

Con esto tendríamos validados los campos de tipo texto... Previo a hacer el binding, deberíamos comprobar que los valores integer, sean realmente enteros. Ya que en mi versión no se porque razón no falla cuando le envió cadena en los datos de tipo entero. :)



Bueno solo quería contar esa pequeña experiencia..
Supongo que seguiré comentando algunas cosas más de mi desarrollo en los dias subsiguiente..

sábado, 10 de noviembre de 2012

Framework Python

Bueno lo prometido es deuda.. :)..

Así que pasare a mostrar mi framework.

Básicamente es un framework que sirve para hacer aplicaciones de escritorio utilizando Python, hace uso de un ORM que es SqlAlchemy y para la parte de interfaz gráfica utiliza PyQT... Cabe aclararar que esta es una primera aproximacion a lo que realmente estoy buscando... por lo cual tiene varias cosas que pulir, y el que quiera colaborar puede hacerlo.. :)..

Por ahora tiene soporte solo para las Bases de Datos:

  • SQLite
  • MySQL
Pero es fecalmente extensible a PostgreSQL.

Es importante como dije en el vídeo seguir ciertas convensiones, la principal es que el nombre del archivo con el cual se guarda el Form, sea igual al nombre del objeto form.. :). el resto practica mente queda a gusto del usuario..

En cuanto a la definición del modelo, hay unas pocas palabras reservadas por el momento:

  • tabla:  # Especifica que se debe crear una nueva tabla, con el nombre que sigue a continuación de los dos puntos
  • campo: # Especifica el nombre del campo y su tipo.
  • ucamp: # Especifica que es el ultimo campo de la tabla.
Tener en cuentas que tabla, campo y ucamp SI O SI deben estar seguidas de dos puntos ":"

En cuanto a los tipos de datos tenemos:

  • entero: Tipo de dato entero. :)
  • cadena: Tipo de dato String. Debe seguir a continuación la longitud de la cadena, en caso que no se especifique la longitud, se toma por defecto 50 caracteres.
  • real. Tipo de dato Real.
Para comprender un poco mas el uso del Framework, recomiendo ver estos dos videitos, que espero se entiendan.. :).. Si no lo logran ver bien, ponganlo en pantalla completa y mejorenle la calidad a 480p y lo verán perfectamente.

Video 1

Video 2

Para descargar el Ejecutable para Windows, pueden hacerlo desde el siguiente Link:

Descargar PyFrame

Espero que les guste, y que les sirva.. Cualquier comentario o sugerencia sera bienvenido..

Saludos y hasta la próxima.. 

martes, 30 de octubre de 2012

Frameworks (Teoria)

Los Frameworks suelen definirse como "Marcos de Trabajo", esta seria la definición prácticamente literal de la palabra Framework. De todas formas si bien a alguno que se encuentra en el tema de la informática,puede llegar a brindarle alguna pista con respecto a lo que en realidad son, al común denominador de la gente la definición "Marco de Trabajo" nada le dice. 

Para que todos lo entendamos, podemos decir que un Framework, no es ni mas ni menos que un programa al cual le faltan porciones que nosotros podemos completarlas para conseguir algun objetivo particular.

Alguna definiciones un poco mas formales que pueden encontrarse en la web son:

________

"En lo que respecta al desarrollo de software, un Framework suele verse como una estructura de soporte bien definida, en la cual otro proyecto software puede ser organizado y desarrollado."
________

“Un framework se puede considerar como una aplicación genérica incompleta y configurable a la que podemos añadirle las últimas piezas para construir una aplicación concreta. Los objetivos principales que persigue un framework son: acelerar el proceso de desarrollo, reutilizar código ya existente y promover buenas prácticas de desarrollo como el uso de patrones.”

La experiencia nos dice que siempre que vamos a desarrollar una aplicación informática, tendemos a normalizar y estructurar los datos de forma tal que podamos modelarlos, para hacer mas sencillo el almacenamiento y la recuperación de estos. Por lo general esa información estructurada suele convertirse en modelos que luego terminan siendo la Base de Datos del sistema que estamos desarrollando. Sin embargo, cuando de estructurar los archivos propios de cada desarrollador se trata, entramos en una zona en la cual nada esta claro y todo queda librado al azar y a las buenas practicas del propio desarrollador. La estructura de directorios, los nombres y estructura de los códigos fuentes, y los nombres y estructuras de los archivos de configuración, son algunas de las cosas que quedan a la "buenas de dios", cuando comenzamos un desarrollo. 
En la mayoría de los casos, cuando se comienza un desarrollo, se suele pensar que luego de haber definido las herramientas (lenguaje de programación, y motor de base de datos), ya tenemos casi todo resuelto, pero esto esta muy alejado de la realidad; En ese momento es justamente donde aparece toda esa incertidumbre producida por la falta de normalizacion y de estructuración de los componentes propios del desarrollo. 
Para solventar esta problemática es que existen los frameworks, ya que los mismos nos brindan una estructura ya probada y satisfactoria para resolver problemas de cierto dominio concreto. 

Los objetivos principales que persiguen los Frameworks son: 

  1. Acelerar el proceso de desarrollo.
  2. Fomentar la reutilizacion de código, y promover buenas practicas de programación, como el uso de patrones. 
Digamos que ambos objetivos están bastante relacionados, ya que el proceso de desarrollo se acelera debido a que mediante la utilización de un framework, se suele tener mucha de la programación de bajo nivel resuelta, por lo cual podemos centrarnos en programar la lógica propia del desarrollo particular que estamos llevando a cabo. 
Habitualmente los frameworks están intrínsecamente relacionados con un lenguaje de programación, ya que de esta forma es que consiguen mayor potencial. Por lo general los frameworks que no están desarrollados para un lenguaje de programación en particular, suelen resolver cuestiones mucho mas sencillas y básicas que aquellos que si lo están. 

La utilización de un framework tiene como ventajas:
  1. Velocidad de desarrollo: 
  2. Código optimizado
  3. Reducción de costos
  4. Estadarizacion y Convención en el código
También trae consigo algunas desventajas como pueden ser:
  1. Tiempo de aprendizaje
  2. Dependencia
  3. Falsa sensación de conocer el lenguaje
Las ventajas "velocidad de desarrollo" y "reducción de costo", van un poco de la mano, ya que al mejorar la velocidad de desarrollo gracias a la reutilizacion de código, se puede reducir la cantidad de trabajo, lo que reduce el tiempo y que es lo que en definitiva disminuye los costos. 
La ventaja de código optimizado esta dada mas que nada por la comunidad que da soporte al framework, sobre todo en frameworks grandes como puede ser por ejemplo "Symphony" o "Django", las comunidades que están detrás de estos desarrollos son enormes, por lo cual permanentemente se les van haciendo actualizaciones y mejoras.
Estadarizacion y Convención en el código, si bien son dos cualidades que pueden conseguirse sin la necesidad de utilizar un framework, podemos decir que la utilización de uno, nos obliga en cierto punto a seguir algunos lineamientos a la hora de desarrollar, lo que produce que cualquiera que conozca el framework y tome nuestro desarrollo, ya sea para hacerle mantenimiento o para ampliarlo, lo comprenda. 

De todas formas no todo es color de rosas en el mundo de los frameworks. Sobre todo en frameworks grandes y complejos, la curva de aprendizaje suele ser bastante empinada, lo cual es un tema a tener en cuenta a la hora de estimar tiempos de desarrollo. Cuando utilizamos un framework, normalmente en la jerga de la informática se dice que "Nos estamos casando con él", ya que una vez que comenzamos el desarrollo, es muy difícil migrarlo a otro framework sin tener que cambiar TODO el código escrito. Por ultimo y a la desventaja final que dice "Falsa sensación de conocer el lenguaje", a lo que me refiero es a que muchas veces se cree que por utilizar un framework, conocemos el lenguaje para el cual están desarrollado. Un ejemplo típico es cuando utilizamos por ejemplo JQuery, muchas veces creemos que por utilizar jQuery sabemos programar con JavaScript, pero esto no es asi... Como nota personal y por mi experiencia siempre aconsejo aprender a manejar el lenguaje de programación, antes de usar un framework complejo. 

Por ultimo algunas cositas que me gustaría comentar son:

Muchas veces se confunde lo que son los frameworks con las librerías o bibliotecas de un lenguaje. 
La diferencia fundamental entre los Frameworks y las librerías o bibliotecas es que cuando utilizamos las bibliotecas lo que estamos reutilizando es código, en cambio cuando utilizamos un framework, reutilizamos la arquitectura.

También he leído en la web que cuando alguien dice que esta utilizando su propio framework en realidad esta haciendo mal el trabajo. Según mi experiencia y esto es una apreciación personal, una persona, tranquilamente puede desarrollar su propio framework, para algún dominio concreto en el cual se encuentre suficientemente capacitado. Yo creo que los pasos para desarrollar un framework serian:

  1. Tener bastante experiencia en desarrollos de un dominio concreto, y haber encontrado alguna manera de desarrollarlos que te ha dado éxito en todos los casos. 
  2. Definir el dominio especifico. 
  3. Definir el lenguaje a utilizar. 
  4. Definir cuales son los pasos genéricos que realizamos cada vez que comenzamos un desarrollo del dominio especifico. 
  5. Ver si se pueden sistematizar dichos pasos genéricos. 
  6. Sistematizarlos.
En una próxima publicación pondré un ejemplo de un framwork que estuve haciendo en estos días, que se adapta perfectamente para la programación de aplicaciones pequeñas, con interfaz gráfica y Base de Datos. 
El framework es para Python, tiene como ORM sqlalchemy, motor de base de datos SQLite y la parte gráfica hecha con PyQT. Con esas cuatro herramientas, podemos hacer programas bastante complejos y en pocos minutos utilizando mi framework. 

Saludos y nos vemos en la proxima. 

sábado, 28 de julio de 2012

Metodos Estaticos (Python)

Los metodos estaticos son aquellos metodos que se pueden ejecutar aun cuando la clase no se a instanciado.

Es decir no es necesario hacer:

p = Persona()

para llamar por ejemplo al metodo obtenerTodas

se podria hacer simplemente

personas = Persona.obtenerTodas()

Veamos un ejemplo como para que quede todo mas claro.

class Persona(object): 
    nombre = "sin nombre" 
     
    def __init__(self): 
        self.nombre = "con nombre" 
     
    def getNombre(self): 
        return self.nombre

Para poder trabajar con esta clase, lo primero que habria que hacer es instanciarla.

p = Persona()
print p.getNombre()

lo cual mostraria el mensaje "con nombre" ya que al hacer Persona(), lo que hace es llamar al constructor de la clase persona, que a su vez le da el valor "con nombre" al atributo nombre.

La forma de declarar un metodo como estatico es la siguiente:

class Persona(object): 
    nombre = "sin nombre"

    def __init__(self): 
        self.nombre = "con nombre" 

    @staticmethod     
    def getNombreStatic(self): 
        return self.nombre

    @classmethod
    def getNombreClass(self): 
        return self.nombr

La diferencia, entre el método estático y el método de clase en Python, es que mientras el método estático no recibe por defecto ningún parámetro, el método de clase recibe como primer argumento el objeto classtype, esto es, la referencia a la declaración de la clase.

# El método estático, recibiendo la clase, retorna True
print Persona.getNombreStatic(OtraClase) 
  
# Mientras que el método de clase ya recibe la clase, y retorna True
print Persona.getNombreClass()

En definitiva no hace falta instanciar la clase persona para utilizar el metodo getNombre.. :)

Espero les sirva!

viernes, 27 de julio de 2012

Validar CBU

El algoritmo de validación del CBU es bastante sencillo.

Las validaciones principales que se pueden hacer es que el CBU tenga 22 digitos numericos y que sea de una entidad financiera en particular:

Por ejemplo si queremos solo aceptar solo CBU's del BANCO NACION deberiamos validar que el CBU ingresado empiece con el numero 011.

La lista de las entidades financieras validas es la siguiente:

  • 005 A.B.N AMRO BANK N.V.
  • 007 BANCO DE GALICIA Y BUENOS AIRES S.A.
  • 010 LLOYDS TSB BANK plc.
  • 011 BANCO DE LA NACION ARGENTINA
  • 014 BANCO DE LA PROVINCIA DE BUENOS AIRES
  • 015 BANKBOSTON, NATIONAL ASSOCIATION
  • 016 CITIBANK N.A.
  • 017 BBVA BANCO FRANCES S.A.
  • 018 THE BANK OF TOKYO - MITSUBISHI, LTD.
  • 020 BANCO DE LA PROVINCIA DE CORDOBA S.A.
  • 027 BANCO SOCIETE GENERALE S.A.
  • 029 BANCO DE LA CIUDAD DE BUENOS AIRES
  • 034 BANCO PATAGONIA SUDAMERIS S.A.
  • 044 BANCO HIPOTECARIO S.A.
  • 045 BANCO DE SAN JUAN S.A.
  • 046 BANCO DO BRASIL S.A.
  • 060 BANCO DEL TUCUMAN S.A.
  • 065 BANCO MUNICIPAL DE ROSARIO
  • 072 BANCO RIO DE LA PLATA S.A.
  • 079 BANCO REGIONAL DE CUYO S.A.
  • 083 BANCO DEL CHUBUT S.A.
  • 086 BANCO DE SANTA CRUZ S.A.
  • 093 BANCO DE LA PAMPA SOCIEDAD DE ECONOMIA MIXTA
  • 094 BANCO DE CORRIENTES S.A.
  • 097 BANCO PROVINCIA DEL NEUQUEN S.A.
  • 137 BANCO EMPRESARIO DE TUCUMAN COOP. LTDO.
  • 147 BANCO B. I. CREDITANSTALT S.A.
  • 150 HSBC BANK ARGENTINA S.A.
  • 165 J P MORGAN CHASE BANK SUCURSAL BUENOS AIRES
  • 191 BANCO CREDICOOP COOP. LTDO.
  • 198 BANCO DE VALORES S.A.
  • 247 BANCO ROELA S.A.
  • 254 BANCO MARIVA S.A.
  • 259 BANCO ITAU BUEN AYRE S.A.
  • 262 BANK OF AMERICA, NATIONAL ASSOCIATION
  • 265 BANCA NAZIONALE DEL LAVORO S.A.
  • 266 BNP PARIBAS
  • 268 BANCO PROVINCIA DE TIERRA DEL FUEGO
  • 269 BANCO DE LA REPUBLICA ORIENTAL DEL URUGUAY
  • 277 BANCO SAENZ S.A.
  • 281 BANCO MERIDIAN S.A.
  • 285 BANCO MACRO BANSUD S.A.
  • 293 BANCO MERCURIO S.A.
  • 294 ING BANK N.V.
  • 295 AMERICAN EXPRESS BANK LTD. S.A.
  • 297 BANCO BANEX S.A.
  • 299 BANCO COMAFI S.A.
  • 300 BANCO DE INVERSION Y COMERCIO EXTERIOR S.A.
  • 301 BANCO PIANO S.A.
  • 303 BANCO FINANSUR S.A.
  • 305 BANCO JULIO S.A.
  • 306 BANCO PRIVADO DE INVERSIONES S.A.
  • 309 NUEVO BANCO DE LA RIOJA S.A.
  • 310 BANCO DEL SOL S.A.
  • 311 NUEVO BANCO DEL CHACO S.A.
  • 312 M. B. A. BANCO DE INVERSIONES S.A.
  • 315 BANCO DE FORMOSA S.A.
  • 319 BANCO CMF S.A.
  • 321 BANCO DE SANTIAGO DEL ESTERO S.A.
  • 322 NUEVO BANCO INDUSTRIAL DE AZUL S.A.
  • 325 DEUTSCHE BANK S.A.
  • 330 NUEVO BANCO DE SANTA FE S.A.
  • 331 BANCO CETELEM ARGENTINA S.A.
  • 332 BANCO DE SERVICIOS FINANCIEROS S.A.
  • 335 BANCO COFIDIS S.A.
  • 336 BANCO BRADESCO ARGENTINA S.A.
  • 338 BANCO DE SERVICIOS Y TRANSACCIONES S.A.
  • 339 RCI BANQUE
  • 340 BACS BANCO DE CREDITO Y SECURITIZACION S.A.
  • 386 NUEVO BANCO DE ENTRE RIOS S.A.
  • 387 NUEVO BANCO SUQUIA S.A.
  • 388 NUEVO BANCO BISEL S.A.
  • 389 BANCO COLUMBIA S.A.


Luego debe separarse la CBU en 2 bloques:

El 1º bloque contiene:
  • Banco (3 dígitos)
  • Dígito Verificador 1 (1 dígito)
  • Sucursal (3 dígitos)
  • Dígito Verificador 2 (1 digito)

    El 2º bloque contiene:
      • Cuenta (13 dígitos)
      • Dígito Verificador (1 dígito)

      Validación:

      Por ejemplo: CBU 2850590940090418135201

      Validación 1º bloque (28505909)

      • Banco = 285 (Descomponer en sus dígitos B1 = 2, B2 = 8, B3 = 5)
      • DigitoVerificador1 = 0 
      • Sucursal = 590 (Descomponer en sus dígitos S1 = 5, S2 = 9, S3 = 0)
      • DigitoVerificador2 = 9
        Obtener:

        • SUMA1 = B1*7 + B2*1 + B3*3 + DigitoVerificador1*9 + S1*7 + S2*1 + S3*3
        • SUMA1 = 2*7 + 8*1 + 5*3 + 0*9 + 5*7 + 9*1 + 0*3 = 14 + 8 + 15 + 0 + 35 + 9 + 0 = 81
          Obtener:

          • DIFERENCIA1 = 10 - ultimo digito de SUMA1 = 10 - 1 = 9
          • Si DIFERENCIA1 = DigitoVerificador2 => CBU OK


            Validación 2º bloque (40090418135201)

            • Cuenta = 4009041813520 (Descomponer en sus dígitos C1 = 4, C2 = 0, C3 = 0, C4 = 9, C5 = 0, C6 = 4, C7 = 1, C8 = 8, C9 = 1, C10 = 3, C11 = 5, C12 = 2, C13 = 0
            • Digito = 1

            Obtener:

            • SUMA2 = C1*3 + C2*9 + C3*7 + C4*1 + C5*3 + C6*9 + C7*7 + C8*1 + C9*3 + C10*9 + C11*7 + C12*1 + C13*3
            • SUMA2 = 12 + 0 + 0 + 9 + 0 + 36 + 7 + 8 + 3 + 27 + 35 + 2 + 0
            • SUMA2 = 139

            Obtener:

            • DIFERENCIA2 = 10 - ultimo digito de SUMA2 = 10 - 9 = 1
            • Si DIFERENCIA2 = Digito => CBU OK


            Espero que les sirva!.. :)..

            jueves, 19 de julio de 2012

            Etiqueta SPAN HTML.. :)

            Supongo que no sere la primera persona que se pregunta para que sirve la etiqueta <span>, aunque increiblemente mil veces me encontre con el inconveniente que esta etiqueta justamente soluciona. La etiqueta <span> permite agrupar varios elementos en línea dentro de un mismo bloque (por ejemplo, varias palabras seguidas en un párrafo), para después darles formato con la hoja de estilo. Yo antes de entender que el span servia para esto, utilizaba un <label> o creaba otro <div> u otro <p> para hacerlo.. :).

            <p>Esto muestra mas o menos como se usa <span> la etiqueta span</span></p>

            A esa etiqueta <span> que engloba la frase "La etiqueta span" se le podria dar el estilo que se desee por medio de CSS.. 

            Espero haber sido claro..

            Saludos y hasta la proximaaaaaaa!!! 




            sábado, 14 de julio de 2012

            Google AdSense

            Bueno, ya a fin de mes en teoria deberia cobrar mis primeros 100 dolares ganados a partir de la publicidad de google AdSense.

            Actualmente tengo una pagina que tiene un nivel de visitas que oscila entre 600 y 800 diarias.
            La pagina es para generar mapas de alianzas de un juego que se llama Ikariam, es un juego de estrategia on-line, de los que se denominan juegos de navegador.

            Mi pagina es:

            Ikamap

            En mi pagina pueden verse dos bloques de publicidad, uno bien a la derecha y otro bien a la izquierda. Dichas publicidades van variando de acuerdo a los deseos del gran Google, ellos saben mas o menos cuales son los intereses de las personas que entran a mi pagina, y en base a eso saben que publicidad mostrarle a unos u a otros. 

            Los pasos que hay que seguir para poner publicidad son bien sencillos.
            Primero que nada es necesario contar con una cuenta de mail del Gmail, la cual siempre sera tu identidad en la mayoria de las aplicaciones que nos brinda Google.

            Si no tiene una cuenta puede registrarse aqui:

            Registrarse a AdSense

            La mayoria de sus dudas puede sacarselas desde este foro:

            Foro AdSense

            Solo debe seguir los pasos que les indique el personal de google y pronto estaran haciendo dinero con la Web.. :)..

            Cualquier consulta no duden en hacerla, yo soy nuevo en esto tambien asi que podemos aprender juntos!.

            Como hacer funcionar Curl en Windows 7

            Tratando de correr unas paginas que estaba haciendo en mi nueva laptop, me encontre con el problema de que cuando queria activar la extension Curl, de PHP, el servidor Apache me daba el siguiente error:

            PHP Warning: PHP Startup: Unable to load dynamic library 'C:\\PHP\\ext\\php_curl.dll' - The specified procedure could not be found.\r\n in Unknown on line 0

            Estuve leyendo un poco sobre el tema, y resulta ser que la ultima version del WAMP server que yo habia instalado era compatible con el sistema operativo ded 64bits (x64bits) pero no lo era con el sistema operativo de 64bits (x84bits), por lo cual esa incompatiblidad generaba que algunas extensiones PHP no corrieran correctamente.

            En definitiva la solucion fue sencilla. Desinstale la ultima version de WAMP server de 64bits e instale la ultima version de WAMP server de 32 bits, la cual si es compatible con x84bits.. :)

            Espero que les sirva.

            WampServer

            Some characters cannot be mapped using “Cp1252″ character encoding.

            En Eclipse ya varias veces me a pasado que cuando estoy escribiendo un codigo que contiene caracteres UTF-8, me aparece un mensaje al querer guardar el archivos que dice:

            'Some characters cannot be mapped using “Cp1252″ character encoding.'

            Esto se soluciona muy facilmente.
            1. Ir al menu Windows –> Preferences –> (Expandir la solapa) General –> (Clickear sobre) Workspace.
            2. Mirar el grupo “Text File Encoding”. Probablemente el valor por defecto sea “Cp1252″.
            3. Activa el radio que dice "Other" y selecciona “UTF-8″ del comboBox. 
            Una vez hecho esto, ya se nos permitira guardar sin problemas nuestro codigo fuente. :)

            lunes, 6 de febrero de 2012

            Aplicaciones con Interfaz grafica Python (GUI)

            Prácticamente cualquier aplicación comercial que quiera hacerse debe contar con tres patas fundamentales.

            Lógica programática.
            Interfaz grafica
            Base de datos.

            Hablando desde mi experiencia personal, les cuento que yo me recibí en la facultad como Licenciado en Informática sin haber escrito nunca un programa que contuviera estas tres patas completas. Por lo cual cuando llego la hora de ponerme a laburar, no me sentía completamente capacitado para hacer sistemas.
            Cuando salí de la facultad era un muy buen programador de scripts, pero un pésimo Programador de aplicaciones de escritorio.

            Si bien la lógica de un programa suele ser la parte más compleja, es la primera que se aprende y esta bien que así sea. Desde nuestros comienzos cuando estudiamos cualquier lenguaje de programación y escribimos nuestros primeros algoritmos ya estamos desarrollando la lógica computacional que puede servir para resolver problemas de casi cualquier índole. El problema surge cuando queremos tomar datos o mostrar los resultados en una pantalla que sea amigable para el usuario final.
            Ahí es cuando entra la Interfaz Grafica de Usuario también conocida como GUI. El tema es que cuando comencé a programar utilizaba Pascal o C, los cuales tienen un soporte para generar interfaces grafica muy muy pobres, luego “evolucione” a Visual Basic y a Java pero así y todo no terminaba de convencerme la manera en que se manejaban estas cuestiones. Por suerte apareció PyQt en mi vida…. J
            En lo referente a las Bases de datos, en un primer momento lo hacia en archivos de Texto plano en donde tenia que ocuparme de TOOOOOODAAAA la lógica, para asegurar la integridad de los datos, trabajo tedioso si los hay. Luego comencé a trabajar con bases de datos relacionales pero haciendo todo a mano. Y por ultimo descubrí la “magia” de los ORM… Seba esta Feliz.. J  

            Comencemos a ver algunas cositas pequeñas.

            Como creo que ya dije en alguna oportunidad hoy en día (Febrero de 2012) me encuentro programando en Python 2.6, y para lo que son las interfaces graficas utilizo PyQt GPL v4.4.3 for Python v2.6. Como en el ejemplo que presentare a continuación usaremos Sqlite les recomiendo bajarse el Sqlite Manager del siguiente enlace:


            PyQT tiene la particularidad de que genera archivos XML que luego pueden compilarse para generar interfaces graficas que se puedan utilizar en varios lenguajes, entre los que se encuentran C y Python entre otros.

            El ejemplo que haremos será sencillo, crear un formulario que acepte 3 campos, Nombre, Apellido y dirección y que tenga tres botones, uno para guardar los datos en la Base de datos, otro para resetear el formulario y otro para cerrar.



            Abrimos el Designer de PyQT y generamos la siguiente pantalla… Es muy intuitivo para utilizar, así que no me pondré a explicar paso a paso como hacerla (Si tenes dudas comenta, pregunta, googlea y seguro que obtenes respuesta)



            Renombramos el formulario en el editor de propiedades que aparece a la derecha.




            Modificamos el titulo de la ventaja tocando la propiedad siguiente:




            La convención que utilizo para los nombres de los botones es btn<Accion>.


            Agregamos tres labels con los textos:

            Nombre
            Apellido
            Direccion

            A los labels a menos que sea completamente necesarios le dejo el nombre por defecto que le pone PyQt.

            Agregamos tres controles de los denominados lineEdit y los nombramos txtNombre, txtApellido y txtDireccion.

            La pantalla final queda de la siguiente manera:


            La guardamos con el nombre FormCargarPersona.ui.

            Vamos a agregar un evento a un botón desde el PyQt Designer. Primero vamos a Edit Signals/Slots



            Oprimimos clic derecho sobre el botón cerrar y luego arrastramos y soltamos sobre el fondo del Form. Se mostrara algo similar a esto:



            Y se nos abrirá la siguiente pantalla. Sobre la parte izquiera se observan las señales habilitadas que puede enviar el boton:

            clicked(), clicked(bool), pressed(). Etc..


            Seleccionamos clicked() y checkeamos donde aparece la leyenda Show signals and slots inherited form QWidget. Nos apareceran mas opciones:



            Seleccionamos clicked() y close(), y le damos click al boton Aceptar.

            Volvemos a la edición de widget común clickeando en Edit Widgets



            Y probamos que todo ande como nosotros queremos. Con CTRL+R corremos el formulario, ahora si pinchamos sobre el botón cerrar el mismo debería cerrarse.

            Guardamos y listo por ahora… :)

            Si editamos el archivo ui con un editor de texto, veremos que es código puramente XML.
            Para compilarlo a lo que

            Para compilar el código XML a código Python se utiliza un compilador llamado Pyuic4 que se encuentra por lo general en el Path: C:\Python25\Lib\site-packages\PyQt4 dependiendo la versión de Python que tengamos instalada.

            Abrimos una consola y nos paramos en el Path en donde guardamos el archivo FormCargarPersona.ui. En ese lugar ejecutamos el siguiente comando:

            >pyuic4 –x FormCargarPersona.ui –o FormCargarPersona.py



            Esto generara en la carpeta C:\Python25\Lib\site-packages\PyQt4> el archivo FormCargarPersona.py. Cabe aclarar que no es recomendable modificar este archivo auto-generado. No es recomendable modificarlo, ya que ante cualquier modificación en la interfaz grafica, deberemos volver a compilar el archivo ui y esta compilación pisara cualquier cambio que se haya realizado en dicho archivo.

            Por ahora pondremos todo en una misma carpeta, pero luego es aconsejable utilizar algún árbol de directorios como puede llegar a ser el siguiente:

            Por gusto personal cuando debo crear una aplicación utilizo el sistema árbol de directorios, no es mi estilo decir cual es la forma correcta de trabajar.. J.. para mi la forma correcta es la que nos queda cómoda y da resultados…



            En la carpeta archivos, guardo archivos que genere con mi aplicación, archivos de Texto, reportes en PDF y demás cuestiones.

            En la carpeta Base de datos guardo todo lo referente a la conexión con la Base de datos, la creación de tablas, y las Clases de negocio que luego serán las que mapeo por medio del ORM con las tablas propiamente dichas.

            En la carpeta diálogos guardo los códigos fuentes de lo que vendría a ser el controlador de las vistas… Al trabajar con Qt es casi obligatorio usar el patrón de diseño MVC, donde las vistas son los formularios creados con Qt y los controladores serian los diálogos en donde se pone toda la funcionalidad.

            En la carpeta form_ui, guardo los formularios sin que hayan sido compilados, solo para tener el resguardo de la última versión.

            En la carpeta forms, pongo los formularios ya compilados.

            En images pongo las imágenes que usare dentro de mi aplicación, tanto iconos usados en los botones, como imágenes de fondo, etc.

            En la carpeta impresión suelo poner los códigos fuentes de los programas dedicados a realizar reportes en PDF que luego se imprimen desde el sistema.

            Por ultimo en la carpeta útiles, pongo código genérico que puedo utilizar en varios programas, para aumentar la reusabildiad de código.



            Veamos un ejemplo funcional de cómo se realizaría la escritura en una Base de datos sencilla.

            Ya tenemos nuestro FormCargarPersona.py… Ahora creemos el resto de los archivos necesarios para hacer funcional nuestro programa.

            #conexion.py

            import sqlalchemy as sql
            from PyQt4.QtGui import *
            from sqlalchemy.orm import sessionmaker

            class conexion():
               
                def __init__(self):
                    self.my_db = sql.create_engine('sqlite:///personas')
                    self.metadata  = sql.MetaData(self.my_db)
               
               
                def crearSession(self):
                    Session = sessionmaker(bind=self.my_db)
                    session = Session()
                    return session

            #creacionTablas.py

            from sqlalchemy import Table, Column, Integer, String, MetaData, Sequence
            from conexion import conexion
            from sqlalchemy.orm import mapper

            from Personas import Personas

            class creacionTablas():
                def __init__(self):
                    bd = conexion()
                    metadata = MetaData()
                    print 'Creacion de tablas'


                    tabla_personas = Table('personas', metadata,
                        Column('idPersona', Integer, Sequence('user_id_seq'), primary_key=True),
                        Column('nombre', String(30)),
                        Column('apellido', String(30)),
                        Column('direccion', String(30))
                    )

                    metadata.create_all(bd.my_db)

                    mapper(Personas,tabla_personas)





            #Personas.py

            class Personas(object):

                def __init__(self, nombre, apellido, direccion):
                    self.nombre = nombre
                    self.apellido = apellido
                    self.direccion = direccion


            #PrincipalPersona.py

            import sys
            import PyQt4
            sys.path.append("..")

            import creacionTablas
            from PyQt4.QtGui import *
            from PyQt4 import QtGui
            from PyQt4 import QtCore

            from dlgCargarPersonas import dlgCargarPersonas

            if __name__ == "__main__":
                app = QtGui.QApplication(sys.argv)
                creacionTablas.creacionTablas()
                d = dlgCargarPersonas()
                d.exec_()


            #dlgCargarPersonas.py

            from PyQt4 import QtCore, QtGui
            from FormCargarPersona import Ui_FormCargarPersona
            from Personas import Personas
            import conexion
            import PyQt4
            import sys

            class dlgCargarPersonas(QtGui.QDialog):

                def __init__(self):
                    QtGui.QDialog.__init__(self)
                    self.ui = Ui_FormCargarPersona()
                    self.ui.setupUi(self)
                    conect = conexion.conexion()
                    self.session = conect.crearSession()
                    self.connect(self.ui.btnAceptar, QtCore.SIGNAL("clicked()"), self.prueba)
                   
                def cargarPersona(self):
                    if(self.ui.txtApellido.text() <> "" and
                       self.ui.txtNombre.text() <> ""):
                        nombre = str(self.ui.txtNombre.text())
                        apellido = str(self.ui.txtApellido.text())
                        direccion = str(self.ui.txtDireccion.text())
                        persona = Personas(nombre, apellido, direccion)
                        self.session.add(persona)
                        self.session.commit()
               
            Poniendo estos 5 archivos en una misma carpeta y ejecutando PrincipalPersona.py, debería poderse guardar personar en la base de datos. Para ver si efectivamente se guardaron los datos en la base de datos podemos usar el sqliteman, que ya descargamos previamente, abrimos la base de datos que se llama personas, que se encontrara en la misma carpeta en donde tenemos todos los fuentes, y hacemos un Select * from personas. 

            ORM – Sqlalchemy (Bases de datos Python)

            Desde ya hace un buen tiempo que trabajar con Bases de Datos dejo de ser algo tedioso y complicado, mucha de esta simplificación se la debemos a los ORM.

            Los ORM básicamente sirven para realizar una conversión directa de objetos software a registros o tablas de una Base de datos relacional.

            Supongamos que tenemos la clase Persona con los atributos, nombre, apellido y dirección.
            Por otro lado deberíamos tener la tabla tPersona en la Base de datos, con los campos idPersona, apellido, nombre y dirección.

            Antiguamente y a grandes razgos para guardar una persona en la Base de datos se tenia que escribir dentro del código fuente de nuestro programa, la sentencia sql que ejecutaba el insert. Así como también hacer el mapeo uno a uno de los atributos de la clase con los campos de la tabla. También se debía crear la conexión manualmente y los programas quedaban fuertemente acoplados con la Base de Datos utilizada. Es decir migrar un programa que usara MySql a uno que usara PostgreSql no era algo trivial.
            Por esta razón el código quedaba “sucio” y su escalabilidad y mantenimiento se volvía complicado.

            Los ORM sirven para subsanar estos inconvenientes, y hacer que el hecho de trabajar con Bases de datos relacionales sea algo mucho más llevadero.

            Por ejemplo si quisiéramos escribir en la Base de datos una persona sin utilizar la potencia de un ORM, seria más o menos así...

            (NO ESTA DE MAS ACLARAR QUE ESTE ES UN EJEMPLO ILUSTRATIVO Y NO FUNCIONAL…)

            class Persona(object):

                def __init__(self, nombre, apellido, direccion):
                    self.nombre = nombre
                    self.apellido = apellido
                    self.direccion = direccion

            tablaPersona = Table('tPersona', self.metadata, autoload=True)

            persona = Persona(“Seba”, “Bataglia”, “Dire seba”)

            sentenciaSql = “Insert into tPersona (nombre, apellido, direccion) values(‘“ + persona.nombre + “’,’” + persona.apellido + “’,’”+persona.direccion+”’)”

            ejecutarSql(sentenciaSql)

            Ahora bien, si quisiéramos hacer lo mismo con un ORM bastaría con hacer algo así.

            persona = Persona(“Seba”, “Bataglia”, “Dire seba”)
            persona.Save()

            Como puede observarse el código queda muchísimo más limpio. Y nos desligamos completamente de escribir Sql dentro de nuestro código fuente.

            Esta es una muy muy breve introducción a lo que son los ORM. En la próxima entrega veremos como crear una aplicación con interfaz grafica por medio de PyQT y luego haremos una aplicación que sirva para persistir datos, bien basica.