Archivo

Archivo para Marzo, 2010

Graba lo que haces en la consola

Miércoles, 31 de Marzo de 2010 Gaspar Fernández Sin comentarios

cinta Estoy de vacaciones, pero tuve que usar este comando en un pequeño proyecto y me pareció buena idea publicarlo en el blog.

A veces tenemos la necesidad de guardar lo que estamos haciendo en consola (sería como un screencast pero para la línea de comandos). Tenemos que guardar los comandos que escribimos y las diferentes salidas en un archivo de texto.
Podemos hacer lo siguiente:

$ script test
Script iniciado; el fichero es test
$ echo “Hola mundo”
Hola mundo
$ exit

Se grabará todo lo que hemos hecho y la salida de los comandos ejecutados en el fichero test. Eso sí, se grabarán todo tipo de caracteres (retornos de carro, retroceso, códigos ANSI…), por lo que al ver el fichero podremos ver los colores representados e incluso veremos parpadeo al hacer limpiezas de pantalla.

Por otra parte es muy útil para guardar el trabajo de consola que vamos haciendo, o cuando estamos investigando, poder saber cómo hemos hecho las cosas.

Foto: Matti Mattila (Flickr)

Categories: Bash, Linux Tags: , ,

No los llames virus para PC cuando son virus para Windows

Lunes, 29 de Marzo de 2010 Gaspar Fernández Sin comentarios

Estoy de vacaciones, pero he encontrado un link que merece la pena leer: http://www.linuxav.net/index.php/2010/03/no-los-llames-virus-para-pc-son-virus-para-windows/.

Lleva toda la razón, en los medios se suele mencionar que los virus afectan a todos los PCs cuando en realidad sólo afectan a los que tienen Windows instalado.

Categories: General Tags: , , ,

Pequeñas vacaciones

Domingo, 28 de Marzo de 2010 Gaspar Fernández Sin comentarios

vacacionesEstaré un poco perdido esta semana (aunque llevo unos días sin escribir), aunque trabajando un poco. Pero volveré con energías renovadas el Domingo día 4 de abril.

Foto: Edo-Finelight (Flickr)

Categories: General Tags:

Montando un servidor FTP en Linux

Domingo, 21 de Marzo de 2010 Gaspar Fernández Sin comentarios

Es algo que me hacía ilusión aprender y sabía que debía haber algo para hacerlo. De hecho me he encontrado con varias opciones, entre ellas: FTPFS (ya obsoleta, por culpa de LUFIS que entró para el kernel 2.6.14), pero he estado viendo una alternativa mucho mejor FUSE (Filesystem in Userspace). Éste último tiene soporte para muchísimos sistemas de archivos, se pueden montar CVS, FTP, SSH, ficheros RAR, dispositivos bluetooth, particiones NTFS (captive, ntfs-3g…), Blogger… y mucho más… Es algo que me gustaría investigar mucho más a fondo.

Lo del montaje de ftps es una cosa muy sencilla, pero por lo menos que esta entrada en el diario sirva de chuleta (tanto a mí, que cada vez que voy a hacerlo no me acuerdo de cómo es) como a muchos de vosotros.

Lo primero es tener instalado fuse, y lufis:

$ emerge sys-fs/fuse lufis

Ya estamos listos, lo bueno de este sistema es que podemos montar y desmontar siendo usuarios siempre que tengamos el módulo fuse cargado:

$ modprobe fuse

Podemos montar de la siguiente forma, siento /mnt/ftps nuestro punto de montaje (si lo hacemos como usuario, éste tiene que tener permiso sobre ese directorio:

$ lufis fs=ftpfs,host=[servidor],username=[usuario],password=[clave] /mnt/ftps

Lo bueno de esto, es que no sale la contraseña en el listado de procesos, lo malo es que sí que sale el nombre de usuario:

$ ps ax
PID TTY          STAT    TIME COMMAND

466 ?             Ss       0:00 /sbin/udevd –daemon
1599 ?             Ssl       0:00 lufis fs ftpfs host servidor username usuario password                /mnt/ftps

1941 pts/2       R+       0:00 ps ax
4012 ?             Ss       0:00 /usr/sbin/acpid -c /etc/acpi/events

Para desmontar:

$ fusermount -u /mnt/ftps

Si queremos montar un ssh… basta con cambiar ftpfs por sshfs y podemos instalar todos los sistemas de archivos que queramos, del enlace que os pasé antes y disfrutar de lo cómodo que es trabajar de esta forma.

Además esto nos permite poder hacer scripts que interactúen con un servidor FTP mucho más fácilmente.

Categories: Linux Tags: , , , ,

Historia de Lenna

Viernes, 19 de Marzo de 2010 Gaspar Fernández Sin comentarios

lenna_mainEste post lo he rescatado de un antiguo blog que tenía allá por 2007, y es que en la Universidad estuve estudiando una asignatura, Tratamiento Digital de Imagen y había una foto que se repetía hasta la saciedad.

Todo se remonta a Julio del 1973 cuando en el Instituto de Procesamiento de Señal e Imagen del USC (California) estaban buscando una imagen para una conferencia. La imagen debía tener un gran margen dinámico. Estaban pensando en una cara, y por supuesto, qué mejor que sacarla de la revista Playboy… y como eran tontillos… Playmate de Noviembre del 1972, no, si la muchacha es guapa, aunque en la foto tenía 21 años. Y la foto no está entera, como os podéis imaginar… pero si queréis os dejo unos enlaces al final :)

Tras la conferencia mucha gente estuvo interesada en la foto, para sus investigaciones con filtros y compresión de imagen. imaginaos que sin Lenna, el JPEG no sería lo que conocemos actualmente; y bueno, que había pocas chicas en la investigación de imagen digital, todo sea dicho.

Con respecto al nombre, es Lena Söderberg, de origen sueco; pero como siempre la manía de cambiar los nombres, en la revista se llamba Lenna Sjööblom (con dos N para que los anglosajones lo pronunciaran bien). Fue el número más vendido de la historia de la revista. Aquí tenéis la ficha de Lenna.

La imagen de Lenna se ha convertido con los años en un estándar de facto de  imagen de prueba de miles de algoritmos relacionados con este campo y muy importante para la comunidad científica, tanto es así que hasta Playboy autorizó su publicación en estos círculos (normal ellos también han terminado utilizando la tecnología desarrollada por ese hecho), no denunciando ni a la revista Optical Engineering(01/1992) ni a IEEE Transactions on Image Processing (1996), ya que la foto tiene derechos. David C. Munson, editor de ésta última reista escribió una nota explicando las razones de por qué se utiliza la foto de Lenna. Más o menos viene a decir dos razones:

* Es una buena imagen de prueba, tiene regiones planas, sombras y texturas lo que es bueno para probar algoritmos de procesamiento de imágenes.

* Segundo, es una chica atractiva, y es normal que esta comunidad de investigación (casi todo hombres) giren en torno a una imagen que encuentran atractiva.

Además la imagen se ha utilizado en multitud de libros para demostrar ciertos algoritmos. Por ejemplo el que estoy leyendo ahora para la asignatura Digital Image Processing de Rafael C. Gonzalez y Richard E. Woods (muy gordo por cierto).

Ahora tenemos la otra cara de la moneda, la cara de un mundo que se empeña en criticar todo lo que se ha creado, porque es incorrecto, les parece mal. A ciertas personas les molesta que sea una mujer la que esté posando, pero les molesta aún más que provenga de una portada de Playboy, al menos está recortada, les molesta que haya salido en revistas, en libros, en miles de pruebas del desarrollo de JPEG.

Lo mejor de todo es que hasta el 1988 ella no se enteró de la repercusión que tenía, hasta que la entrevistaron de una revista de informática sueca. Y en mayo de 1997, fue invitada a la la 50th Annual Conference of the Society for Imaging Science in Technology, como parte de de la historia de la imagen digital. Y bueno, casi casi pudo montar un club de fans, todo el mundo pidiéndole autógrafos, yo creo que le hicieron más caso a ella que a todo lo demás… tantas horas delante de un ordenador mirándola fijamente, unen mucho :) Y una de sus frases fue: deben estar tan cansados de mí … ¡mirando la misma foto por todos estos años!

lenna_oldHay muy poca información sobre ella actualmente. Está casada, tiene tres hijos y trabaja para el estado. Cuando la invitaron para la conferencia que he citado antes trabajaba ayudando a discapacitados a trabajar con ordenadores.

Por cierto, el póster también sale en la película El dormilón (Original: Sleeper) de Woody Allen (1973). Lenna en Sleeper.

Aquí os dejo unos cuántos enlaces si queréis más información:

May 2001 Newsletter of the IEEE Professional Communication Society (PDF)
La Historia de Lenna
Lenna - Wikipedia
The Rest of The Lenna Story

Tamaño de archivo para seres humanos (PHP,C++ y C)

Miércoles, 17 de Marzo de 2010 Gaspar Fernández Sin comentarios

Cuando obtenemos un tamaño de archivo, lo obtendremos en bytes, aunque está bien tener esa información en otras unidades, sobre todo, para expresar las cantidades al usuario de una forma más amigable.

1
2
3
4
5
6
7
8
9
function human_size ($tam) {
        $i = 0;
        $unids=array("bytes","Kb","Mb","Gb","Tb","Pb","Eb","Zb","Yb","Bb");
        while ($tam>1024) {
                $tam = $tam /1024;
                $i++;
        }
        return number_format($tam,2,",",".").$unids[$i];
}

Ahora sólo tenemos que llamar a human_size(filesize(’archivo’)), por ejemplo, para dar el tamaño de un archivo.
En C++ podemos por ejemplo hacer lo siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <sstream>

using namespace std;

string human_size(long double size)
{
  static string units[10]={"bytes","Kb","Mb","Gb","Tb","Pb","Eb","Zb","Yb","Bb"};
  ostringstream out;
  int i= 0;

  while (size>1024) {
    size = size /1024;
    i++;
  }

  out.precision(3);
  out<<size<<units[i];
  return out.str();
}

int main()
{
  cout <<human_size(1232312333)<<endl;
}

Y ya puestos, lo hacemos en C de la siguiente forma:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

char *human_size(char *store, long double size)
{
  static char units[10][6]={"bytes","Kb","Mb","Gb","Tb","Pb","Eb","Zb","Yb","Bb"};  
  int i= 0;

  while (size>1024) {
    size = size /1024;
    i++;
  }

  sprintf(store,"%.2Lf%s",size, units[i]);

  return store;
}

int main()
{
  char cadena[30];
  printf("Size: %s\n", human_size(cadena, 1293323872));
}

Nota: Sé que he puesto muchas unidades: “bytes”, “Kilobytes”, “Megabytes”, “GigaBytes”, “Terabytes”, “Petabytes”, “Exabytes”, “Zetabytes”, “Yottabytes” y “Brontobytes”, y que las variables no almacenarán valores tan grandes, pero bueno, por tener una referencia de las unidades en un lugar seguro :)

Función curiosa: preg_replace_callback (PHP)

Lunes, 15 de Marzo de 2010 Gaspar Fernández 2 comentarios

A veces tenemos la necesidad de reemplazar un texto dentro de una cadena larga. Por ejemplo, el uso principal que le doy a esta función es el procesamiento de plantillas para páginas web, en donde tengo la página en HTML puro por un lado, y en su interior hay ciertas palabras clave, por ejemplo —seccionA—, —fotoUsuario—, —menuSesion—, etc; y en la web definitiva, aparecerá otra cosa en lugar de ese texto, aparecerá el objeto al que hace referencia.
Aunque cada cadena de texto seccionA, fotoUsuario, requiere un procesamiento distinto y es posible que no tengamos por qué procesar siempre todas las equivalencias de todos los textos. Queremos en definitiva reemplazar —seccionA— por el resultado de una función que ejecutaremos cuando encontremos ese texto. Sería como:

1
2
3
4
$disparadores=array("---seccionA---", "---fotoUsuario---", "---menuSesion---");
$reemplazos=array(dibuja_seccionA(), get_fotoUsuario(), dibuja_menuSesion);

$web=str_replace($disparadores, $reemplazos, $web);

Aunque, como dijimos, en el ejemplo anterior, se tienen que ejecutar dibuja_seccionA(), get_fotoUsuario() y dibuja_menuSesion().

Pero podemos aprovecharnos de las expresiones regulares, para extraer texto que esté entre “—” y “—” y pasar lo que hay entre medias a otra función que decidirá qué hacer; eso hace preg_replace_callback().

1
2
3
4
5
6
7
8
9
10
function quehacer($texto)
{
  switch ($texto[1]) // [0] devuelve: ---texto---, [1] devuelve texto
  {
     case 'seccionA': return dibuja_seccionA();
     case 'fotoUsuario': return get_fotoUsuario();
     case 'menuSesion': return dibuja_menuSesion();
  }
}
$web=preg_replace_callback('/---([a-zA-Z0-9_]*)---/', 'quehacer', $web);

Hasta aquí bien, el primer parámetro es una expresión regular (es un tema muuuy extenso), el segundo es la función a la que llamamos cuando encontramos el texto, y el tercero es de dónde lo sacamos. Bueno, ahora surge un problema, imaginad que necesito pasarle parámetros a esa función callback. Lo podemos hacer así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function guardar_datos($data=null)
{
  static $guardados; // Una variable estática, muy importante

  // Si se especifica $data, lo guardamos en $guardados, al ser estática, aunque salgamos de la función, el valor de la variable no se perderá.
  if ($data)
    $guardados=$data;
 
  return $guardados;
}

function quehacer($texto)
{
  $datos = guardar_datos();

  switch ($texto[1]) // [0] devuelve: ---texto---, [1] devuelve texto
  {
     case 'seccionA': return dibuja_seccionA();
     case 'fotoUsuario': return get_fotoUsuario($datos);
     case 'menuSesion': return dibuja_menuSesion($datos);
  }
}

guardar_datos(array($datos_usuario, $datos_sesion));
$web=preg_replace_callback('/---([a-zA-Z0-9_]*)---/', 'quehacer', $web);

Nota: las variables $datos_usuario, $datos_sesion y $web no están definidas, como esto es parte de un programa, hay que imaginar un poco cuál será la información que contendrán.

Un fondo de escritorio para Linuxeros

Domingo, 14 de Marzo de 2010 Gaspar Fernández 2 comentarios

Acabo de verlo en MuyLinux y me ha encantado. Lo han sacado de Be Linux My Friend. Es una chuleta para la línea de comandos, con todas esas órdenes útiles que vamos a necesitar.
Dada su distribución, bien podemos tener iconos de escritorio a la izquierda o un emulador de terminal para ir practicando :)
Encontramos los comandos básicos para manejo de ficheros, búsquedas procesos, compresión, instalación de programas, permisos, y más.
cli_commands-1400x900

Categories: Bash, General Tags: , , ,

Funciones con nombres raros, y cortos (PHP, Javascript ,C)

Viernes, 12 de Marzo de 2010 Gaspar Fernández Sin comentarios

El objetivo de la programación, además de escribir poco (ya sabemos que todos los que programamos no queremos dejarnos las manos escribiendo), es hacer nuestro código mantenible, y para eso es necesario que nuestras funciones y métodos tengan nombres descriptivos.
Es decir, podemos definir 20 funciones: a(), b(), c(),… y mientras hacemos el programa tener un mapa mental de todas ellas, y utilizarlas, pero dentro de 6 meses, cuando vayamos a hacer la versión 2.0 de nuestro programa, ¿nos acordaremos de para qué valía cada función? Seguramente no; pero siempre que hacemos un for, lo más normal es escribir: “for (i=0;….”, “for (j=0;……)”, etc, eso sí que sale automático :)

Podemos, por ejemplo, tener nombres descriptivos, pero tal vez sean demasiado largos y muchos de ellos empezarán por las mismas letras, lo cual podemos considerarlo improductivo.

Si habéis curioseado prototype o JQuery, veréis cómo hay una llamada que se repite: $() y ella sola, con lo corta que es, hace maravillas para obtener objetos en Javascript. Los que hayan curioseado gettext recordarán la función _(), que sirve para traducir un mensaje. Estas funciones tienen en común que no vamos a parar de llamarlas en nuestros programas, sabemos lo que hacen y necesitamos una forma corta de llamarlas, ya que si desde nuestro programa llamamos a la función gettext() unas 2000 veces, estaríamos escribiendo 12000 caracteres de más, y en Javascript, si por ejemplo queremos llamar a document.getElementById(), con $() (no es lo único que hace) unas 60 veces, estaremos escribiendo unas 1320letras de más (y en Javascript eso se traduce en más transferencia por nuestra parte).

Pero cuando vamos a hacer una aplicación, todo se utiliza más o menos a un ritmo similar, aunque encontraremos tal vez funciones de formateo que llamemos constantemente, y esas funciones podrán tener un nombre raro que puede ser un símbolo. Pero con lo caprichosos que son los lenguajes de programación, ¿qué símbolos podemos utilizar? Deben ser caracteres con los que podamos empezar una función.
Aquí van algunos ejemplos para funciones PHP:

  • €();
  • ¡();
  • ç();
  • º();
  • ½();
  • _(); Pertenece a gettext
  • ł();
  • ¶();
  • ŧ();
  • ←();

C sólo permite el uso de _()

En Javascript, tenemos por ejemplo los siguientes:

  • $() Ojo con jquery y prototype
  • _()
  • º()
  • ª()
  • ß()
  • ð()
  • ŋ()
  • ħ()
  • ł()

Hay algunos más, pero no es plan de abusar, y no quiere decir que tenemos que usarlos, sólo que tenemos esa posibilidad; también muchos caracteres dependen de la codificación que utilicemos, por lo tanto pueden darnos ciertos problemas en el futuro (sobre todo en Javascript).

trim(), un gran amigo (PHP, C++, C)

Miércoles, 10 de Marzo de 2010 Gaspar Fernández 2 comentarios

A mi entender, es una de las funciones más útiles que se han inventado, como programador de PHP estoy harto de utilizarlo para filtrar información (caracteres a la derecha y a la izquierda, ya sean espacios, caracteres especiales o algún carácter que yo utilice para el control de la información).
Sabemos que el usuario final no nos va a dejar las cosas fáciles, puesto que a veces, nos llena un campo con “intros” al principio y al final; o la información, después de pasar por HTTP, lectura de un archivo XML o por otros tratamientos, tal vez tenga un retorno de carro al final; por eso, a veces es útil hacer:

1
$cadena=trim($cadena);

Pero ahora estamos en C++, bien quería postear también el código en C++, así que decidí googlear un poco para ver esto:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string>
const std::string whiteSpaces( " \f\n\r\t\v" );

void trimRight( std::string& str,
      const std::string& trimChars = whiteSpaces )
{
   std::string::size_type pos = str.find_last_not_of( trimChars );
   str.erase( pos + 1 );
}

void trimLeft( std::string& str,
      const std::string& trimChars = whiteSpaces )
{
   std::string::size_type pos = str.find_first_not_of( trimChars );
   str.erase( 0, pos );
}

void trim( std::string& str, const std::string& trimChars = whiteSpaces )
{
   trimRight( str, trimChars );
   trimLeft( str, trimChars );
}

Con esto podemos jugar con nuestros textos…

Ahora vamos al caso de C, muchos se siguen preguntando… pero si C es un lenguaje muy antiguo, ¿aún se sigue usando? Pues sí ! Aunque muchas cosas sean horribles de programar en C, a pelo, se sigue usando, y aún le queda mucha vida a este lenguaje. Por eso, veremos dos funciones trim() especiales para C:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <stdio.h>
#include <string.h>

char *trim(char *s)
{
  char *start = s;

  /* Nos comemos los espacios al inicio */
  while(*start && isspace(*start))
    ++start;

  char *i = start;
  char *end = start;

  /* Nos comemos los espacios al final */
  while(*i)
  {
    if( !isspace(*(i++)) )
      end = i;
  }

  /* Escribimos el terminados */
  *end = 0;

  return start;
}

char *trim2(char *s, const char *trimChars)
{
  char *start = s;

  /* Nos comemos los caracteres al principio */
  while(*start && strpbrk((const char*)start, trimChars)==start)
    ++start;

  char *i = start;
  char *end = start;

  /* Nos comemos los caracteres al final */
  while(*i)
  {
    if( strpbrk(i++, trimChars)!=i-1 )
      end = i;
  }

  /* Coloramos el perminador */
  *end = 0;

  return start;
}

int main()
{
  char mi_cadena[30]="\f\n Cadena; \tSucia \n\t ;";
  printf("Mi cadena inicialmente: \"%s\"\n", mi_cadena);
  printf("Mi cadena tras trim(): \"%s\"\n", trim(mi_cadena));
  printf("Mi cadena tras trim2(): \"%s\"\n", trim2(mi_cadena,";\f\n\t"));
}

En C también podremos tener nuestro trimleft y nuestro trimright y creo que es fácil sacarlo desde esta función general, ya que *start se mueve indicando el principio de la cadena, y con end, y es ese movimiento (que aunque perdemos algo de memoria) el que hace que se recorte la cadena; además, como buena función de C, perdemos la cadena que inicialmente teníamos.

Categories: C/C++ Tags: , , ,

Visita otras webs de la red