<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Segmentation Fault! &#187; Programación</title>
	<atom:link href="http://www.segmentationfault.es/category/programacion/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.segmentationfault.es</link>
	<description>La formulación de un problema es más importante que su solución.</description>
	<lastBuildDate>Tue, 29 Jun 2010 19:45:33 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>How to backup your server to Amazon S3</title>
		<link>http://www.segmentationfault.es/2010/06/how-to-backup-your-server-to-amazon-s3/</link>
		<comments>http://www.segmentationfault.es/2010/06/how-to-backup-your-server-to-amazon-s3/#comments</comments>
		<pubDate>Tue, 29 Jun 2010 19:39:27 +0000</pubDate>
		<dc:creator>Christopher Vallés</dc:creator>
				<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[7z]]></category>
		<category><![CDATA[amazon s3]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[s3cmd]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.es/?p=1725</guid>
		<description><![CDATA[This post is a HowTo about backups to Amazon S3 using some tools like 7z, s3cmd and a couple of bash scripts.]]></description>
			<content:encoded><![CDATA[<p>Since a few months ago I&#8217;m taking care of three ubuntu servers with different services like svn, mysql, websites, etc. and for sure I want to provide a flexible, secure and cheap backup system to my customers.</p>
<p>I started playing around with <a href="http://s3tools.org/s3cmd" target="_blank">s3cmd</a> command line utility and I realize that is really powerful so, I decide to write my own scripts to be able to backup automatically all the important files of my servers to the cheaper and easy to use <a href="http://aws.amazon.com/s3/" target="_blank">Amazon S3</a> service.</p>
<p>The whole system is based on two bash scripts, the crontab and a few extra applications like <a href="http://p7zip.sourceforge.net/" target="_blank">7zip</a> and s3cmd. I will explain step by step how I build up the system and at the end I&#8217;ll provide the full code of the scripts.</p>
<h4>Requirements</h4>
<p>The first step is to be sure that you have installed the 7zip and s3cmd tools, in my case I&#8217;m using ubuntu so, for me the command to install the tools is:</p>
<pre class="brush: bash;">
sudo apt-get install p7zip s3cmd
</pre>
<h4>Basic setup</h4>
<p>Now we can follow with the basic setup, I created a folder in the root of the filesystem called backups, the inside this folder I create serveral folders, at the end the structure is like follow:</p>
<pre class="brush: bash;">
/backups
    /compressed
    /data
        /db
        /svn
        /www
    /scripts
</pre>
<p>The compressed folder is used at the end of the script to compress all the files to one .7z file, in the data folder we will copy the information we want to backup and in the scripts folder we will store as it&#8217;s name says the two scripts we will use.</p>
<h4>Backup script</h4>
<p>Now, let&#8217;s have a look at those scripts. The first one is to do the backup, in my case I&#8217;m doing a backup of the subversion, mysql and files under /var/www.</p>
<p>The script starts with the following block:</p>
<pre class="brush: bash;">
echo `date '+%F %T'`: Starting the backup

#Dumping the repos
echo `date '+%F %T'`: Starting the dump of the repos
for i in /user/local/svn/*/; do
    repo=`basename $i`
    echo `date '+%F %T'`: Dumping repo $repo
    /usr/bin/svnadmin dump /usr/local/svn/$repo &gt; /backups/data/svn/$repo.dump
    echo `date '+%F %T'`: Repo $repo dumped
done
</pre>
<p>We suppose that the svn folder is located at /usr/local/svn, basically here we are going through each folder inside /usr/local/svn/ and we call svnadmin dump to dump that repository in one file, that file is stored in /backups/data/svn/.</p>
<pre class="brush: bash;">
#Dumping the DB
echo `date '+%F %T'`: Starting the dump of the DataBases
for i in /var/lib/mysql/*/; do
    db=`basename $i`
    echo `date '+%F %T'`: Dumping DB $db
    /usr/bin/mysqldump -uroot -p$db_password $db &gt; /backups/data/db/$db.sql
    echo `date '+%F %T'`: Database $db dumped
done
</pre>
<p>In this second block we are doing more or less the same thing, we are going through each folder on /var/lib/mysql/ and calling mysqldump to export each DB in one file stored at /backups/data/db/.</p>
<pre class="brush: bash;">
#Copy all the websites
echo `date '+%F %T'`: Starting the dump of websites
for i in /var/www/*/; do
    site=`basename $i`
    echo `date '+%F %T'`: Dumping site $site
    /usr/bin/7z a -mx6 -t7z /backups/data/www/$site.7z -p$compression_password /var/www/$site
    echo `date '+%F %T'`: Site $site dumped
done
</pre>
<p>In the third block we are dumping the websites, I have the websites stored at /var/www folder and each site is inside a folder with the domain as folder name. Basically we are doing the same, loop through /var/www/ and compressing each site individually in a .7z file with a compression level of 6 and secured with a password.<br />
I store each site in a separate file because if I have to restore a site I don&#8217;t need to uncompress all the sites, just the main file and then the compressed site.<br />
I was playing with different compression levels and 6 is the most suitable to maintain a good compression ratio without wasting a lot of time.</p>
<pre class="brush: bash;">
#Compressing all the data
echo `date '+%F %T'`: Compressing the info
filename=$(date +%Y%m%d)
/usr/bin/7z a -mx6 -t7z /backups/compressed/$filename.7z -p$password /backups/data/*
echo `date '+%F %T'`: Info compressed
</pre>
<p>Now with all the information we want to backup in place we will compress all together in one single file, that&#8217;s the purpose of this block of code, the final filename is a timestamp of today using the date command.</p>
<pre class="brush: bash;">
#Upload to Amazon S3
echo `date '+%F %T'`: Uploading to Amazon S3
/usr/bin/s3cmd put --no-progress /backups/compressed/$filename.7z s3://BUCKET_NAME/$filename.7z
echo `date '+%F %T'`: Upload completed
</pre>
<p>Ok, we have the compressed file and one of the final steps is upload this file to Amazon S3. For that task we are using the s3cmd tool passing the parameter &#8211;no-progress to avoid an &#8220;interactive&#8221; output of the upload status.</p>
<pre class="brush: bash;">
#Delete the local backups
echo `date '+%F %T'`: Cleaning up
rm -Rf /backups/data/svn/*
rm -Rf /backups/data/db/*
rm -Rf /backups/data/www/*
rm -Rf /backups/compressed/*
echo `date '+%F %T'`: Clean completed
echo `date '+%F %T'`: Backup completed
</pre>
<p>And the final block of code is just a clean up, after the upload to amazon we delete all the files we have generated inside the /backups folder.</p>
<p>Ok, seems complex but is pretty strightforward, also if you take a look you&#8217;ll see that all the messages contains a timestamp, with that information we are able to determine how many time we spend in each task.<br />
One disadvantage of this script is that we are not checking if the file was uploaded correctly to Amazon, maybe this will be a future improvement.</p>
<h4>Maintenance script</h4>
<p>Now let&#8217;s take a look at the other script, the purpose is just delete old backups based on a timestamp, in my case we&#8217;re storing the backups for one month, it&#8217;s very affordable with the Amazon prices. </p>
<pre class="brush: bash;">
for filename in `s3cmd ls s3://$bucket`; do
    if [[ $filename =~ ([0-9]*)\.7z ]]; then
        timestamp=${BASH_REMATCH[1]}
        echo `date '+%F %T'` - Reading metadata of: $filename
        echo -e &quot;\tFilename: $filename&quot;
        echo -e &quot;\tTimestamp: $timestamp&quot;
        if [[ $timestamp -le $limit ]]; then
            let &quot;total=total+1&quot;
            echo -e &quot;\tResult: Backup deleted\n&quot;
            /usr/bin/s3cmd del $filename
        else
            echo -e &quot;\tResult: Backup keeped\n&quot;
        fi
    fi
done
</pre>
<p>This is the only code block we have in the maintenance script, the idea is to retrieve the list of files we have in the bucket with s3cmd, then we check if the gived part contains the pattern ([0-9]*)\.7z (because the command s3cmd ls gives more information rather than just the filenames).<br />
If we detect a segment that matches the regex we get the filename without the extension (the timestamp of the backup), and we check in this case if the timestamp is older than one month (the timestamp of one month ago is stored in the $limit variable). If the backup is older we remove it calling the s3cmd del command.</p>
<p>If you need to store the files more time just change the $limit variable and that&#8217;s it.</p>
<p>Wow, seems a large process, ok, now let&#8217;s have a look at the last step to let this work, the cronjobs.<br />
I created to cronjobs and redirected the output of them to the stdout because I want to receive an email after the backup, my crontab look like this:</p>
<pre class="brush: bash;">
# m h  dom mon dow   command
MAILTO=YOUR_EMAIL_ADDRESS_HERE
00 22 * * * /backups/scripts/s3backup 2&gt;&amp;1
00 23 * * * /backups/scripts/s3backup-maintenance 2&gt;&amp;1
</pre>
<p>Just put there the values you want to run the crons and don&#8217;t forget to put at the end 2>&#038;1.</p>
<h4>Conclusion</h4>
<p>With this system you&#8217;ll have your backups in a safe and cheap place without headaches and with a full report in you email every time the script runs. For sure these scripts can be impoved with a few checks and you can extend it to fit your needs.<br />
I hope you have enjoyed this HowTo and begin to use this scripts! For sure improvements are welcomed, don&#8217;t hesitate to comment!.</p>
<h4>Source code</h4>
<p>Grab the full source code of the <a href="http://pastie.textmate.org/1023939" target="_blank">backup script</a> and the <a href="http://pastie.textmate.org/1023947" target="_blank">maintenance script</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.segmentationfault.es/2010/06/how-to-backup-your-server-to-amazon-s3/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>CSS: the &#8216;opacity&#8217; property</title>
		<link>http://www.segmentationfault.es/2010/02/css-opacity/</link>
		<comments>http://www.segmentationfault.es/2010/02/css-opacity/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 13:01:38 +0000</pubDate>
		<dc:creator>Noemí Losada</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[efectos visuales]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.es/?p=1361</guid>
		<description><![CDATA[Today we will talk about the property 'opacity' in CSS and how it works on IE and Firefox at the same time.]]></description>
			<content:encoded><![CDATA[<p>Today we will talk about the &#8216;opacity&#8217; property in CSS and how it works on IE and Firefox at the same time.</p>
<p>We will try to get the same effect as the image below:</p>
<style type="text/css">
.background{ background-image: url(/wp-content/2010/02/caracol.png); width: 300px; height: 208px; margin-right: auto; margin-left: auto; border: 1px solid #000000; } .white{ background-color: #ffffff; width: 250px; height: 158px; border: solid 1px #000000; margin: 25px 25px; opacity: 0.6; filter:alpha(opacity=60); }</style>
<div class="background">
<div class="white">This is an exemple with the property opacity of CSS</div>
</div>
<p>To create this effect you have to add the following lines on the html file:</p>
<pre class="brush: xml;">
﻿&lt;div class=&quot;background&quot;&gt;
   &lt;div class=&quot;white&quot;&gt;This is an exemple with the CSS opacity property&lt;/div&gt;
&lt;/div&gt;
</pre>
<p>The first div have the class &#8220;background&#8221; to put a standard background and the second div is inside the first div to put another background called &#8220;white&#8221; over the first background.</p>
<p>Now you can customize the classes with the following attributes and values on your css file:</p>
<pre class="brush: css;">
.background{
 background-image: url(caracol.png);
 width: 300px;
 height: 208px;
 border: 1px solid #000000;
}

.white{
 background-color: #ffffff;
 width: 250px;
 height: 158px;
 border: solid 1px #000000;
 margin: 25px 25px;
 opacity: 0.6;
 filter:alpha(opacity=60);
}
</pre>
<p>The class &#8220;background&#8221; contains an image background, the class &#8220;white&#8221; contains a background color with the opacity property to obtain the transparent effect. The attribute &#8220;opacity: 0.6;&#8221; is for Firefox and the values can go from 1.0 to 0.0, to be able to show this effect in IE you have to use the following code  &#8220;filter:alpha(opacity=60);&#8221; and the possible values can go from 100 to 0.</p>
<p>Remember to put the Doctype declaration on your HTML file to avoid the problems with the diferents bowsers and also write a stardard code.</p>
<p>I hope you enjoy it and do not hesitate if you have any doubt. <img src='http://www.segmentationfault.es/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.segmentationfault.es/2010/02/css-opacity/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>From the Array to the Object</title>
		<link>http://www.segmentationfault.es/2010/02/from-the-array-to-the-object/</link>
		<comments>http://www.segmentationfault.es/2010/02/from-the-array-to-the-object/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 12:04:20 +0000</pubDate>
		<dc:creator>Christopher Vallés</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[object]]></category>
		<category><![CDATA[recursivity]]></category>
		<category><![CDATA[stdClass]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.es/?p=1411</guid>
		<description><![CDATA[The other day working late with my colleague Tudor we found that in one point of our application we had to use an object but we had an Array. At this point we found two possible solutions, the first rewrite our code to use the Array instead the object or the second and more sophisticated solution convert the Array to an Object.]]></description>
			<content:encoded><![CDATA[<p>The other day working late with my colleague Tudor, who also have a blog at <a href="http://blog.motane.lu" target="_blank">blog.motane.lu</a>, we found that in one point of our application we had to use an object but we had an Array. At this point we found two possible solutions, the first rewrite our code to use the Array instead the object or the second and more sophisticated solution convert the Array to an Object.</p>
<p>The tricky point was that the Array could contain more Arrays so we had to write a recursive function to accomplish our objective.</p>
<p>Tudor, at the end, gave the following method to be able to do the conversion.</p>
<pre class="brush: php;">
/**
 * Recursively converts an array to a stdClass object
 *
 * @param array $array
 * @return stdClass
 */
 protected function _convertToStdObject(array $array){
   $obj = new stdClass();
   foreach($array as $key =&gt; $value) {
     if(!is_array($value)) {
       $obj-&gt;{$key} = $value;
     }else{
       $obj-&gt;{$key} = $this-&gt;_convertToStdObject($value);
     }
   }

   return $obj;
 }
</pre>
<p>Maybe, in the next interviews we will do to our PHP Developers candidates, we will ask about this and see how they solve the problem <img src='http://www.segmentationfault.es/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.segmentationfault.es/2010/02/from-the-array-to-the-object/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Debugging PHP en MacOS X</title>
		<link>http://www.segmentationfault.es/2010/01/debugging-php-macos/</link>
		<comments>http://www.segmentationfault.es/2010/01/debugging-php-macos/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 12:21:21 +0000</pubDate>
		<dc:creator>Gabi García</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[MacGDBp]]></category>
		<category><![CDATA[MAMP]]></category>
		<category><![CDATA[XDebug]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.es/?p=1334</guid>
		<description><![CDATA[En este breve post os explico los pasos que he seguido para configurar XDebug para PHP 5.2 usando MAMP Pro bajo MacOS X Snow Leopard. Espero que os resulte útil a todos los que utilizáis el lenguaje de programación PHP. ¡Se acabaron los quebraderos de cabeza por no poder debuggar vuestro código PHP! ]]></description>
			<content:encoded><![CDATA[<p>Hace unos días me decidí a poner a punto de nuevo mi MacBook y una de las cosas que he tenido que hacer es volver a configurar el debugger para PHP, concretamente XDebug. Me ha llevado mi tiempo y algunas búsquedas en Google así que he decidido compartir los pasos con todos vosotros. ¡Dispongámonos a ello!</p>
<p>Antes de nada debo decir que estos son los pasos que he seguido para instalar XDebug para PHP 5.2 usando MAMP Pro 1.8.4 bajo MacOS X Snow Leopard. Es posible que, si tenéis una configuración distinta, los pasos puedan variar un poco.</p>
<p>En primer lugar debemos descargarnos los binarios de XDebug en esta URL: <a href="http://aspn.activestate.com/ASPN/Downloads/Komodo/RemoteDebugging" target="_blank">http://aspn.activestate.com/ASPN/Downloads/Komodo/RemoteDebugging</a>.</p>
<p>Descomprimimos el archivo .tgz que nos acabamos de descargar y veremos que hay una estructura de directorios que representa las diferentes versiones de PHP. Yo actualmente estoy utilizando PHP 5.2 (la que en estos momentos incluye por defecto MAMP y MAMP Pro) así que copiaré el fichero <strong>xdebug.so</strong> que hay dentro de esta carpeta.</p>
<p>Este archivo<strong> xdebug.so</strong> deberemos copiarlo en el directorio de extensiones de PHP, en MAMP es <em>/Applications/MAMP/bin/php5/lib/php/extensions/no-debug-non-zts-20050922/</em>.</p>
<p>Ahora deberemos añadir algunas líneas a nuestro <em>php.ini</em> para activar y configurar la extensión. La localización habitual del fichero <em>php.ini </em>en MAMP es<em> /Applications/MAMP/conf/php5/php.ini</em> pero (<strong>¡OJO!</strong>) si utilizáis MAMP Pro las modificaciones en este fichero serán en vano. Esto es debido a que MAMP Pro carga su propia copia del php.ini que se localiza en <em>/Applications/MAMP PRO x.x.x/MAMP PRO.app/Contents/Resources/php5.ini</em> (accediendo haciendo clic con botón derecho sobre la app de MAMP Pro y &#8220;<em>Mostrar contenido del paquete</em>&#8220;).</p>
<p>Una vez localizado el php.ini adecuado, debemos añadir la siguiente línea:</p>
<pre class="brush: bash; toolbar: true;">
[xdebug]
zend_extension=&quot;/Applications/MAMP/bin/php5/lib/php/extensions/no-debug-non-zts-20060613/xdebug.so&quot;
</pre>
<p>Si utilizáis el editor TextMate para programar, añadid también esta línea a continuación para que el debugger muestre los errores como enlaces a TextMate en la línea correcta:</p>
<pre class="brush: bash; toolbar: true;">
xdebug.file_link_format = &quot;txmt://open?url=file://%f&amp;line=%l&quot;
</pre>
<p>Si además váis a utilizar <a href="http://www.bluestatic.org/software/macgdbp/" target="_blank">MacGDBp</a> para <em>debuggar</em> y queréis que se ejecute el <em>debugger</em> por defecto (si lo tenéis abierto) podéis añadir también (sino deberéis añadir <code>?XDEBUG_SESSION_START=macgdbp</code> a vuestra URL cada vez para iniciar el <em>debugger</em>):</p>
<pre class="brush: bash; toolbar: true;">
xdebug.remote_enable = On
xdebug.remote_autostart = 1
</pre>
<p>Para que funcione todo correctamente posiblemente deberemos desactivar el <em>Zend Optimizer</em>, que viene activado por defecto en MAMP.  Para ello, comentamos las siguientes líneas:</p>
<pre class="brush: bash; toolbar: true;">
;zend_optimizer.optimization_level=15
;zend_extension_manager.optimizer=/Applications/MAMP/bin/php5/zend/lib/Optimizer-3.3.3
;zend_optimizer.version=3.3.3
</pre>
<p>Ahora debéis reiniciar el servidor Apache y ya podréis comenzar a <em>debuggar</em> vuestras aplicaciones en PHP. Si ha funcionado ya os daréis cuenta de que los errores se muestran en una tabla muy colorida y hay una mejora muy sustancial a la hora de mostrar los resultados de var_dump.</p>
<p>Espero que os sea de utilidad y si tenéis problemas acudid a los comentarios para intentar resolverlos entre todos. ¡Salu2!</p>
<p><span style="text-decoration: underline;"><strong>Fuentes</strong></span></p>
<p>debuggable.com &#8211; <a href="http://debuggable.com/posts/setting-up-xdebug-on-mac-os-x-or-win32-linux:480f4dd6-0240-4a90-8fa1-4e41cbdd56cb" target="_blank">http://debuggable.com/posts/setting-up-xdebug-on-mac-os-x-or-win32-linux:480f4dd6-0240-4a90-8fa1-4e41cbdd56cb</a></p>
<p>Techno Sophos &#8211; <a href="http://technosophos.com/content/debugging-your-php-code-xdebug-mamp-textmate-and-macgdbp-support" target="_blank">http://technosophos.com/content/debugging-your-php-code-xdebug-mamp-textmate-and-macgdbp-support</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.segmentationfault.es/2010/01/debugging-php-macos/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Parsear ficheros CSV en PHP</title>
		<link>http://www.segmentationfault.es/2010/01/parsear-csv-en-php/</link>
		<comments>http://www.segmentationfault.es/2010/01/parsear-csv-en-php/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 00:20:37 +0000</pubDate>
		<dc:creator>Christopher Vallés</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[CSV]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.es/?p=1340</guid>
		<description><![CDATA[¿Cómo parsearías un fichero CSV? la respuesta mas común a esta pregunta suele ser con expresiones regulares pero en este post voy a tratar de explicar la manera más sencilla y a la vez potente de parsear este tipo de ficheros.]]></description>
			<content:encoded><![CDATA[<p>Desde que en Agosto cambié de empresa me he encontrado muchas veces con la necesidad de parsear ficheros CSV. Hace un tiempo que empecé a evaluar a nuevos candidatos y a todos les hacía la misma pregunta: ¿Cómo parsearías un fichero CSV? La respuesta más común a esta pregunta suele ser &#8220;con expresiones regulares&#8221; pero en este post voy a tratar de explicar la manera más sencilla, y a la vez potente, de parsear este tipo de ficheros.</p>
<p>Desde la versión 4 de PHP existen dos funciones muy útiles para estos menesteres, <strong>fgetcsv </strong>y  <strong>fputcsv</strong>.</p>
<p>Según la documentación PHP la firma de esta función es la siguiente:</p>
<pre class="brush: php;">
array fgetcsv (resource $handle [,int $length [,string $delimiter = ',' [,string $enclosure = '&quot;' [,string $escape = '\\']]]])
</pre>
<p>Como podemos ver, el primer parámetro a proporcionar es el puntero al fichero que queremos leer y después toda una serie de parámetros opcionales como la dimensión de la cadena a leer, el delimitador de campos, el carácter de envoltorio de campos y el carácter para escapar símbolos poco comunes. Esta función, al ser llamada con los parámetros correctos, devolverá la línea que ha leído en formato de array, donde cada campo será una nueva entrada en el array.</p>
<p>Bien, en este punto y antes de mostrar un trozo de código tengo que hacer mención a un detalle, esta función puede ocasionar algunos problemas dependiendo del sistema operativo en el que estemos corriendo PHP. En mi caso, utilizando Mac OS X Snow Leopard, me he encontrado que la función no detecta bien el final de la línea con lo cuál, y para ahorrarnos problemas, vamos a utilizar también la siguiente instrucción:</p>
<pre class="brush: php;">
ini_set('auto_detect_line_endings', TRUE);
</pre>
<p>Esta línea lo que hace es forzar a detectar el final de línea, lo que resuelve el problema en dichas plataformas.</p>
<p>Dicho todo esto, voy a mostrar un trozo de código que lo que hace es recorrer el fichero y generar una array de arrays con todo el fichero parseado.</p>
<pre class="brush: php;">
&lt;?php

//Prepare the auto detect line endings for some OS's
ini_set('auto_detect_line_endings', TRUE);

//Save the path to the file we want to open
$file = dirname(__FILE__) . 'test.csv';

//Create a file pointer to de file in read mode
$fp = fopen($file, 'r');

//Setup the result var
$parsedCSV = array();

/* Get the headers of the csv and store it in a special key in the array. Setting the max length to 0 strip the length constrain */
$parsedCSV['headers'] = fgetcsv($fp, 0, ',');

/* Loop to read the entire file, take a look at the comparison and remember that if fgetcsv arrives at the end of the file a FALSE will be returned. We use this to detect the EOF */
while(($line = fgetcsv($fp, 0, ',')) !== FALSE){
    $parsedCSV[] = $line;
}

//Print out the array
die(var_dump($parsedCSV));
</pre>
<p>Para detectar el final de fichero en este script estamos usando la comparación <em>($line = fgetcsv($fp, 0, &#8216;,&#8217;)) !== FALSE</em> ya que fgetcsv devuelve FALSE en caso de error o EOF (End Of File).</p>
<p>Espero que este post os sea de ayuda y recordad que podéis preguntarnos mediante el sistema de comentarios.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.segmentationfault.es/2010/01/parsear-csv-en-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Persistencia de objetos en Python</title>
		<link>http://www.segmentationfault.es/2009/11/persistencia-python/</link>
		<comments>http://www.segmentationfault.es/2009/11/persistencia-python/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 23:35:29 +0000</pubDate>
		<dc:creator>Gabi García</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[cPickle]]></category>
		<category><![CDATA[Pickle]]></category>
		<category><![CDATA[Serialización]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.es/?p=1327</guid>
		<description><![CDATA[Cuando estamos creando un programa muchas veces queremos que los datos y los resultados de la ejecución de nuestro programa no se pierdan. Es posible que el objetivo de nuestro programa sea trabajar sobre un conjunto de datos concreto que debe "mejorar" o "modificar" en cada ejecución. En este post os pretendo mostrar una forma de hacerlo posible en Python gracias a Pickle.]]></description>
			<content:encoded><![CDATA[<p>Cuando estamos creando un programa muchas veces queremos que los datos y los resultados de la ejecución de nuestro programa no se pierdan. Es posible que el objetivo de nuestro programa sea trabajar sobre un conjunto de datos concreto que debe &#8220;mejorar&#8221; o &#8220;modificar&#8221; en cada ejecución. Por lo tanto, necesitamos guardar la información en cada ejecución para poder cargarla en otra posterior ejecución.</p>
<p>Si nuestra aplicación sigue el paradigma de la orientación a objetos debemos almacenar el estado del objeto para recuperarlo a posteriori. Un posible enfoque sería almacenar toda esa información en una base de datos y trabajar así con un sistema gestor de base de datos (SGBD) como <em>MySQL</em>. Pero existe un inconveniente en este caso, que la mayoría de SGBD son relacionales y nuestro programa sigue el modelo de la orientación a objetos (OOP) y la conversión entre modelos muchas veces no es obvia.</p>
<p>La alternativa que pretendo explicaros en este post es la serialización de los objetos para que sean almacenados en ficheros de texto, dándo así persistencia a nuestras aplicaciones. Me he decidido a realizar la explicación en <em>Python</em> su excelente mecanismo para la serialización de objetos, <a href="http://en.wikipedia.org/wiki/Pickle_%28Python%29" target="_blank"><em>Pickle</em></a>.</p>
<p>Para el post he creado una sencilla clase llamada SFSaludador que se encarga de saludar al usuario imprimiendo un &#8220;Hola!&#8221; por pantalla. El objeto guardará el total de saludos y esa información se hará persistente en un fichero llamaso &#8220;sfsaludador.txt&#8221; serializanso mediante <em>Pickle</em>. Os dejo el código a continuación:</p>
<pre class="brush: python;">
import os
import pickle

class SFSaludador(object):
	&quot;&quot;&quot;Clase SFSludador&quot;&quot;&quot;

	def __init__(self, totalSaludos):
		super(SFSaludador, self).__init__()
		self.__totalSaludos = totalSaludos

	def saluda(self):
		&quot;&quot;&quot;Saluda&quot;&quot;&quot;
		print &quot;Hola!&quot;
		self.__totalSaludos += 1

	def getTotalSaludos(self):
		&quot;&quot;&quot;Devuelve el total de saludos&quot;&quot;&quot;
		print &quot;He saludado &quot; + str(self.__totalSaludos) + &quot; veces.&quot;

	def load(self):
		&quot;&quot;&quot;Obtiene la informacion del archivo&quot;&quot;&quot;
		dataFile = open('sfsaludador.txt','r')
		self.__totalSaludos = pickle.load(dataFile)
		dataFile.close()

	def write(self):
		&quot;&quot;&quot;Graba los datos en el fichero&quot;&quot;&quot;
		dataFile = open('sfsaludador.txt','w')
		pickle.dump( self.__totalSaludos, dataFile)
		dataFile.close()

def main():
	&quot;&quot;&quot;Main function&quot;&quot;&quot;

	miSaludador = SFSaludador(0)

	if (os.path.exists('sfsaludador.txt')):
		print(&quot;Archivos encontrados. Cargando...&quot;)
		miSaludador.load()
	else:
		print(&quot;Archivos no encontrados...&quot;)

	miSaludador.getTotalSaludos()
	miSaludador.saluda()
	miSaludador.getTotalSaludos()

	miSaludador.write()

if __name__ == '__main__':
	main()
</pre>
<p>Para ejecutar el programa utilizaremos el intérprete de Python por consola de la siguiente forma (en entornos UNIX):</p>
<pre class="brush: bash;">
python SFSaludador.py
</pre>
<p>Dónde SFSaluadador.py es el fichero con el código de nuestro programa de ejemplo.</p>
<p>La primera vez que ejecutamos el programa no encontrará ningún fichero (así nos lo comunicará nuestra aplicación) y será al final de esta ejecución cuando creará el fichero con el estado del objeto para cargarlo en siguiente ejecuciones. Si volvemos a ejecutarlo vemos como esta vez si encuentra el fichero y el total de saludos tiene en cuenta los saludos de ejecuciones anteriores.</p>
<p>A veces <em>Pickle</em> puede llegar a ser un poco lento si necesitamos serializar muchos ficheros. Para solucionar esto existe una implentación de la librería realizada en el lenguaje de programación C, llamada <em>cPickle</em>. Si queremos hacer uso de ella sin tener que realizar modificaciones en nuestro código solo debemos sustituir el import de la librería por:</p>
<pre class="brush: bash;">
import cPickle as pickle
</pre>
<p>Espero que con este breve post haya podido haceros llegar la idea de la persistencia de datos en ficheros y su implementación en el potente lenguaje <em>Python</em>. Como siempre, ¡os espero en los comentarios!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.segmentationfault.es/2009/11/persistencia-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>jQuery UI: Efecto acordeón</title>
		<link>http://www.segmentationfault.es/2009/10/jquery-ui-acordeon/</link>
		<comments>http://www.segmentationfault.es/2009/10/jquery-ui-acordeon/#comments</comments>
		<pubDate>Sat, 17 Oct 2009 21:27:11 +0000</pubDate>
		<dc:creator>Noemí Losada</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[jQuery UI]]></category>
		<category><![CDATA[Curiosidades]]></category>
		<category><![CDATA[efectos visuales]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[librerías]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.es/?p=1209</guid>
		<description><![CDATA[Para los que no lo sepáis, jQuery UI es una librería que añade widgets y efectos visuales al framework <a href="http://es.wikipedia.org/wiki/JQuery" target="_blank">jQuery</a>.

Uno de esos widgets es el <strong>acordeón</strong>. Al clicar en los títulos se extienden mostrando el contenido de estos.

Para realizar este efecto nos basaremos en el ejemplo de la propia web de <a href="http://jqueryui.com/" target="_blank">jQuery UI</a> dónde podréis comprobar otros efectos muy interesantes.]]></description>
			<content:encoded><![CDATA[<p>Para los que no lo sepáis, jQuery UI es una librería que añade widgets y efectos visuales al framework <a href="http://es.wikipedia.org/wiki/JQuery" target="_blank">jQuery</a>.</p>
<p>Uno de esos widgets es el <strong>acordeón</strong>. Al clicar en los títulos se extienden mostrando el contenido de estos.</p>
<p>Para realizar este efecto nos basaremos en el ejemplo de la propia web de <a href="http://jqueryui.com/" target="_blank">jQuery UI</a> dónde podréis comprobar otros efectos muy interesantes.</p>
<p>En primer lugar crearemos un documento html en el que añadiremos las diferentes secciones con sus correspondientes títulos y contenidos, nosotros en este ejemplo utilizaremos 3 secciones:</p>
<pre class="brush: xml; toolbar: true;">
&lt;div id=&quot;accordion&quot;&gt;
 &lt;h3&gt;&lt;a href=&quot;#&quot;&gt;Section 1&lt;/a&gt;&lt;/h3&gt;
 &lt;div&gt;
 &lt;p&gt;
 Content
 &lt;/p&gt;
 &lt;/div&gt;
 &lt;h3&gt;&lt;a href=&quot;#&quot;&gt;Section 2&lt;/a&gt;&lt;/h3&gt;
 &lt;div&gt;
 &lt;p&gt;
 Content
 &lt;/p&gt;
 &lt;/div&gt;
 &lt;h3&gt;&lt;a href=&quot;#&quot;&gt;Section 3&lt;/a&gt;&lt;/h3&gt;
 &lt;div&gt;
 &lt;p&gt;
 Content
 &lt;/p&gt;
 &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>Hemos asignado la id &#8220;accordion&#8221; al div principal porque será el que le diremos a JQuery UI que utilice para montar el acordeón. </p>
<p>Para poder hacer uso de las librerías de jQuery el procedimiento es como el que utilizamos en otro post para incluir <a href="http://www.segmentationfault.es/2009/08/listas-ordenadas-scriptaculous/" target="_blank">Prototype y Scriptaculous</a>, la primera es descargarnos las librerías desde la web y llamarlas desde nuestro html y la segunda es incluirlas directamente desde la web oficial.  Nosotros las incluiremos directamente desde la web oficial. </p>
<p>Para ello hay que añadir las siguientes líneas de código:</p>
<pre class="brush: xml; toolbar: true;">
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/redmond/jquery-ui.css&quot; type=&quot;text/css&quot; media=&quot;all&quot; /&gt;
&lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js&quot;&gt;&lt;/script&gt;
</pre>
<p>La primera línea incluye el estilo visual. En este caso hemos utilizado el estilo &#8220;Redmond&#8221; pero ya veréis que en la web de jQuery UI tenéis mucha variedad y con la posibilidad de modificarlos desde la misma web con una interfaz gráfica.</p>
<p>Por último añadimos el script que coge el div &#8220;<em>accordion</em>&#8221; y llama al método <em>accordion()</em> que es el que monta el acordeón propiamente dicho:</p>
<pre class="brush: xml; toolbar: true;">
&lt;script type=&quot;text/javascript&quot;&gt;
$(function() {
$(&quot;#accordion&quot;).accordion();
});
&lt;/script&gt;
</pre>
<p>Y este es un ejemplo del resultado final:</p>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/redmond/jquery-ui.css" type="text/css" media="all" />
<script type="text/javascript" charset="utf-8" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script><br />
<script type="text/javascript" charset="utf-8" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script></p>
<p><script type="text/javascript">
	$(function() {
		$("#accordion").accordion();
	});
	</script></p>
<div id="accordion">
<h3><a href="#">Section 1</a></h3>
<div>
<p>
			Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer<br />
			ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit<br />
			amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut<br />
			odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.
			</p>
</p></div>
<h3><a href="#">Section 2</a></h3>
<div>
<p>
			Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet<br />
			purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor<br />
			velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In<br />
			suscipit faucibus urna.
			</p>
</p></div>
<h3><a href="#">Section 3</a></h3>
<div>
<p>
			Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis.<br />
			Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero<br />
			ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis<br />
			lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.
			</p>
<ul id="lista">
<li style="position:relative;">Lorem</li>
<li style="position:relative;">ipsum</li>
<li style="position:relative;">dolor</li>
<li style="position:relative;">sit</li>
<li style="position:relative;">amet</li>
<li style="position:relative;">consectetur</li>
<li style="position:relative;">adipisci</li>
<li style="position:relative;">velit</li>
</ul></div>
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.segmentationfault.es/2009/10/jquery-ui-acordeon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Efecto &#8220;Fade Out&#8221; con C++ e ImageMagick</title>
		<link>http://www.segmentationfault.es/2009/10/fade-out-cpp-imagemagick/</link>
		<comments>http://www.segmentationfault.es/2009/10/fade-out-cpp-imagemagick/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 07:33:48 +0000</pubDate>
		<dc:creator>Gabi García</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[imagemagick]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[procesamiento de imágenes]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.es/?p=1177</guid>
		<description><![CDATA[Para todos aquellos que os interese el tratamiento de imagen os dejo aquí un breve tutorial sobre cómo implementar el famoso efecto "desvanecer" (Fade Out) utilizando el lenguaje de programación C++ y las librerías de ImageMagick. ¡Saciad vuestra curiosidad y ganas de aprender leyendo el post completo! ]]></description>
			<content:encoded><![CDATA[<p>Llevo algunas semanas realizando una aplicación en C++ con las librerías de tratamiento de imagen de ImageMagick y me he decidido a hacer un tutorial sobre algo que he aprendido desarrollando dicha aplicación. En este breve tutorial pretendo explicaros cómo implementar el conocido efecto &#8220;desvanecer&#8221; (<em>Fade Out</em>) utilizando el lenguaje de programación C++ y trabajando sobre Linux.</p>
<p>Voy a saltarme la explicación sobre cómo instalar las librerías de desarrollo de ImageMagick ya que varía ligeramente de una distribución a otra y no suele ser muy complicado (teniendo en cuenta que ImageMagick suele estar presente en los repositorios más comunes y accesible desde gestores de paquetes como Synaptic). De todas formas si os surge alguna duda utilizad los comentarios.</p>
<p>Para simplificar la aplicación, ésta carecerá de interfaz gráfica y se ejecutará por terminal. El <em>input</em> del programa serán dos imágenes del mismo tamaño y un número entero positivo que indicará el número de imágenes intermedias que queremos que genere el programa como resultado.</p>
<p>Antes de empezar a poneros código fuente os comentaré la estructura de directorios del proyecto. Llamaremos al proyecto <strong>SFFadeOut </strong>(de Segmentation Fault Fade Out), por lo que la carpeta contenedora tendrá ese nombre. Dentro crearemos 4 directorios más:</p>
<ul>
<li>/bin: para los ficheros binarios</li>
<li>/inc: para los <em>headers </em>(.h) a incluir en el proyecto</li>
<li>/obj: para los .o</li>
<li>/src: para los ficheros de código fuente</li>
</ul>
<p>Ahora sí, ¡veamos el código!</p>
<p>En primer lugar os dejo el código de los 2 ficheros que conforman la clase Imagen. Esta clase se encargará de almacenar la información de los píxeles así como de tener algunos métodos y operadores para facilitar el trabajo. Primero os dejo el fichero <em><strong>Imagen.h</strong></em> que estará en /SFFadeOut/inc:</p>
<pre class="brush: cpp; toolbar: true;">
#ifndef IMAGEN_H
#define IMAGEN_H

class Imagen
{
 public:
  int dim[2];
  double * datos;
  Imagen();
  Imagen(int fil, int col);
  Imagen(int fil, int col, double val);
  ~Imagen();

  void  operator=(Imagen &amp;im2);

  int fils(){return dim[0];}
  int cols(){return dim[1];}

  inline double &amp; operator()(int i, int j)
  {
    return(datos[i*dim[1]+j]);
  };

};

Imagen &amp; lee(char * archima, int campo);
int compara_dims(Imagen &amp; im1, Imagen &amp; im2);
void escribe(char * archima, Imagen &amp; imR, Imagen &amp; imG, Imagen &amp; imB);

#endif
</pre>
<p>En éste fichero se encuentra la definición estática de la clase. Podéis ver los atributos de la clase, los constructores, un par de operadores y métodos propios de la clase. A continuación os dejo su correspondiente <strong><em>Imagen.cpp</em></strong>:</p>
<pre class="brush: cpp; toolbar: true;">
#include &lt;Imagen.h&gt;
#include &lt;stdio.h&gt;
#include &lt;math.h&gt;

Imagen::Imagen()
{
  dim[0]=0;
  dim[1]=0;
  datos=new double[1];
}

Imagen::Imagen(int fil, int col)
{
  dim[0]=fil;
  dim[1]=col;
  datos=new double[fil*col];
}

Imagen::Imagen(int fil, int col, double val)
{
  dim[0]=fil;
  dim[1]=col;
  datos=new double[fil*col];
  for(int i=0; i&lt;fil*col;i++)
    datos[i]=val;
}

Imagen::~Imagen()
{
  delete[] datos;
}

void Imagen::operator=(Imagen  &amp;im2)
{
  // este operador no duplica la memoria //
  int fil2=im2.fils();
  int col2=im2.cols();
  if(dim[0]!=fil2 || dim[1]!=col2)
  {
		dim[0]=fil2;
		dim[1]=col2;
		delete[] datos;
		datos=new double[fil2*col2];
	}

  int largo=dim[0]*dim[1];
  for(int i=0; i&lt;largo; i++)
    datos[i]=im2.datos[i];

  return;
}
</pre>
<p>Si os habéis dado cuenta, hay algunas funciones definidas en el header que no están implementadas en el .cpp. El motivo es que vamos a crear otro fichero llamado <strong><em>inout.cpp</em></strong> en el que incluir las funciones de lectura y escritura de imágenes (y también la función para comparar las dimesiones de las imágenes).</p>
<pre class="brush: cpp; toolbar: true;">
#include &lt;Imagen.h&gt;
#include &lt;stdio.h&gt;

#include &lt;Magick++.h&gt;
#include &lt;iostream&gt;
using namespace std;
using namespace Magick;

Imagen  &amp; lee(char * archima, int campo)
{
  string filename(archima);
  Image image;
  image.read(filename);
  Geometry g = image.size();
  int ancho = g.width();
  int alto= g.height();
  double c=1.0/257.0;
  Imagen * im=new Imagen(alto,ancho,(double)0.0);

  for(int i=0;i&lt;alto;i++)
    for(int j=0;j&lt;ancho;j++)
      switch(campo)
      {
        case 0:
          (*im)(i,j)=c*( double (image.pixelColor(j,i).redQuantum()));
          break;
        case 1:
          (*im)(i,j)=c*( double(image.pixelColor(j,i).greenQuantum()));
          break;
        case 2:
          (*im)(i,j)=c*( double(image.pixelColor(j,i).blueQuantum()));
          break;
        default:
          fprintf(stderr,&quot;\n Error en inout.cpp al leer archivo \n&quot;);
          break;
      }

   return(*im);
};

int compara_dims(Imagen &amp; im1, Imagen &amp; im2)
{
  if(im1.fils()!=im2.fils() | im1.cols()!=im2.cols())
    return 0;
  return 1;
};

void escribe(char * archima, Imagen &amp; imR, Imagen &amp; imG, Imagen &amp; imB)
{
    int ancho=imR.cols();
    int alto=imR.fils();
  if(compara_dims(imR,imG)!=1 | compara_dims(imG,imB)!=1 )
    {
      fprintf(stderr,&quot;\n Error al escribir en inout.cpp: imagenes R,G,B con distintas dimensiones. \n&quot;);
      return;
    }

  Geometry geom(ancho,alto);
  Image im(geom,&quot;white&quot;);

  for(int i=0;i&lt;alto;i++)
    for(int j=0;j&lt;ancho;j++)
      {
        double R=imR(i,j);
        double G=imG(i,j);
        double B=imB(i,j);
        R/=255.0;
        G/=255.0;
        B/=255.0;
        ColorRGB col(R,G,B);
              im.pixelColor(j,i,col);
      }

  im.write(archima);
  return;
};
</pre>
<p>Explicar todo el código anterior es bastante complejo por lo que pretendo que lo toméis como una API que supone una capa más de abstracción sobre la librería de ImageMagick. Ahora sí que os dejo la parte interesante, el fichero <strong><em>fadeout.cpp</em></strong> en el cual está el main del programa. Lo primero que realiza es comprobar si son correctos los parámetros de entrada y en caso contrario alertar al usuario. A continuación lee las imágenes y las almacena en objetos de la clase Imagen anteriormente detallada. Crea también un objeto para las imágenes resultantes e intera para cada píxel de cada una de las imágenes resultantes <em>n</em>, realizando el fundido (FadeOut).</p>
<pre class="brush: cpp; toolbar: true;">
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;math.h&gt;
#include &lt;sstream&gt;

#include &lt;Imagen.h&gt;
#include &lt;Magick++.h&gt;
#include &lt;iostream&gt;
using namespace std;
using namespace Magick;

void uso()
{
  fprintf(stderr,&quot;Uso: prueba imagen0 imagen1 n \n&quot;);
  exit(1);
};

char * getImagename(int i){
	stringstream temp;

	temp &lt;&lt; &quot;imagen_resultante_&quot; &lt;&lt; i &lt;&lt; &quot;.tiff&quot;;
	string resultName = temp.str();

	char *cstr = new char [resultName.size()+1];
  strcpy (cstr, resultName.c_str());

	return cstr;

}

main(int argc,char **argv)
{

  //verifica que la cantidad de argumentos es correcta
  if(argc&lt;4)
    uso();

  //almacena los argumentos en sus correspondientes variables
  argv++;
  char * nimagen0 =*argv++;
  char * nimagen1 =*argv++;
  int n=atoi(*argv++);

  //lee la primera imagen de entrada
  Imagen im0R=lee(nimagen0,0);
  Imagen im0G=lee(nimagen0,1);
  Imagen im0B=lee(nimagen0,2);

  //lee la segunda imagen de entrada
  Imagen im1R=lee(nimagen1,0);
  Imagen im1G=lee(nimagen1,1);
  Imagen im1B=lee(nimagen1,2);

	int cont;
 	int ancho=im0R.cols();
  int alto=im0R.fils();

	// crea un objeto Imagen para la imagen resultante
	Imagen resultR(ancho, alto);
	Imagen resultG(ancho, alto);
	Imagen resultB(ancho, alto);

	// la primera imagen resultante es la imagen de inicio
  escribe(&quot;imagen_resultante_0.tiff&quot;,im0R,im0G,im0B);

 	// bucle para generar n imágenes resultantes
	for(cont=0; cont &lt;n; cont++){
		// doble bucle que recorre los píxeles
	  for(int i=0;i&lt;alto;i++){
	    for(int j=0;j&lt;ancho;j++){

				// realiza el fundido
      	resultR(i,j) = (float)(((float)(n+1)-(cont+1)) / (float)(n+1)) * im0R(i,j) + (float)((float)(cont+1) / (float)(n+1)) * im1R(i,j);
				resultG(i,j) = (float)(((float)(n+1)-(cont+1)) / (float)(n+1)) * im0G(i,j) + (float)((float)(cont+1) / (float)(n+1)) * im1G(i,j);
				resultB(i,j) = (float)(((float)(n+1)-(cont+1)) / (float)(n+1)) * im0B(i,j) + (float)((float)(cont+1) / (float)(n+1)) * im1B(i,j);
	    }
	  }
		// escribe la imagen resultante n
		escribe(getImagename(cont+1),resultR,resultG,resultB);
	}

	// escribe la imagen final
	escribe(getImagename(cont+1),im1R,im1G,im1B);

	fprintf(stdout,&quot;\n\n Final del programa \n\n&quot;);
}
</pre>
<p>El cuerpo de los bucles es el que realiza el fundido propiamente dicho aplicando la fórmula:</p>
<p><div id="attachment_1186" class="wp-caption aligncenter" style="width: 146px"><img class="size-full wp-image-1186" title="formula_fadeout" src="http://www.segmentationfault.es/wp-content/2009/10/formula_fadeout.png" alt="Fórmula para implementar el fundido." width="136" height="30" /><p class="wp-caption-text">Fórmula para implementar el fundido.</p></div></p>
<p>Para facilitar un poco más la tarea de compilar el programa os dejo también el <a href="http://es.wikipedia.org/wiki/Make" target="_blank">Makefile</a> que yo utilizo:</p>
<pre class="brush: bash; toolbar: true;">
HOME = ..

TARGETS = $(SFFADEOUT)

OBJECTS = $(OBJSFFADEOUT)

###############################
# esto es general

CPP = g++

incdir1 = $(HOME)/inc
incdir2 = /usr/include/ImageMagick
#incdir2 = /usr/include/GraphicsMagick

SRC= $(HOME)/src
OBJ = $(HOME)/obj
bindir=$(HOME)/bin

INCLUDES = -I$(incdir2) -I$(incdir1)

CPPFLAGS = -g -O3

LIBS = -DHAVE_CONFIG_H -D_REENTRANT -D_FILE_OFFSET_BITS=64 -I/usr/include/magick -I/X11 -L/usr/lib -L/usr/X11R6/lib -lMagick++ -ltiff -ljpeg -lpng -lbz2 -lz -lpthread -lm -ldl -lxml2

##########################################
# SFFADEOUT

SFFADEOUT = sffadeout
OBJSFFADEOUT = fadeout.o Imagen.o inout.o

installsffadeout: $(bindir)/$(SFFADEOUT)
$(bindir)/sffadeout: $(OBJ)/sffadeout
	-rm $(bindir)/sffadeout
	cp -p $(OBJ)/sffadeout $(bindir)/sffadeout

sffadeout: $(OBJ)/sffadeout

$(OBJ)/sffadeout: $(addprefix $(OBJ)/, $(OBJSFFADEOUT))
	$(CPP) $(INCLUDES) $(CPPFLAGS) -o $(addprefix $(OBJ)/,$(SFFADEOUT)) $(addprefix $(OBJ)/, $(OBJSFFADEOUT)) -lpthread $(LIBS) $(MesaLibs)

#########################################
# reglas generales

$(OBJ)/%.o : %.cpp
	$(CPP) -c $(INCLUDES) $(CPPFLAGS)  $&amp;amp;lt; -o $@

.PHONY: prueba

all: directorios $(TARGETS)

clean:
	-rm $(TARGETS)
	-rm $(OBJ)/*.o

cleanall: clean

build: clean all

install: $(subst $(OBJ),$(bindir),$(TARGETS))

directorios:
	@if [ ! -d $(bindir) ]; then mkdir $(bindir); fi
	@if [ ! -d $(OBJ) ]; then mkdir $(OBJ); fi
</pre>
<p>Utilizando el comando make sólo deberéis navegar hasta la ruta adecuada y ejecutar el Makefile:</p>
<pre class="brush: bash; toolbar: false;">
make -k sffadeout
</pre>
<p>Recordad que para que todo funcione correctamente debéis ser fieles a la estructura que os he comentado al inicio del post. Es decir, al final debéis tener una estructura de:</p>
<ul>
<li>/SFFadeOut
<ul>
<li>/bin</li>
<li>/inc
<ul>
<li>Imagen.h</li>
</ul>
</li>
<li>/obj</li>
<li>/src
<ul>
<li>fadeout.cpp</li>
<li>Imagen.cpp</li>
<li>inout.cpp</li>
<li>Makefile</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Una vez compilado necesitáis un par de imágenes del mismo tamaño para provar si realmente funciona. Siendo fiel a mis anteriores artículos sobre procesamiento de imagen os animo a provar con la <a href="http://www.segmentationfault.es/wp-content/2009/04/lenna-300x300.png" target="_blank">imagen de Lenna</a> y una<a href="http://www.segmentationfault.es/wp-content/2009/10/negro.jpg" target="_blank"> imagen negra</a>.</p>
<p>Podéis ejecutar el programa con la instrucción (si las imágenes están en el directorio /SFFadeOut):</p>
<pre class="brush: bash; toolbar: false;">
./obj/sffadeout ../lenna.png ../negro.jpg 4
</pre>
<p>El resultado con n=4 debería dar las siguientes imágenes:</p>
<p><div id="attachment_1198" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.segmentationfault.es/wp-content/2009/10/FadeOutResult.jpg"><img class="size-medium wp-image-1198 " title="FadeOutResult" src="http://www.segmentationfault.es/wp-content/2009/10/FadeOutResult-300x200.jpg" alt="Resultado con n=4." width="300" height="200" /></a><p class="wp-caption-text">Resultado con n=4.</p></div></p>
<p>Os dejo además <a href="http://www.segmentationfault.es/wp-content/2009/10/SFFadeOut.zip" target="_blank">un zip</a> con todo el código estructurado en los directorios correctamente y con las imágenes de prueba que os he comentado. Para obtener mejores resultados probad con una <em>n</em> más alta y si queréis ver el fundido en acción os recomiendo crear un GIF animado.</p>
<p>Espero que os haya parecido interesante y no demasiado complicado. Seguro que hay fallos y mejoras así que os animo a todos a que expreséis vuestra opinión, sugerencias, problemas y demás en los comentarios.</p>
<p>Salu2!</p>
<p><span style="text-decoration: underline;"><strong>Fuentes</strong></span></p>
<p>Marcelo Bertalmío &#8211; http://www.tecn.upf.es/~mbertalmio/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.segmentationfault.es/2009/10/fade-out-cpp-imagemagick/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Enviar mails desde PHP</title>
		<link>http://www.segmentationfault.es/2009/09/enviar-mails-desde-php/</link>
		<comments>http://www.segmentationfault.es/2009/09/enviar-mails-desde-php/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 20:20:01 +0000</pubDate>
		<dc:creator>Gabi García</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.es/?p=1147</guid>
		<description><![CDATA[¿Alguna vez habéis necesitado automatizar el envío de mails? ¿Tenéis que crear algún tipo de boletín electrónico? ¿Queréis saber cómo enviar mails desde PHP? ¡Éste es vuestro tutorial! En él os explico el uso de la función mail() de forma breve y concisa. ¡Ánimos, es muy simple! ]]></description>
			<content:encoded><![CDATA[<p>Alguna vez os habréis topado con la necesidad de enviar un correo electrónico de forma automatizada, por ejemplo en la implementación de <a href="http://es.wikipedia.org/wiki/Bolet%C3%ADn_informativo" target="_blank"><em>Newsletters</em></a> en alguna aplicación web. A continuación, voy a mostraros cómo hacerlo en el famoso lenguaje, pero no por ello menos potente, PHP.</p>
<p>PHP posee en su librería estándar una función llamada <em>mail()</em> que nos va a permitir realizar esta tarea de una forma sencillísima. Como todas las funciones de este lenguaje, está perfectamente documentada en <a href="http://es.php.net/manual/en/function.mail.php" target="_blank">la web</a>. Sin entreteneros más, os pongo el código:</p>
<pre class="brush: php; toolbar: true;">
&lt;?php
$to = &quot;test@segmentationfault.es&quot;;
$subject = &quot;Segmentation Fault Mail From PHP&quot;;
$body = &quot;This is a mail sent from PHP&quot;;
$headers = &quot;From: gabi@segmentationfault.es&quot; . &quot;\r\n&quot;;

if (mail($to,$subject,$body,$headers)){
  echo &quot;Mail successfully sent&quot;;
} else {
  echo &quot;Error: mail could not be sent&quot;;
}

?&gt;
</pre>
<p>A la función <em>mail()</em> le pasamos los parámetros: <em> </em></p>
<ul>
<li>$to : dirección de correo a quien queremos enviar el mail.</li>
<li>$subject : asunto del mail.</li>
<li>$body : aquí incluiremos el cuerpo del mensaje.</li>
<li>$headers (opcional): Aquí podemos incluir cabeceras específicas en el mail. En este caso hemos especificado la dirección del remitente, pero se pueden incluir más opciones.</li>
</ul>
<p>Como la función <em>mail()</em> de PHP retorna un bool (<em>true/false</em>) podemos utilizarlo para identificar si el mail se ha enviado de forma satisfactoria o no y comunicárselo al usuario.</p>
<p>Ahora ya sabemos cómo enviar mail de texto simple mediante PHP. Pero no nos vamos a quedar sólo aquí, ahora vamos a aprender cómo enviar mails con contenido HTML (la base de cualquier boletín).</p>
<pre class="brush: php; toolbar: true;">
&lt;?php

$to = &quot;test@segmentationfault.es&quot;;
$subject = &quot;Segmentation Fault Mail From PHP with HTML content&quot;;

$body = &quot;&lt;html&gt;&lt;head&gt;&quot;;
$body .= &quot;&lt;title&gt;Segmentation Fault Mail From PHP with HTML content&lt;/title&gt;&quot;;
$body .= &quot;&lt;/head&gt;&lt;body&gt;&quot;;
$body .= &quot;&lt;h1&gt;Segmentation Fault&lt;/h1&gt;&quot;;
$body .= &quot;&lt;p&gt;This is a &lt;b&gt;simple HTML mail&lt;/b&gt; sent from PHP. You can know how to do it in &lt;a href=\&quot;http://segmentationfault.es\&quot;&gt;SegmentationFault Blog&lt;/a&gt;.&lt;/p&gt;&quot;;
$body .= &quot;&lt;/body&gt;&lt;/html&gt;&quot;;

/* Headers necesarios para enviar contenido HTML */
$headers = &quot;MIME-Version: 1.0&quot; . &quot;\r\n&quot;;
$headers .= &quot;Content-type:text/html;charset=iso-8859-1&quot; . &quot;\r\n&quot;;

$headers .= &quot;From: gabi@segmentationfault.es&quot; . &quot;\r\n&quot;;
$headers .= 'CC: noemi@segmentationfault.es' . &quot;\r\n&quot;;

if (mail($to,$subject,$body,$headers)){
  echo &quot;Mail successfully sent&quot;;
} else {
  echo &quot;Error: mail could not be sent&quot;;
}

?&gt;
</pre>
<p>En este segundo ejemplo, el cuerpo del mensaje es contenido HTML y para poder enviarlo necesitamos incluir <em>headers</em> adicionales. Además, hemos añadido un CC para mostrar cómo incluir diversos destinatarios de un mismo mail.</p>
<p>¡Enhorabuena! Ya sabéis enviar mails desde PHP de una forma rápida y simple. Si surgen dudas, haced uso de los comentarios. Salu2!</p>
<p><span style="text-decoration: underline;"><strong>Fuentes</strong></span></p>
<p><a href="http://es.php.net/manual/en/function.mail.php" target="_blank">Documentación PHP &#8211; http://es.php.net/manual/en/function.mail.php</a></p>
<p><a href="http://www.w3schools.com/php/func_mail_mail.asp" target="_blank">W3Schools &#8211; http://www.w3schools.com/php/func_mail_mail.asp</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.segmentationfault.es/2009/09/enviar-mails-desde-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Algoritmos genéticos – Creando a nuestros ciudadanos</title>
		<link>http://www.segmentationfault.es/2009/09/algoritmos-geneticos-ciudadanos/</link>
		<comments>http://www.segmentationfault.es/2009/09/algoritmos-geneticos-ciudadanos/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 21:00:36 +0000</pubDate>
		<dc:creator>Christopher Vallés</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[algoritmos genéticos]]></category>
		<category><![CDATA[hello world]]></category>

		<guid isPermaLink="false">http://www.segmentationfault.es/?p=1138</guid>
		<description><![CDATA[En esta segunda parte vamos a crear la clase que va a representar a nuestros ciudadanos, recordad que por cuestiones prácticas vamos a utilizar php y por si no habéis leído el post anterior sobre la teoría de algoritmos genéticos aquí os dejo el enlace. Una vez dicho esto pasemos a la acción. ]]></description>
			<content:encoded><![CDATA[<p>En esta segunda parte vamos a crear la clase que va a representar a nuestros ciudadanos, recordad que por cuestiones prácticas vamos a utilizar php y por si no habéis leído el post anterior sobre la teoría de algoritmos genéticos <a href="http://www.segmentationfault.es/2009/08/algoritmos-geneticos-teoria/" target="_blank">aquí os dejo el enlace</a>. Una vez dicho esto pasemos a la acción.</p>
<p>En primer lugar nuestra clase ciudadano va a necesitar guardar dos valores referentes al ciudadano al que representa, el primer dato será el material genético a guardar y el segundo caso el fitness actual del ciudadano, para ello emplearemos dos variables privadas ya que queremos controlar exactamente que se almacena en estas variables. Por lo tanto para poder manipular y ver estos datos vamos a necesitar los respectivos setters/getters.</p>
<p>Por último necesitaremos crear una función para calcular el fitness del ciudadano.</p>
<p>El fitness va muy ligado al problema a resolver, en nuestro caso como estamos desarrollando un Hello World el algoritmo va a tratar de llegar a una string objetivo a partir de una string aleatoria, con lo cuál una buena función de fitness debe atorgar una puntuación mas alta o baja dependiendo de lo cerca que estemos del objetivo. En mi caso voy a calcular la distancia entre las letras de la cadena objetivo y la cadena del ciudadano actual.</p>
<p>Atención, no me estoy refiriendo a la distancia Levenshtein. La distancia Levenshtein es el número mínimo de operaciones requeridas para transformar la cadena A en la cadena B, por ejemplo si tenemos la cadena &#8220;Manzana&#8221; y queremos conseguir &#8220;Manzanas&#8221; la distancia Levenshtein será 1.</p>
<p>Nuestra función de fitness para calcular lo bueno que es nuestro ciudadanos  va a sumar la diferencia carácter a carácter entre la string objetivo y la string actual a partir del número correspondiente ASCII de los caracteres. Es decir, entre la letra &#8220;A&#8221; (número 65 en la tabla ASCII) y la letra &#8220;P&#8221; (número 80 en la tabla ASCII) nuestra función debería retornar el número 15. Por lo tanto si tenemos la cadena &#8220;Manzana&#8221; y la cadena &#8220;Manzano&#8221; nuestra función retornará 14.</p>
<p>Cabe destacar que para que el algoritmo funcione correctamente hay que establecer unas cuantas limitaciones, de momento debemos establecer que las strings siempre van a ser del mismo tamaño, es decir en el momento de comparar las strings en nuestra función de fitness vamos a suponer que las strings miden lo mismo.</p>
<p>Por otra parte también quiero hacer notar que en el constructor de la clase inicializamos los datos de las variables, el fitness a -1 y el string a vacío.</p>
<p>Sin mas dilaciones aquí os dejo el código completo de nuestra clase Citizen.</p>
<pre class="brush: php;">
&lt;?php

class Citizen{

 private $data;
 private $fitness;

 public function __construct(){
   $this-&gt;data = '';
   $this-&gt;fitness = -1;
 }

 public function getData(){
   return $this-&gt;data;
 }

 public function setData($newData = NULL){
   try{
     if(!is_null($newData)){
     $this-&gt;data = $newData;
     }
   }catch(Exception $e){
     die($e-&gt;getMessage());
   }
 }

 public function getFitness(){
   return $this-&gt;fitness;
 }

 public function setFitness($newFitness = NULL){
   try{
     if(!is_null($newFitness)){
     $this-&gt;fitness = $newFitness;
     }
   }catch(Exception $e){
     die($e-&gt;getMessage());
   }

 }

 public function calculateFitness($objective = NULL){
   try{
     if(is_null($objective)){
       throw new Exception('Error, no se ha especificado objetivo');
     }

     $fitness = 0;
     for($x=0;$x&lt;strlen($objective);$x++){
       $fitness += abs(ord($objective[$x]) - ord($this-&gt;data[$x]));
     }

     $this-&gt;setFitness($fitness);
   }catch(Exception $e){
     die($e-&gt;getMessage());
   }

 }

}

?&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.segmentationfault.es/2009/09/algoritmos-geneticos-ciudadanos/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->