Pan casero y mate

Hoy mi hija mayor, que estudia en una escuela de cocina, hizo pan casero y mi esposa cambio mi habitual cafe por mate cocido. Esto me trajo a la memoria recuerdos de mi niñez que les conte a mis hijas y ahora quiero compartirlo con ustedes.

Cuando era un niño aun, hace ya bastantes años,  mas de 30, frente a mi casa paterna vivía una familia amiga, los Gutierrez, era una familia de trabajo, numerosa y de condicion humilde, yo era amigo de varios de sus hijos e hijas, por aquellos tiempos mi padre era almacenero y teniamos un mejor pasar economico.

Era una aventura acompañar a mis amigos los fines de semana al cerro cercano a buscar leña para hacer pan cacero, ellos comian solo pan casero que preparaban los domingo y que racionaban para toda la semana.

Ocacionalmente mi madre invitaba a mis amigos a tomar la leche en casa, como teniamos almacen no faltaban los biscochos, la mermelada y la manteca, a mis amigos les encantaba tomar la merienda en mi casa. Con la misma frecuencia la hermana mayor de esa familia, Teresa, nos invitaba a merendear a su casa, en casa de los Gutierrez se servia mate cocido y se comia pan casero bollos con y sin chicharron. Para mi era un placer indescriptible entrar a esa casa y sentir el olor a pan que invadia cada rincon, esperaba con ansias la invitacion a tomar el mate a casa de los Gutierrez.

Ellos creían que el pan de panaderia era mejor que su propio pan, que la leche de sachet y la mermelada de frasco eran mejor que su mate cocido. Cuan equivocados estaban.

Hoy el olor del pan horneandose me trajo ese hermoso recuerdo y lo quise compartir.

El lenguaje AWK

AWK o para ser mas precisos su version libre GAWK es un poderoso lenguaje de analisis semantico. Aprender a usarlo es un poco mas simple que otros lenguajes, pero eso no significa que sea una tarea rapida, toma su tiempo dominarlo, sin embargo, es posible obtener resultados rapidos para necesidades complejas desde el punto de vista de otros lenguajes no especializados. Veremos aca con una serie de simples ejemplos el poder de esta poderosa herramienta de los administradores de sistemas. Vamos entonces con el primer ejemplo.

Tenemos el archivo de usuarios de un servidor.

awk -F: '{ print $1 }' /etc/passwd

Esta sencilla linea nos devuelve los nombres de usuarios contenidos en el archivo /etc/passwd, si analizamos la linea de comandos tenemos que,  con la opcion -F mas el argumento : estamos definiendo el separador de campos de cada linea del archivo, luego,  ‘{ print $1 }’ que en si el programa a ejecutar, a primera instancia parecera que solo decimos que imprima el primer campo $1, pero en realidad es mas que eso como veremos en el proximo ejemplo aca estamos haciendo una evaluacion.

Veamos entonces el segundo ejemplo, queremos ahora obtener un reporte de usuarios del sistema, es decir aquello que tengan un UID menor a 1000, para esto usaremos una evaluacion.

gawk -F: '$3 < 1000 { print $1 " " $7}' /etc/passwd

Si analizamos esta linea podemos apreciar que agregamos una evaluacion $3 < 1000 que es la condicion a cumplir para que luego se ejecute la accion { print $1 ” ” $7}, aca podemos observar que se agrego ” “ que es un espacion que actua como separador y un nuevo campo a imprimir $7. Como resultado de la ejecucion de este programa obtendremos un listado de nombres de usuarios seguido del shell de todas aquella cuentas con UID inferior a 1000.

Veamos ahora un ultimo ejemplo para terminar de emprolijar nuestro informe:

gawk -F: 'BEGIN { print "Usuario\t Shell\n------- -----" } $3 < 1000 { print $1 "\t" $7}' /etc/passwd

Es fácil entender que esta linea agrega una cabecera al informe y usa un par de caracteres de escape para formatear mas prolijamente nuestro informe.  Existe un completo manual para este lenguaje y muchos tutoriales en español.

Bueno espero que le sirva para conocer esta util herramienta y la adopten para su uso habitual. Comenten no sean vagos.

Invitación para colaboradores

RetroNet invita a todos los interesados en convertirse en colaboradores del sitio a registrarse y enviarme una mail para asignar el rol correspondiente, puede ser autor o editor segun los prefieran. La idea es lograr un staff de miembros que enriquezcan el contenido de la pagina con sus aportes, se buscan especialmente programadores en lenguajes como ser Java, C#, Perl, Ruby, etc. y administradores de sistemas para plataformas Windows y todas las variantes de Unix.

¿Para que sirve esta funcion?

He escrito una muy simple función en Python, ¿alguien me puede explicar para que sirve?

def incognita(n):
    return not (n & 1);

Hay que tener en cuenta que recibe como argumento un numero entero. Descubre su propósito y explicalo.

Listas por comprension en python

Una de las esctructuras de datos mas versatiles y utilizadas a la hora de programar son las listas, en python en particular asumen un rol de gran importancia por ser muy potentes para combinarlas con iteradores, generar listas a partir de otras listas es una tarea frecuente en la programacion, veamos algunos ejemplos de listas en Python:

numeros = [21, 1, 5, 32, 97]
dias = ['lunes', 'martes', 'miercoles', 'jueves', 'viernes', 'sabado', 'domingo']
pares = range(2,100,2)

Una lista por comprension es una forma natural, facil y elegante de generar nuevas listas mediante el proceso de una pre-existente. Vamos un ejemplo.

digitos = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

cuadrados = [digito * digito for digito in digitos]

Podemos observar que dada una lista compuesta por los 10 digitos del sistema de numeracion decimal, podemos procesar esa lista para obtener una nueva lista formada por los cuadrados de esos digitos. Como se leeria el codigo, tomar secuencialmente de a uno los elementos de la lista digitos, asignarlo a la variable digito y multiplicar esta por si misma, luego, almacenar cada resultado en una nueva lista.
Como podemos observar es una manera simple y natural de procesar listas, pero su poder no se limita al simple ejemplo que puse, probemos hacer algunos ejercicios, van a continuacion un par de enunciados.

  1. dada una lista formada por los dias de la semana convertirla a mayusculas
  2. generar con range una lista con los 50 primeros impares y mediante listas por comprension generar una nueva lista que este formada por cada numero de la primer lista mas 10.

Yojota resolvio ambos problemas, a continuacion la solucion propuesta:

#! /usr/bin/python
#listas por comprension
import string
alta = str
dias = ['lunes', 'martes', 'miercoles', 'jueves', 'viernes', 'sabado', 'domingo']
mayuscula = [string.upper(alta) for alta in dias]
print mayuscula
lista2 = [n + 10 for n in (range(1,50,2))]
print lista2

Desafio python, divisores y cubos

Sabiendo que los divisores propios de un número son  todos los numeros que resultan en una division entera menos el propio número, podemos escribir una breve funcion en python que devuelva una lista con los divisores de un numero dado:

def divisoresPropios(n):
   lista=[]
   for i in range(1,(n/2)+1):
       if (n%i)==0:
           lista.append(i)
   return lista

Si tomamos los divisores propios de un numero y los multiplicamos, luego buscamos aquellos números cuyo producto de divisores es igual al cuadrado del numero dado vamos a encontrar 16 numeros que cumplen con esa condicion, por ejemplo, tomemos el 12 que es el primero de ellos, sus divisores son [1, 2, 3, 4, 6] si los multiplicamos obtenemos:

1 * 2 * 3 * 4 * 6 = 144

Que es igual a 12 al cuadrado:

12 * 12 = 144

El desafio consiste en encontrar los otros 15 numeros menores a 100 que cumplen esta condicion. A ver quien se anima?

Excelente solucion encontrada por Daniel:

def divisoresPropios(n):
        lista=[]
        for i in range(1,(n/2)+1):
                if (n%i)==0:
                        lista.append(i)
        return lista

def producto(l):
        rlt = 1
        for num in l:
                rlt *= num
        return rlt

for i in range(1, 100):
        if producto(divisoresPropios(i)) == i*i:
                print 'ncontrado:', i

Problema facil en C

Se pretende hacer un programa que imprima 20 guiones “-”. Para ello he escrito el siguiente codigo.

#include <stdio.h>
int main()
{
    int i;
    int n = 20;
    for( i = 0; i < n; i-- )
        printf("-");
    return 0;
}

Es fácil darse cuenta donde esta el error, el desafío consiste en modificar el programa para que funcione correctamente cambiando solo un carácter del código fuente original. Se sabe que existen tres posibles soluciones, ¿alguien se anima a encontrar alguna o todas?

Dos soluciones encontradas por lionheart:

La primera.

#include <stdio.h>
int main()
{
    int i;
    int n = 20;
    for( i = 0; -i < n; i-- )
        printf("-");
    return 0;
}

La segunda.

#include <stdio.h>
int main()
{
    int i;
    int n = 20;
    for( i = 0; i < n; n-- )
        printf("-");
    return 0;
}

Vamos por la ultima!

Julio Tentor encontro la ultima solicion:

#include
int main()
{
    int i;
    int n = 20;
    for( i = 0; i + n; i-- )
        printf(“-”);
    return 0;
}

El KamaSutra y la criptografía

Leyendo sobre la historia de la criptografía en la Wikiedia me encontré con un dato bastante curioso, en el tratado indu sobre sexualidad KamaSutra se describe un método de encriptación por sustitución para que los amantes puedan comunicarse sin riesgo de ser descubiertos, aunque en realidad es muy poco eficiente sobre todo sabiendo del amor por las matemáticas y ciencias relacionadas de los indues, por lo que posiblemente muchas infidelidades pudieron ser descubiertas. Hacer un programa que sea capaz de encriptar un mensaje secreto mediante el método de sustitución monoalfabetica es bastante sencillo, ¿alguien se anima a publicar código?

Yojata, un prolifico programador propone la siguiente solucion:

#! /usr/bin/python
encriptada= ''
cadena = raw_input("Ingrese la cadena: ")
for i in range(0,len(cadena)): encriptada += chr(1+ord(cadena[i]))
print "Cadenana encriptada: ", encriptada

La que funciona perfectamente, ahora bien, estaria bueno crear el codigo necesario para convertirlo en una funcion que reciba dos parametros, el primero con la cadena a procesar y el segundo con un valor booleano siendo True encriptar y False desencriptar. De esta manera la funcion servira tanto para codificar como para decodificar la cadena. ¿Alguien se anima?

Desafio de análisis forense

El Honeynet Project acaba de publicar el  Forensic Challenge 5 – Log Mysteries. Trata sobre máquinas virtuales y análisis de logs confusos. Hay que determinar qué ha ocurrido con un servidor virtual utilizando todos los logs de un servidor posiblemente comprometido. El Challenge 5 ha sido creado por Raffael Marty del Bay Area Chapter, Anton Chuvakin del Hawaiian Chapter, y Sebastien Tricaud del French Chapter. La fecha límite de entrega es el día 30 de septiembre y los ganadores serán anunciados el 21 de octubre. Habrá algunos premios para los tres mejores.

Generador de números primos C++

Este es un pequeño ejemplo de programa en C++ para generar números primos hasta un determinado limite ingresado por teclado.

#include <iostream>
using namespace std;

int main()
{
    int i, j, limite;
    cout << "Ingrese limite: ";
    cin >> limite;
    for ( i = 2; i < limite; i++ )
    {
        for ( j = 2; j <= i/2; j++ )
        {
            if ( ! ( i % j ) ) break;
        }
            if ( j > i / 2 ) cout << i << endl;
    }
    return 0;
}

Para compilar:

luis@ono-senday:~/desarrollo/primos$ c++ main.cpp -o primos

No es lo mas eficiente pero funciona, a ver que aportes pueden hacer con otros algoritmos con el mismo proposito.