domingo, 31 de agosto de 2008

Convertir fichero .nrg a .iso

Para convertir un fichero .nrg al formato .iso en linux sin necesidad de ningún programa adicional tan solo hay que ejecutar el siguiente comando.

dd bs=1k if=imagen.nrg of=imagen.iso skip=300

La explicación, con este comando lo que hacemos es copiar el fichero quitando los primeros 300kB (skip indica el número de bloques que no queremos copiar y bs es el block size).

En realidad un fichero .nrg y uno .iso se diferencian simplemente en eso, nero añade esa cabecera con información propia.

Hay un programa que hace esta misma conversión en linux, nrg2iso.
Este programa está hecho en c, la conversión la realiza de esta manera.

fseek (nrgFile, 307200, SEEK_SET);

El resto del programa es básicamente una copia de ficheros, al igual que hace el comando dd, en este caso salta 307200 bytes, que en realidad corresponde a los 300kB mencionados arriba (300*1024).

sábado, 30 de agosto de 2008

Ficheros abiertos por un proceso

Para localizar los procesos que están usando un fichero en linux tenemos el comando fuser. En concreto ejecutando lo siguiente.

fuser -va fichero (fichero también puede ser un directorio).

fuser -km fichero (mata todos los procesos que acceden al fichero).

Una funcionalidad similar se puede obtener con lsof, además lsof también permite ver los sockets abiertos.

lsof fichero

Ejecutando simplemente lsof se muestran todos los fichero abiertos así que podemos filtrar mejor con grep.

lsof | grep fichero
lsof | grep UDP (sockets udp abiertos).

miércoles, 27 de agosto de 2008

Hacer copia de seguridad del MBR

Si instalamos y reinstalamos frecuentemente distintos sistemas operativos en el mismo disco duro es frecuente perder el MBR (Master Boot Record).

Cuando ya tenemos un MBR que nos sirve y no lo queremos perder en ninguna reinstalación podemos hacer una copia de seguridad, para ello hay que ejecutar el siguiente comando.

dd if=/dev/sda of=/mbr.bak bs=512 count=1

Donde /dev/sda es el disco duro y /mbr.bak la copia de seguridad, para reestablecer la copia de seguridad tan solo hay que hacer.

dd if=/mbr.bak of=/dev/sda bs=512 count=1

El problema al hacerlo así es que también estamos sobreescribiendo la tabla de particiones, para no afectar a la tabla de particiones sobreescribiendo el gestor de arranque hay que escribir solo los primeros 446 bytes.

dd if=/dev/sda of=/mbr.bak bs=446 count=1
dd if=/mbr.bak of=/dev/sda bs=446 count=1

martes, 26 de agosto de 2008

Matar procesos selectivamente en linux

Para terminar (matar) procesos en linux se suele usar la orden kill pid o killall programa pero hay otra forma de hacerlo más potente.

El comando en cuestión es pkill, dejo una guía rápida de las opciones que permite, siempre se pueden combinar varias.

pkill -u usuario mata todos los procesos de un usuario.

pkill patron mata todos los procesos en los que el patrón esté incluído en el nombre.

pkill -n patron mata al proceso más nuevo de los que coinciden con el patrón.

pkill -o patron mata al proceso más antiguo de los que coinciden con el patrón.

pkill -x patron mata los procesos en los que el nombre coincide exactamente con el patrón.

pkill -v -u usuario mata todos los procesos que no son del usuario (-v invierte el efecto de la acción).

Hay algunas opciones más, para verlas todas man pkill.

domingo, 24 de agosto de 2008

Número de argumentos variables en C

Para crear un método que acepte un número de argumentos variables en C hay que incluir la cabecera stdarg, una vez incluída podremos acceder a las macros va_start, va_arg y va_end.

va_start acepta como parámetro el último parámetro antes de la lista variable.
va_arg necesita el tipo del parámetro que hay que devolver.
va_end libera los recursos usados para la lectura de parámetros.

#include <stdio.h>
#include <stdarg.h>

int sumatorio(int howmany, ...){
int i;
int total = 0;
va_list ap;

va_start(ap, howmany);

for (i=0; i<howmany; i++)
total+=va_arg(ap, int);

va_end(ap);

return total;
}

int main(){
printf("%d\n", sumatorio(4, 1,2,3,4));
}

Comprobaciones numéricas en C

Es conocido que C es un lenguaje muy potente pero a muy bajo nivel, esto tiene algunas consecuencias al trabajar con valores numéricos que con otros lenguajes ni nos plantearíamos.

En primer lugar, ¿qué devuelven las funciones matemáticas en caso de que no exista un resultado a su operación?

Hay algunas funciones matemáticas como la raíz cuadrada y el logaritmo que no siempre tienen solución, en estos casos se devuelve nan (Not A Number) y se puede comprobar con la función isnan.

Otra situación posible es llegar a un valor infinito, ¿qué ocurre entonces? pues se devuelve inf y se puede comprobar con isinf.

Aquí un ejemplo de como se puede llegar a estas situaciones, para compilar gcc prog.c -o prog -lm.

#include <stdio.h>
#include <math.h>

int main(){
float dividendo=999999999;
float divisor=0.000000000000000000000000000000001;
float num=dividendo/divisor;

if(isinf(num)) printf("Infinito\n");
printf("%f\n",num);

num=sqrt(-num);
if(isnan(num)) printf("Not a number\n");

printf("%f\n",num);
}

viernes, 22 de agosto de 2008

Threads en ruby

El manejo de threads en ruby es muy sencillo, la creación de threads se basa en pasar un bloque a la creación de un objeto de la clase thread.

#!/usr/bin/ruby

t1 = Thread.new do
10.times do
puts "hello from thread 1"
sleep(0.2)
end
end

t2 = Thread.new do
10.times do
puts "hello from thread 2"
sleep(0.2)
end
end

t1.join
t2.join

Para pasar parámetros se hace de la siguiente forma.

#!/usr/bin/ruby

t1 = Thread.new(1) do |id|
10.times do
puts "hello from thread #{id}"
sleep(0.2)
end
end

t2 = Thread.new(2) do |id|
10.times do
puts "hello from thread #{id}"
sleep(0.2)
end
end

t1.join
t2.join

Para controlar las secciones criticas tan solo hay que cambiar la variable de clase critical a true.

#!/usr/bin/ruby

counter = 0;

t1 = Thread.new do
100000.times do
Thread.critical = true
counter += 1
Thread.critical = false
end
end

t2 = Thread.new do
100000.times do
Thread.critical = true
counter -= 1
Thread.critical = false
end
end

t1.join
t2.join

puts counter

Se pueden consultar los demás métodos de la clase Thread en la documentación oficial.

jueves, 21 de agosto de 2008

Resaltado de expresiones regulares

A veces cuando estamos trabajando con expresiones regulares nos podemos perder un poco, para hacer más fácil la tarea se puede realizar un resaltado del matching de la siguiente forma.

#!/usr/bin/ruby

pre = "\033[7m"
post = "\033[m"

print "Cadena> "
STDOUT.flush
str = gets.chop!

while true
print "Expresion regular> "
STDOUT.flush
re = Regexp.new(gets.chop!)
puts str.gsub(re, "#{pre}\\&#{post}")
end


Un ejemplo de uso.

domingo, 17 de agosto de 2008

Patrón singleton en ruby

Singleton es un patrón de diseño en ingeniería del software, un singleton es una clase de la que solo se puede obtener un objeto. Se suele utilizar en ocasiones en las que un objeto se utiliza de forma global o por lo que sea existe la restricción de no poder crear más de un objeto de una determinada clase.

Su implementación en ruby sería la siguiente.

#!/usr/bin/ruby

class Singleton
@@instance = nil
@contador = nil

def Singleton.createInstance
@@instance ||= new
end

def Singleton.getInstance
@@instance
end


def aumentarContador
@contador = (@contador || 0) + 1
end

private_class_method :new
end

Se declara como privado el método new para evitar crear objetos de la clase.
Como se puede ver instance es una variable de clase y por lo tanto compartida, pero contador es una variable de instancia, sin embargo, si ejecutamos lo siguiente.

s = Singleton.createInstance
s2 = Singleton.createInstance
s3 = Singleton.getInstance

puts s.aumentarContador
puts s2.aumentarContador
puts s3.aumentarContador

Podemos ver que tan solo hay un objeto de la clase Singleton.

sábado, 16 de agosto de 2008

Definir métodos dinámicamente en ruby

Ruby permite la definición dinámica de métodos, para ello hay varios métodos en Class que nos ayudan.

#!/usr/bin/ruby

class Clase
end

objeto = Clase.new

Clase.send :define_method, :saludo do
puts "Hola mundo"
end

objeto.saludo if Clase.method_defined?(:saludo)

Clase.send :undef_method, :saludo

# Tambien puede usarse:
# Clase.send :remove_method, :saludo

objeto.saludo if Clase.method_defined?(:saludo)

Mediante :define_method se define dinámicamente el método saludo y luego vemos como mediante :undef_method lo podemos eliminar. Con method_defined? consultamos si el método está definido en ese momento o no.

Lo de ejecutar los métodos :define_method y :undef_method mediante send es porque son privados.

¿Qué ventajas puede tener definir los métodos dinámicamente? Pues la primera es que se puede elegir el nombre de los métodos añadidos dinámicamente ya que en lugar de símbolos como nombres también aceptan cadenas. No es una gran ventaja, pero puede ser útil en algún caso.

Además de eso donde si puede resultar muy útil la definición automática de métodos es en programas en los que las acciones posibles a ejecutar evolucionen con el tiempo.

Puede parecer que son situaciones muy rebuscadas, pero no lo son tanto, sería útil en la gran mayoría de juegos de rol, según la ocasión el protagonista puede realizar unas acciones y no otras.

viernes, 15 de agosto de 2008

Generación dinámica de javascript y css con php

El lenguaje php es usado normalmente para generar html dinámicamente según los parámetros de entrada correspondientes.

Sin embargo, no es tan conocido que con php no solo se puede generar html sino cualquier tipo de fichero, los más interesantes en diseño web son javascript y css.

Para generar distintos tipos de ficheros simplemente hay que cambiar el content-type, dejo un ejemplo de como se puede generar un fichero javascript dinámicamente.

En el fichero principal.

<html>
<script type='text/javascript' src='jscripts.php'></script>

<body>
<h1>Usando php...</h1>

<?php
echo 'hola mundo <br/>';
?>
<a href=# onclick="saludo()">Haz click</a>

</body>
</html>

En el fichero jscripts.php.

<?php 
header('Content-Type: text/javascript; charset=utf-8');
echo "function saludo(){alert('hello');}";
?>

Editar texto 'in place'

Hay un efecto muy útil que tienen muchas webs para editar texto, el texto aparece como normalmente pero si hacemos click en él aparece una caja de texto para editarlo.

Ese efecto se puede conseguir de varias formas, una de ellas es mantener dos div's con el mismo texto, uno con el texto en sí y otro con una caja de texto, luego haciendo uso del evento onclick mostrar el que queramos.

En cualquier caso podemos hacerlo también con jquery y un plugin llamado jedit.

Un ejemplo de como queda.

<html>
<head>
<script src="jquery.js" type="text/javascript"></script>
<script src="jquery.jeditable.js" type="text/javascript"></script>

<script>
$(document).ready(function() {
$(".edit").editable("edit.php");
});
</script>

</head>

<body>
<div class="edit">Texto texto texto texto texto texto texto texto texto texto texto texto texto texto texto texto texto texto texto
texto texto texto texto texto texto texto texto texto texto texto texto texto texto texto texto texto texto texto texto texto
texto texto texto texto texto texto </div>
</body>
</html>

En la web de jedit hay más ejemplos de lo que se puede hacer con este plugin.

martes, 12 de agosto de 2008

Operaciones vectoriales en C++

Una de las mejoras que tienen los nuevos procesadores sobre los antiguos es la inclusión de operaciones vectoriales o SIMD (Single Instruction Multiple Data).

Estas instrucciones básicamente operan bajo un conjunto de datos (normalmente un vector) en paralelo reduciendo brutalmente el tiempo de ejecución.

En la web de gcc sobre operaciones vectoriales se explica como se pueden usar.

Para compilarlo con gcc se pueden pasar las opciones -mmmx, -msse, -msse2, -msse3 o -m3dnow, según el procesador será mejor una u otra.

En el siguiente ejemplo se consigue una mejora de entre 5 o 6 veces usando las instrucciones SIMD en mi Pentium IV.

#include <iostream>

#define SIZE 8

using namespace std;

typedef int vectorSIMD __attribute__ ((vector_size(SIZE*4)));

int main() {
long int start, end, tiempo1, tiempo2;
int repeticiones = 9999999;

int total[] = {0, 0, 0, 0, 0, 0, 0, 0};
int sumando[] = {1, 4, 3, 7, 2, 4, 5, 6};

vectorSIMD totalV = {0, 0, 0, 0, 0, 0, 0, 0};
vectorSIMD sumandoV = {1, 4, 3, 7, 2, 4, 5, 6};

cout << "Empezando suma de vectores" << endl;
start=clock();
for (int i=0;i<repeticiones;i++){
for(int j=0;j<SIZE;j++){
total[j]+=sumando[j];
}
}
end=clock();
tiempo1=end-start;
cout << "Suma de vectores realizada en " << tiempo1 << " tics de reloj" << endl;

cout << "Empezando suma vectorial" << endl;
start=clock();
for (int i=0;i<repeticiones;i++){
totalV+=sumandoV;
}
end=clock();
tiempo2=end-start;
cout << "Suma vectorial realizada en " << tiempo2 << " tics de reloj" << endl;

cout << "Se ejecuta " << tiempo1/((float)tiempo2) << " veces mas rapido con las instrucciones SIMD" << endl;
}

sábado, 9 de agosto de 2008

Haciendo capturas de pantalla en linux

Hay algunos programas para hacer capturas de pantalla en linux, el más versátil es import que viene incluído en ImageMagick.

Para crear una captura tan solo hay que ejecutar el comando.

import captura.png (Y después seleccionar la parte de la pantalla que se quiera capturar).

import -window ventana captura.png (Para capturar la ventana 'ventana').

import -window root captura.png (Para hacer una captura de pantalla completa).

sleep 5; import -window root captura.png (Para hacer una captura completa después de 5 segundos).

Maquetación web básica con CSS

La maquetación CSS puede parecer compleja al principio pero simplifica bastante el proceso de diseño web.

Aquí dejo un boceto de como se divide una página en secciones, cada una la he dejado de un color para distinguirlas mejor.

En el fichero html.

<html>
<head>
<link rel="stylesheet" type="text/css" href="styles.css" />
<title>Titulo</title>
</head>

<body>
<div id="page">
<div id="top"></div>
<div id="leftContent"></div>
<div id="centerContent"></div>
<div id="rightContent"></div>
<div id="foot"></div>
</div>
</body>
</html>

En el fichero CSS.

#page{
width: 800px;
height: 550px;
}

#top{
width: 800px;
height: 100px;
background-color: blue;
}

#leftContent{
width: 200px;
height: 350px;
background-color: yellow;
float:left;
}

#centerContent{
width: 400px;
height: 350px;
background-color: green;
float:left;
}

#rightContent{
width: 200px;
height: 350px;
background-color: red;
float:left;
}

#foot{
width: 800px;
height: 100px;
background-color: blue;
float: left;
}

Y el resultado en el navegador.

viernes, 8 de agosto de 2008

SVN fácil y rápido

Para administrar el código de proyectos con algo de dimensión se suelen/deben usar sistemas de control de versiones. El más usado seguramente es Subversion (svn).

Dejo una lista de los comandos más habituales.


svnadmin create "path al repositorio" (Crea un repositorio)

svn checkout "path al repositorio" (Copia un repositorio localmente)

svn update fichero (Actualiza el fichero a la última versión)

svn update -rV fichero (Actualiza el fichero a la versión V)

svn add fichero (Añade el fichero al repositorio)

svn delete fichero (Elimina el fichero del repositorio)

svn copy fichero1 fichero2 (Copia el fichero en el repositorio)

svn move fichero1 fichero2 (Mueve el fichero en el repositorio)

svn revert fichero (Elimina los cambios hechos al fichero localmente)

svn diff fichero (Muestra las diferencias creadas localmente con la última versión)

svn diff fichero@1 fichero@2 (Muestra las diferencias entre la versión 1 y la 2)

svn commit fichero (Sube el fichero al repositorio)

svn resolve fichero
(Resuelve los conflictos del fichero, lo deja listo para poder subirlo)

domingo, 3 de agosto de 2008

Cambiando la apariencia de las webs con Greasemonkey

Greasemonkey es una extensión para firefox que permite aplicar automáticamente nuestro código javascript al entrar en una web.

Hay miles de scripts en internet pero lo interesante es que resulta muy fácil crear uno desde cero en muy poco tiempo para cambiar lo que no nos gusta de los sitios que visitamos. Incluso se pueden añadir nuevas funcionalidades.

Aquí dejo un ejemplo de como se puede convertir con Greasemonkey la portada de google.es a "irish google".

// ==UserScript==
// @name firstscript
// @namespace http://javiyu.es
// @include http://www.google.es*
// ==/UserScript==

//Cambia el color de fondo
document.body.bgColor="448844";

//Quita la barra de arriba si has accedido con tu cuenta
var guser=document.getElementById('guser');
if(guser){
guser.parentNode.removeChild(guser);
}

var gbar=document.getElementById('gbar');
if(gbar){
gbar.parentNode.removeChild(gbar);
}

var gbhs=document.getElementsByClassName('gbh');
while(gbhs.length>0){
gbhs[0].parentNode.removeChild(gbhs[0]);
}

//Quita el logo de google
var divs=document.getElementsByTagName('div');
for(i=0;i<divs.length;i++){
if(divs[i].title=="Google"){
divs[i].style.background="url(http://www.garmentrecoverysystems.com/images/irish_flag.jpg)";
divs[i].style.width="500px";
divs[i].style.height="150px";

divs[i].textContent="";
}
}

//Cambia el texto de los botones
var inputs=document.getElementsByTagName('input');
for(i=0;i<inputs.length;i++){
if(inputs[i].value=="Voy a tener suerte")
inputs[i].value="Soy un suertudo";

if(inputs[i].value=="Buscar con Google")
inputs[i].value="Busca leprechaun!";
}

Aquí el resultado

viernes, 1 de agosto de 2008

Efectos javascript con script.aculo.us

Para crear webs atractivas con multitud de efectos en javascript sin perder demasiado tiempo hay muchas librerías, a mi la que mas me gusta es script.aculo.us.

La instalación consiste en los siguientes pasos:

1) Bajar el fichero con la última versión de la web.

2) Descomprimir el fichero.

3) Copiar fichero prototype.js (directorio lib) y builder.js, controls.js, dragdrop.js, effects.js, scriptaculous.js, slider.js, sound.js y unittest.js (directorio src) en nuestra carpeta de javascripts.

4) Añadir las siguientes líneas a nuestra página web.

<script src="javascripts/prototype.js" type="text/javascript"></script>
<script src="javascripts/scriptaculous.js" type="text/javascript"></script>

En la documentación oficial se pueden encontrar detalladas todas las posiblidades, aquí os dejo un ejemplo con algunos efectos.

<html>
<head>
<script src="javascripts/prototype.js" type="text/javascript"></script>
<script src="javascripts/scriptaculous.js" type="text/javascript"></script>
<title></title>
</head>

<body>
<p id="texto">TextoTextoTextoTexto TextoTextoTextoTexto <br/>
TextoTextoTextoTexto TextoTextoTextoTexto TextoTextoTextoTexto</p>

<button type="button" onclick="new Effect.Highlight($('texto'));">Highlight</button>

<button type="button" onclick="$('texto').morph('background:#00ffff; width:300px;');">Morph</button>

<button type="button" onclick="$('texto').morph('background:#ffffff; width:600px;');">UnMorph</button>

<button type="button" onclick="new Effect.Move($('texto'),{x:60, y:60 });">Move</button>

<button type="button" onclick="new Effect.Scale($('texto'),200);">Scale</button>

<button type="button" onclick="new Draggable($('texto'));">Draggable</button>
</body>
</html>