domingo, junio 24, 2007

Problemas en GNU/Linux y ayuda de Python

Hace unos días instale un Debian Etch pero tengo un detalle con el sonido. El sonido me anda pero cuando escucho algo si intento bajar o subir el volumen me quedo totalmente sin el y debo hacerlo desde los propios parlantes. También tengo instalado un Ubuntu Dapper que hace rato no usaba. Como en Ubuntu no tube ningún problema y en Debian si se me ocurrio investigar. Primero quiero agregar que todaía no pude solucionar el problema pero investigando se me ocurrio que tal vez era algún módulo que no se cargaba por lo cual inicie en Ubuntu y después en Debian y en ambos ejecute:

# lsmod > lsmod_DISTRO.txt

Y con ayuda de python pude identificar aquellos módulos que en Debian no se cargaban y base estos datos seguí mi investigación (sin exito hasta la fecha). A continuación les dejo el código en Python que me ayudo a identificar los modulos que no se cargaban rapidamente.

  1. dario@debian:~/audio$ python
  2. Python 2.4.4 (#2, Apr 5 2007, 20:11:18)
  3. [GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
  4. Type "help", "copyright", "credits" or "license" for more information.
  5. >>> f1 = open('lsmod_debian.txt','r')
  6. >>> f2 = open('lsmod_ubuntu.txt','r')
  7. >>> debian = f1.readlines()
  8. >>> ubuntu = f2.readlines()
  9. >>>
  10. >>> mod_debian = []
  11. >>> for linea in debian:
  12. ... mod_debian.append(linea.split(' ')[0])
  13. ...
  14. >>> mod_ubuntu = []
  15. >>> for linea in ubuntu:
  16. ... mod_ubuntu.append(linea.split(' ')[0])
  17. ...
  18. >>> len(mod_debian)
  19. 58
  20. >>> len(mod_ubuntu)
  21. 88
  22. >>> for modulo in mod_ubuntu:
  23. ... if modulo not in mod_debian:
  24. ... print modulo
  25. ...
Dario Ocles.

sábado, junio 23, 2007

Auto-completar en CMD.exe de Windows

Si trabajas o usastes GNU/Linux y has usado Bash, te acostumbras algunas cosas como puede ser el ir auto-completando los comando por medio de tab's. Es muy comodo escribir las primeras letras de un comando (o directoprio) apretar tab y que se complete automaticamente, si el nombre es muy difícil o muy largo el tab nos ayuda. El porque no viene activado por default en el shell de Win no lo sé, pero aquí esta este tip:

El la shell de windows con auto-completado de los comandos y directorios.

Inicio -> Ejecutar -> regedit

Una ves que se abre buscamos en el arbol:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor]

Y a la clave “CompletionChar” le damos doble-click y el valor que tiene es 40, ahora lo cambiamos y dejamos 9.

Listo! Ahora abran una consola (Inicio -> Ejecutar -> cmd) vayan al raíz ("cd \") y escriban "cd ar" y presionen TAB, les debería quedar igual que a la imagen.

Ya son usuario felices con una shell "como la gente".

Dario Ocles.

viernes, junio 22, 2007

Composite Pattern en Python

En un post anterior muestro como implementar el patron Composite en PHP. Hoy implemente el mismo código pero en Python, solamente como un jercicio propio y para empezar a hacer algo en Python ya que no hago mucho, solo leo :-(

Ya que estoy remarco algunas cosas para el que no conozca Python. En python para marcar los bloques de código se hace por medio de la identación lo cual hace -obligadamente- el código más fácil de leer. Los puntos y las ">>>" que ven en el código es porque estaba trabajando con la consola interactiva de Python algo muy practico para probar cosas rapidamente.

Bueno, sin más preambulos les dejo el código (disculpen, no encontre como colorear el código :-( ):

  1. >>> class Grafico:
  2. ... def dibujar(self):
  3. ... pass
  4. ...
  5. >>> class Triangulo(Grafico):
  6. ... def __init__(self,nombre = 'unknown'):
  7. ... self.nombre = nombre
  8. ... def dibujar(self):
  9. ... print '-Soy triangulo ', self.nombre
  10. ...
  11. >>> class Contenedor(Grafico):
  12. ... def __init__(self, nombre = 'unknown'):
  13. ... self.nombre = nombre
  14. ... self.contenedor = []
  15. ... def dibujar(self):
  16. ... print 'Soy contenedor ', self.nombre
  17. ... for grafico in self.contenedor:
  18. ... grafico.dibujar()
  19. ... def agregar(self, grafico):
  20. ... self.contenedor.append(grafico)
  21. ... def sacar(self, grafico):
  22. ... if grafico in self.contenedor:
  23. ... self.contenedor.remove(grafico)
  24. ...
  25. >>> tri1 = Triangulo('1')
  26. >>> tri2 = Triangulo('2')
  27. >>> tri3 = Triangulo('3')
  28. >>> cont1 = Contenedor('1')
  29. >>> cont2 = Contenedor('2')
  30. >>> cont3 = Contenedor('3')
  31. >>> cont1.agregar(tri1)
  32. >>> cont1.agregar(tri2)
  33. >>> cont2.agregar(tri3)
  34. >>> cont3.agregar(cont1)
  35. >>> cont3.agregar(cont2)
  36. >>>
  37. >>> cont3.dibujar()
  38. Soy contenedor 3
  39. Soy contenedor 1
  40. -Soy triangulo 1
  41. -Soy triangulo 2
  42. Soy contenedor 2
  43. -Soy triangulo 3
Dario Ocles.

martes, junio 19, 2007

Que lenguaje soy? Que extención de archivo soy?

Soy friki! que le voy hacer?

Array, equivalencias e igualdades.

Cuanto más leo el libro de la certificación más "curiosidades" me encuentro. PHP cuenta con 11 funciones distintas para ordenar array's, un número nada despreciable. También veo que los array's pueden ser equivalentes (==) o identicos (===). Ser equivalente no es igual a ser identicos, pero no solo eso, sino que estas comparaciones estan atados a algunos "detallitos".

$uno = array('a', 'b', 'c', 'd');
$dos = array(1 => 'b', 'c', 'd', 0 => 'a');

if(
$uno == $dos)
echo
'$uno y $dos son equivalentes.';

if(
$uno === $dos)
echo
'$uno y dos son identicos.';

Resultado:

$uno y $dos son equivalentes.

Como bien vimos arriba, ambos array's tienen todos los elementos con la misma clave pero en diferente orden, por este motivo se los concidera equivalentes, pero no identicos.

Lamentablemente, lo anterior solo fue el principio. También hay un "detallito" con algunas reglas en las claves de los array's. Con estas reglas se debe tener cuidado pero no haré una explicación teorica escrita, lo demostrare con un ejemplo:

$uno = array(10 => 1);
$dos = array('10' => 1);

if(
$uno == $dos)
echo
'$uno y $dos son equivalentes.';

if(
$uno === $dos)
echo
'$uno y dos son idénticos.';

Devuelve:

$uno y $dos son equivalentes.
$uno y dos son idénticos.

Lo anterior no debería sorprenderno cuando lo siguiente se evalua como verdadero.

if( "10dario" == 10)
echo
'Verdadero';

Lo anterior se evalúa como verdadero porque PHP cuando hace una comparación primero homologa ambos términos haciendo casting si fuere necesario, en el caso de la cadena se hace casting y el resultado termina siendo un 10 entero y por consiguiente evaluandoce como verdadero.

Como ven, los array's en PHP son una cosa curiosa y debemos prestar especial atención... es una lastima que toda esta info este "escondida" y no se sepa o se muestre en los tutoriales que se suelen leer cuando uno aprende, este tema de seguro a provocado más de un dolor de cabeza.

Dario Ocles.

domingo, junio 17, 2007

Composite Pattern, un poco de código y poca explicación

Hoy con un poco de tiempo (exactamente media hora de "ocio") me dispuse a leer algunos de los blogs que tengo en los favoritos y llego al Blog de Alejo y veo el diagrama que esta aquí a la derecha y veo que es el diagrama del patrón Composite. De inmediato me dirijo a Google y encuentro información sobre Composite en Wikipedia y con ayuda del código que aparece en la versión en ingles del articulo de Composite logro entenderlo y aplicarlo en un pequeño ejemplo que dejo a continuación.

abstract class Grafico{
abstract public function
dibujar();
}

class
Triangulo extends Grafico{
private
$nombre = '';

public function
__construct($nombre = 'unknown'){
$this->nombre = $nombre;
}

public function
dibujar(){
echo
'-Soy triagulo '.$this->nombre.'.<br>';
}
}

class
Contenedor extends Grafico{
private
$nombre = '';
private
$contenedor = array();

public function
__construct($nombre = 'unknown'){
$this->nombre = $nombre;
}

public function
dibujar(){
echo
'Soy contenedror '.$this->nombre.'.<br>';
foreach(
$this->contenedor as $grafico)
$grafico->dibujar();
}

public function
add(Grafico $grafico){
$this->contenedor[] = $grafico;
}

public function
del(Grafico $grafico){
unset(
$this->contenedor[$grafico]);
}
}

$tri1 = new Triangulo('1');
$tri2 = new Triangulo('2');
$tri3 = new Triangulo('3');

$contenedor1 = new Contenedor('1');
$contenedor2 = new Contenedor('2');
$contenedor3 = new Contenedor('3');

$contenedor1->add($tri1);
$contenedor1->add($tri2);
$contenedor2->add($tri3);

$contenedor3->add($contenedor1);
$contenedor3->add($contenedor2);

$contenedor3->dibujar();

Si ejecutamos lo anterior devuelve lo siguiente:
Soy contenedror 3.
Soy contenedror 1.
-Soy triagulo 1.
-Soy triagulo 2.
Soy contenedror 2.
-Soy triagulo 3.

Saludos. Dario Ocles.

viernes, junio 15, 2007

Expresiones Regulares en la Certificación

La verdad es que las expresiones regulares son bastante extensas, lo suficiente como para escribir un libro. Hoy termine de leer el capitulo 4 del libro de la certificación (String And Patterns) y se toca el tema de las expresiones regulares pero solamente haciendo incapie sobre las expresiones PCRE (Perl Compatible Regular Expressions). El tema se trata muy por arriba y en el libro aclara que solo se vera lo necesario como para dar el examen. En si mucha pelota no le dan, explican muy por arriba y dan unos ejemplos, explican lo que son metacaracteres y te muestra algunos ejemplos con 4 o 5 funciones.

Mi recomendación sobre el tema es que busquen por internet y que le den bola a las "regex" (Regular Expressions) son muy poderosas si se las aprende a utilizar y sobre todo son muy interesantes y divertidas. En alguna ocasión hablare sobre ellas y explicare algunas bases. Tratare de que sea en un futuro no muy lejano. Por lo pronto prometo hablar sobre los capítulos 3 y 4 del libro ("Array", "String And Paterns"... respectivamente). Sobre los capítulos 1 y dos ya he hablado en alguna oportunidad pero solo son comentarios.

Dario Ocles.

domingo, junio 10, 2007

Array, que cosa curiosa.

Los array's en PHP son algo curiosos y ahora gracias al libro de la Certificación de PHP descumbro algunas curiosidades nuevas (que hablare en otro post). En este post quiero mostrar algo bastante curioso, que había leído hace algún tiempo pero había olvidado.

$a = array(0 => 1,
1 => 2,
2 => 3,
3 => 'a',
4 => 'b',
5 => 'c',
6 => NULL);

if(isset(
$a[0]))
echo
'Existe $a[0].<br>';
else
echo
'No existe $a[0].<br>';

unset(
$a[0]);

if(isset(
$a[0]))
echo
'Existe $a[0].<br>';
else
echo
'No existe $a[0].<br>';

if(isset(
$a[6]))
echo
'Existe $a[6].<br>';
else
echo
'No existe $a[6].<br>';

if(
array_key_exists(6, $a))
echo
'Existe $a[6].<br>';
else
echo
'No existe $a[6].<br>';

Y esto es lo que devuelve:

Existe $a[0].
No existe $a[0].
No existe $a[6].
Existe $a[6].

Como pueden ver en la tercera comprobación no devuelve lo que espera... isset() sirve con variables, pero cuando estamos comprobando los elemento de un array hay que tener cuidado de que este no sea un NULL ya que sino isset devolvera un False. La forma de evitarlo es usando array_key_exists(), aunque nunca me acostumbre a utilizar esta función, empezare a utilizarla puede que algún día me salve de un error que sería muy difícil de localizar.

Dario Ocles.

sábado, junio 09, 2007

PHP 5 Certification: Algunos comentarios.

Después de un pequeño faltaso, una gripe terrible y unas cuantas visitas al medico aquí estoy de nuevo. Hoy vengo a comentar sobre los primeros 2 capitulos del libro de la certificación de PHP 5. El primer capitulo se llama "PHP Basics" y el segundo "Function". No quiero parecer sobervio pero en realidad fueron 2 capitulos de esfuerzo (no se mucho de ingles) y tiempo perdidos... si has leido el manual oficial sabés mucho más de lo que explican en estos capitulos.

Si bien por ahora no hubo algo que me sorprendiera en gran medida hubo algo que, si bien es simple y lógico no supe contestar en el momento que estaba leyendo el libro. ¿Por que la ejecución del siguiente código devuelve lo que devuelve?

$a = array(1,2,3);

foreach(
$a as &$entero){
//Hacer algo
}

foreach(
$a as $entero){
//Hacer algo
}

echo
'<pre>';
print_r($a);
echo
'</pre>'
;

Y devuelve:
Array
(
[0] => 1
[1] => 2
[2] => 2
)

La explicación es bastante simple. En el primer foreach por alguna razón -que puede ser que quieras modificar el valor del array dentro de este- se usa por referencia el foreach. Cuando termina la ejecución del primer foreach la variable, en este caso, $entero sigue siendo una referencia al ultimo elemento del array, cuando empieza el segundo foreach en la primera iteración el ultimo elemento del array (el referenciado) toma el valor del primer elemento, en la segunda iteración el referenciado toma el valor del segundo elemento y en la ultima iteración toma el valor de si mismo que es en realidad el valor de la iteración anterior.
Como pueden ver es muy simple y trivial, pero sinceramente no me dí cuenta ni supe contestarlo, tal vez por distraido, por falta de concentración o lo que sea, pero hasta donde llevo leído el libro esto es lo más avanzado que he leído y la verdad es que no es nada del otro mundo.

Dario Ocles