Crear la base de datos de una red social puede parecer en principio muy complicado, nada más lejos de la realidad, lo que seguramente sea más difícil es optimizar los accesos en caso de que obtenga un gran número de usuarios.
Suponiendo que usamos el modelo relacional, deberíamos crear una tabla de usuarios tal como:
id | datos
Dónde id es un identificador único para cada usuario y datos son los datos específicos que queremos guardar, nombre, apellidos, email, etc.
No todos los datos personales como tales pueden/deben ir ahí, si por ejemplo queremos guardar las aficiones y poder estudiarlas más tarde deberíamos tener una tabla aficiones.
id | aficion
Al igual que podemos crear grupos de usuarios de una forma similar.
id | grupo
Y otra tabla propia a la información de cada grupo.
grupo | informacion_relevante
Con unas consultas simples podemos reconstruir toda la información relativa a estos datos.
La mayor utilidad de las redes sociales es el enlace entre usuarios, así que también necesitaremos guardar esta información en una tabla llamada enlaces o amigos.
id1 | id2
Podemos tener otras si tenemos varios tipos de relaciones (por cierto no me ha parecido ver esto implementado en ninguna red social, tan solo amistad).
Una de las utilidades más usadas de las redes sociales es la de etiquetar a gente en las fotos.
Se me ocurren dos formas de implementarlo, teniendo una tabla global de fotografías (grandísima) o creando una tabla por fotografía (muchísimas tablas). Creo que la segunda escalaría peor que la primera, pero es cuestión de probarlo en un DBMS concreto.
Las otras aplicaciones como tablón, envío de mensajes, solicitudes pendientes de amigos...no difieren demasiado de estas.
Como se puede ver conceptualmente la base de datos de una red social no es nada complicada comparada con otras aplicaciones, sin embargo hay que tener en cuenta que optimizarla para soportar 80 millones de usuarios que tiene facebook debe ser algo más complicado.
viernes, 27 de junio de 2008
miércoles, 25 de junio de 2008
Otra visión de top
Hay varias formas de mostrar los procesos que están ejecutándose en linux, ps, top, pstree...pero hay otro comando menos popular y quizá más útil, htop.
Aquí os dejo una captura de pantalla.
Aparte de estar la información mejor organizada en la pantalla se pueden organizar los procesos por CPU gastada, memoria entre otras cosas, además se puede cambiar la prioridad de procesos, organizarlos en árbol e incluso matarlos.
Todo ello con una tecla.
Aquí os dejo una captura de pantalla.
Aparte de estar la información mejor organizada en la pantalla se pueden organizar los procesos por CPU gastada, memoria entre otras cosas, además se puede cambiar la prioridad de procesos, organizarlos en árbol e incluso matarlos.
Todo ello con una tecla.
Etiquetas:
linux
Modificar cookies
La mayoría de webs en las que hay que registrarse nos mandan cookies con información necesaria para comprobar que somos nosotros. Es posible que nosotros también lo necesitemos para crear nuestras propias webs.
Para depurar, se puede ver cual es el valor actual de las cookies mandada por la página actual usando el siguiente script en la barra de navegación.
Si queremos, podemos mostrar las cookies separadas por campos para que resulte más claro. Simplemente necesitamos iterar sobre el script anterior.
Para depurar, se puede ver cual es el valor actual de las cookies mandada por la página actual usando el siguiente script en la barra de navegación.
javascript:void(document.cookie=prompt("Cambiar cookie",document.cookie).split(";"))
Si queremos, podemos mostrar las cookies separadas por campos para que resulte más claro. Simplemente necesitamos iterar sobre el script anterior.
javascript:for(var g in document.cookie.split(";"))void(prompt("Cambiar cookie "+document.cookie.split(";")[g].split("=")[0],document.cookie.split(";")[g].split("=")[1]));alert("Cookies:\n"+document.cookie.replacer(/;/,"\r\n"));
Etiquetas:
javascript,
web
martes, 24 de junio de 2008
Descomprimir ficheros en python
Para descomprimir ficheros en python podemos usar la librería gzip. Puede resultar muy útil para guardar de forma eficiente el estado de nuestros programas y posteriormente recuperarlo.
Aquí un ejemplo.
Como se puede ver tan solo es necesario llamar al método open del módulo gzip y ya podemos tratarlo como un fichero descomprimido.
Aquí un ejemplo.
#!/usr/bin/python
import gzip;
f=open("prueba.txt", "r");
texto=f.read();
print texto;
print "----------------";
comprimido=gzip.open("prueba.gz", "r");
descomprimido=comprimido.read();
print descomprimido;
Como se puede ver tan solo es necesario llamar al método open del módulo gzip y ya podemos tratarlo como un fichero descomprimido.
Etiquetas:
programacion,
python
Expresiones regulares en python
Uno de los módulos mas interesantes en python es el que se encarga de proporcionarnos las funcionalidades de las expresiones regulares. Este módulo se llama re.
Veamos un ejemplo de uso.
En estos ejemplos se está usando el método search, search busca coincidencias en toda la cadena. También existe match que tan solo busca coincidencias desde el principio de la cadena.
El primer ejemplo es el más sencillo, se busca la subcadena "cadena" dentro del texto.
En el segundo se introduce el uso del operador ".", que equivale a cualquier carácter.
En el tercer ejemplo se reúne el OR de dos consultas, palabras de un carácter con espacios a los dos lados y palabras con dos caracteres.
En el cuarto se busca cualquier número que haya en la cadena.
En el quinto justo lo contrario que en el cuarto, la ausencia de números.
En el sexto ejemplo se comprueba si la cadena termina con los caracteres "ga", para comprobar el comienzo de la cadena se usa "^".
Las expresiones regulares no son muy útiles si no podemos recuperar subcadenas de los textos que tratamos, se hace de la siguiente forma.
En el caso de usar search buscamos las primera palabra seguida de espacio, en el caso de findall se devuelve una lista con todas las coincidencias.
Veamos un ejemplo de uso.
#!/usr/bin/python
import re;
cadena_larga="esto es una cadena muy larga";
if(re.search("cadena", cadena_larga)):
print "caso 1: presente";
else:
print "caso 1: ausente";
if(re.search("ca.ena", cadena_larga)):
print "caso 2: presente";
else:
print "caso 2: ausente";
if(re.search("\s.\s|\s..\s", cadena_larga)):
print "caso 3: presente";
else:
print "caso 3: ausente";
if(re.search("[0-9]", cadena_larga)):
print "caso 4: presente";
else:
print "caso 4: ausente";
if(re.search("[^0-9]", cadena_larga)):
print "caso 5: presente";
else:
print "caso 5: ausente";
if(re.search("ga$", cadena_larga)):
print "caso 6: presente";
else:
print "caso 6: ausente";
En estos ejemplos se está usando el método search, search busca coincidencias en toda la cadena. También existe match que tan solo busca coincidencias desde el principio de la cadena.
El primer ejemplo es el más sencillo, se busca la subcadena "cadena" dentro del texto.
En el segundo se introduce el uso del operador ".", que equivale a cualquier carácter.
En el tercer ejemplo se reúne el OR de dos consultas, palabras de un carácter con espacios a los dos lados y palabras con dos caracteres.
En el cuarto se busca cualquier número que haya en la cadena.
En el quinto justo lo contrario que en el cuarto, la ausencia de números.
En el sexto ejemplo se comprueba si la cadena termina con los caracteres "ga", para comprobar el comienzo de la cadena se usa "^".
Las expresiones regulares no son muy útiles si no podemos recuperar subcadenas de los textos que tratamos, se hace de la siguiente forma.
#!/usr/bin/python
import re;
cadena_larga="esto es una cadena muy larga";
parsed=re.search("(\S+)\s",cadena_larga);
print parsed.groups();
print re.findall("(\S+)\s",cadena_larga);
En el caso de usar search buscamos las primera palabra seguida de espacio, en el caso de findall se devuelve una lista con todas las coincidencias.
Etiquetas:
programacion,
python
sábado, 7 de junio de 2008
Leyendo correo POP3 desde python
Acceder a una dirección de correo electrónico desde python es muy sencillo si se tiene habilitado POP3.
Para ello se puede usar la librería poplib. Para los ejemplos usaré gmail, si queréis probarlo acordaros de habilitar POP3 en la web de gmail.
Primero creamos un objeto POP3_SSL, (gmail funciona con SSL), metemos usuario y contraseña.
A partir de entonces ya podemos administrar el correo con las funciones que nos provee la librería poplib.
En el ejemplo se obtiene la lista de mensajes con list(), se elige de la respuesta el último mensaje y se le pide al servidor mediante retr(msgid). Es necesario parsear la salida puesto que lo que tenemos hasta el momento es la respuesta en bruto del servidor, pero si leéis en pantalla ya podeis distinguir de que mensaje se trata.
Usando esto podemos crear muy fácilmente un programa que revise nuestro buzón de correo y nos avise cuando nos llega un nuevo mensaje.
El script no está probado, solo es un ejemplo de como se podría crear algo útil con esta librería.
Para ello se puede usar la librería poplib. Para los ejemplos usaré gmail, si queréis probarlo acordaros de habilitar POP3 en la web de gmail.
#!/usr/bin/python
import poplib;
p=poplib.POP3_SSL("pop.gmail.com");
p.user("usuario@gmail.com");
p.pass_("pass");
mensajes=p.list()[1];
lastmsg=mensajes[-1].split()[0];
print p.retr(lastmsg);
p.quit();
Primero creamos un objeto POP3_SSL, (gmail funciona con SSL), metemos usuario y contraseña.
A partir de entonces ya podemos administrar el correo con las funciones que nos provee la librería poplib.
En el ejemplo se obtiene la lista de mensajes con list(), se elige de la respuesta el último mensaje y se le pide al servidor mediante retr(msgid). Es necesario parsear la salida puesto que lo que tenemos hasta el momento es la respuesta en bruto del servidor, pero si leéis en pantalla ya podeis distinguir de que mensaje se trata.
Usando esto podemos crear muy fácilmente un programa que revise nuestro buzón de correo y nos avise cuando nos llega un nuevo mensaje.
#!/usr/bin/python
import poplib;
import time;
oldmensajes=0;
nmensajes=0;
first=1;
while(1):
p=poplib.POP3_SSL("pop.gmail.com");
p.user("usuario@gmail.com");
p.pass_("pass");
nmensajes=p.stat()[0];
print nmensajes;
p.quit();
if(first==1):
oldmensajes=nmensajes;
first=0;
if(nmensajes!=oldmensajes):
print "Se ha recibido " + str(nmensajes-oldmensajes) + " mensaje(s) nuevos";
nmensajes=oldmensajes;
time.sleep(300);
El script no está probado, solo es un ejemplo de como se podría crear algo útil con esta librería.
Etiquetas:
programacion,
python
Importación de módulos en python
En python hay varias formas de importar módulos, la primera de ellas es la siguiente.
Se importa la librería math pero después para hacer uso de la función sqrt es necesario especificar que viene de esta librería en concreto.
Se hace así para diferenciar que funciones vienen de cada librería y que no haya confusión de a que función estamos llamando.
Si por ejemplo disponemos de una librería matemática más rapida pero menos completa, para sustituir esta llamada se podría hacer math2.sqrt(80) sin ningún problema.
La segunda manera de importar módulos es como sigue.
En esta ocasión nos ahorramos especificar en la llamada de donde viene la función sqrt pero debe especificarse en la importación.
Esta forma de importar funciones de los módulos hace que quede muy claro que funciones se usan y de donde provienen, además simplifica la sintaxis en la llamada pero tiene un problema; si tenemos en cuenta el ejemplo de antes, debemos saber de antemano que llamadas vamos a usar de math y de math2 y no podríamos usar sqrt de las dos en el mismo programa.
La tercera forma es la siguiente.
Es igual a la primera pero sin necesidad de indicar el espacio de nombres en cada llamada, tiene el mismo problema de la segunda y en general es considerado un mal hábito de programación. Se están importando multitud de nombres que pueden colisionar con los del programa y no provee ninguna utilidad especial.
En conclusión, para scripts pequeños de unas cuantas líneas me quedaría con la segunda o la tercera por sencillez, pero si se pretende hacer algo más grande y serio la primera opción es la adecuada.
#!/usr/bin/python
import math
print math.sqrt(80)
Se importa la librería math pero después para hacer uso de la función sqrt es necesario especificar que viene de esta librería en concreto.
Se hace así para diferenciar que funciones vienen de cada librería y que no haya confusión de a que función estamos llamando.
Si por ejemplo disponemos de una librería matemática más rapida pero menos completa, para sustituir esta llamada se podría hacer math2.sqrt(80) sin ningún problema.
La segunda manera de importar módulos es como sigue.
#!/usr/bin/python
from math import sqrt
print sqrt(80)
En esta ocasión nos ahorramos especificar en la llamada de donde viene la función sqrt pero debe especificarse en la importación.
Esta forma de importar funciones de los módulos hace que quede muy claro que funciones se usan y de donde provienen, además simplifica la sintaxis en la llamada pero tiene un problema; si tenemos en cuenta el ejemplo de antes, debemos saber de antemano que llamadas vamos a usar de math y de math2 y no podríamos usar sqrt de las dos en el mismo programa.
La tercera forma es la siguiente.
#!/usr/bin/python
from math import *
print sqrt(80)
Es igual a la primera pero sin necesidad de indicar el espacio de nombres en cada llamada, tiene el mismo problema de la segunda y en general es considerado un mal hábito de programación. Se están importando multitud de nombres que pueden colisionar con los del programa y no provee ninguna utilidad especial.
En conclusión, para scripts pequeños de unas cuantas líneas me quedaría con la segunda o la tercera por sencillez, pero si se pretende hacer algo más grande y serio la primera opción es la adecuada.
Etiquetas:
programacion,
python
Suscribirse a:
Entradas (Atom)