<?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>Codigo Manso &#187; Pau Sanchez</title>
	<atom:link href="http://www.codigomanso.com/es/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.codigomanso.com</link>
	<description>Programación, informática y tecnología</description>
	<lastBuildDate>Sun, 21 Aug 2011 10:54:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Hack Manso: Mejorar la velocidad de SQLite en Google App Engine SDK</title>
		<link>http://www.codigomanso.com/es/2011/08/manso-trick-speedup-sqlite-database-in-google-app-engine-sd/</link>
		<comments>http://www.codigomanso.com/es/2011/08/manso-trick-speedup-sqlite-database-in-google-app-engine-sd/#comments</comments>
		<pubDate>Sun, 21 Aug 2011 10:54:29 +0000</pubDate>
		<dc:creator>Pau Sanchez</dc:creator>
				<category><![CDATA[Programacion]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[truco manso]]></category>
		<category><![CDATA[gae]]></category>
		<category><![CDATA[hack manso]]></category>
		<category><![CDATA[mansohack]]></category>
		<category><![CDATA[mansotrick]]></category>

		<guid isPermaLink="false">http://www.codigomanso.com/es/?p=1065</guid>
		<description><![CDATA[Estaba tratando de inicializar una base de datos en local, con el Google App Engine SDK y me estaba volviendo loco.
Ni siquiera era factible usar &#8211;use_sqlite que introdujeron en la versión 1.3.3. La velocidad de los inserts a la base de datos iban superlentos, en plan, diez por segundo. Infumable.
Vale, vale, es el SDK, y [...]]]></description>
			<content:encoded><![CDATA[<p>Estaba tratando de inicializar una base de datos en local, con el Google App Engine SDK y me estaba volviendo loco.</p>
<p>Ni siquiera era factible usar &#8211;use_sqlite que introdujeron en la versión 1.3.3. La velocidad de los inserts a la base de datos iban superlentos, en plan, diez por segundo. Infumable.</p>
<p>Vale, vale, es el SDK, y el objetivo es desarrollar la aplicación y la velocidad no es lo más importante&#8230; pero si para insertar 1000 datos, tienen que pasar 10 minutos, pues mal vamos. Si me dijeras 1 millón, pues aún lo entendería minimamente&#8230; pero ¿1000 miseros inserts? ¿10 minutos? ¿estamos todos locos?</p>
<p>Así que, partiendo de que SQLite parece funcionar de puta madre, pues no me cuadraba&#8230; Mirando el FAQ de SQLite, me he encontrado con que la pregunta 19:</p>
<p><a href="http://www.sqlite.org/faq.html#q19" target="_blank"><strong>(19) INSERT is really slow &#8211; I can only do few dozen INSERTs per second</strong></a></p>
<p>La respuesta es, SQLite puede hacer fácil 50.000 inserts/segundo peeeeeeeero para garantizar la integridad de los datos, se espera a que el disco confirme que los datos se han escrito bien, por si se va la luz, etc&#8230; Vamos, un cuello de botella enorme, cuando a mi los datos me dan un poco igual porque es un entorno de prueba, lo que quiero es que vayan rápido los inserts porque si no me muero del asco desarrollando.</p>
<p>En fin, que la solución que dan es usar &#8220;<a href="http://www.sqlite.org/pragma.html#pragma_synchronous" target="_blank">PRAGMA synchronous=OFF</a>&#8220;. La única forma de usar ese pragma, es editar el SDK del Google App Engine, y ejecutar esa línea tras inicializar la base de datos.</p>
<p>Hay que editar el archivo:</p>
<p>google_appengine/google/appengine/datastore/datastore_sqlite_stub.py</p>
<p>Vamos al constructor &#8220;__init__&#8221;, y después de que inicialize la conexión a la base de datos &#8220;self.__connection = sqlite3.connect [...]&#8221; pues metemos la siguiente linea:</p>
<p>self.__connection.execute(&#8216;PRAGMA synchronous=OFF&#8217;)</p>
<p>Y, afotunadamente, cambiando esta línea he pasado de 10 inserts por segundo a más de 100 inserts por segundo. Más de 10x más rápido cambiando sólo una linea.</p>
<p>Ahora ya puedo continuar con lo que estaba haciendo.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codigomanso.com/es/2011/08/manso-trick-speedup-sqlite-database-in-google-app-engine-sd/feed/</wfw:commentRss>
		<slash:comments>470</slash:comments>
		</item>
		<item>
		<title>Truco Manso: obtener una cadena hexadecimal aleatoria en python</title>
		<link>http://www.codigomanso.com/es/2011/07/truco-manso-obtener-una-cadena-hexadecimal-aleatoria-en-python/</link>
		<comments>http://www.codigomanso.com/es/2011/07/truco-manso-obtener-una-cadena-hexadecimal-aleatoria-en-python/#comments</comments>
		<pubDate>Wed, 06 Jul 2011 07:22:53 +0000</pubDate>
		<dc:creator>Pau Sanchez</dc:creator>
				<category><![CDATA[Programacion]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[truco manso]]></category>

		<guid isPermaLink="false">http://www.codigomanso.com/es/?p=1058</guid>
		<description><![CDATA[Obtener una cadena de bytes aleatoria es una de esas cosas que hacen falta de vez en cuando.
La opción más sencilla en python es importar uuid y hacer la siguiente llamada:
uuid.uuid4().hex
Ale, con esa llamada ya tenemos 32 caracteres hexadecimales aleatorios (16 bytes aleatorios).
¿Sabes de algún otro método?
]]></description>
			<content:encoded><![CDATA[<p>Obtener una cadena de bytes aleatoria es una de esas cosas que hacen falta de vez en cuando.<br />
La opción más sencilla en python es importar uuid y hacer la siguiente llamada:</p>
<p><code>uuid.uuid4().hex</code></p>
<p>Ale, con esa llamada ya tenemos 32 caracteres hexadecimales aleatorios (16 bytes aleatorios).</p>
<p>¿Sabes de algún otro método?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codigomanso.com/es/2011/07/truco-manso-obtener-una-cadena-hexadecimal-aleatoria-en-python/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>TrucoManso: Transformar el tiempo en formato 24h a formato 12h (Python)</title>
		<link>http://www.codigomanso.com/es/2011/05/trucomanso-transformar-el-tiempo-en-formato-24h-a-formato-12h-python/</link>
		<comments>http://www.codigomanso.com/es/2011/05/trucomanso-transformar-el-tiempo-en-formato-24h-a-formato-12h-python/#comments</comments>
		<pubDate>Sat, 28 May 2011 18:13:24 +0000</pubDate>
		<dc:creator>Pau Sanchez</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[truco manso]]></category>
		<category><![CDATA[appengine]]></category>
		<category><![CDATA[formatting]]></category>

		<guid isPermaLink="false">http://www.codigomanso.com/es/?p=1052</guid>
		<description><![CDATA[Truco manso para transformar una cadena de tiempo en formato de 24h en formato de 12h (AM/PM)

def ampmformat (hhmmss):
  """
    This method converts time in 24h format to 12h format
    Example:   "00:32" is "12:32 AM"
            [...]]]></description>
			<content:encoded><![CDATA[<p>Truco manso para transformar una cadena de tiempo en formato de 24h en formato de 12h (AM/PM)</p>
<pre><code>
def ampmformat (hhmmss):
  """
    This method converts time in 24h format to 12h format
    Example:   "00:32" is "12:32 AM"
               "13:33" is "01:33 PM"
  """
  ampm = hhmmss.split (":")
  if (len(ampm) == 0) or (len(ampm) > 3):
    return hhmmss

  # is AM? from [00:00, 12:00[
  hour = int(ampm[0]) % 24
  isam = (hour >= 0) and (hour < 12)

  # 00:32 should be 12:32 AM not 00:32
  if isam:
    ampm[0] = ('12' if (hour == 0) else "%02d" % (hour))
  else:
    ampm[0] = ('12' if (hour == 12) else "%02d" % (hour-12))

  return ':'.join (ampm) + (' AM' if isam else ' PM')
</code></pre>
<p>Y un ejemplo de uso:</p>
<pre><code>ampmformat ("00:00:00") # devuelve "12:00:00 AM"
ampmformat ("12:00:00") # devuelve "12:00:00 PM"

ampmformat ("01:23:45") # devuelve "01:23:45 AM"
ampmformat ("13:23:45") # devuelve "01:23:45 PM"
ampmformat ("05:43:21") # devuelve "05:43:21 AM"
ampmformat ("17:43:21") # devuelve "05:43:21 PM"

ampmformat ("11:59:59") # devuelve "11:59:59 AM"
ampmformat ("23:59:59") # devuelve "11:59:59 PM"
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.codigomanso.com/es/2011/05/trucomanso-transformar-el-tiempo-en-formato-24h-a-formato-12h-python/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Google App Engine SDK 1.4.0 released</title>
		<link>http://www.codigomanso.com/es/2010/12/google-app-engine-sdk-1-4-0-released/</link>
		<comments>http://www.codigomanso.com/es/2010/12/google-app-engine-sdk-1-4-0-released/#comments</comments>
		<pubDate>Wed, 08 Dec 2010 12:54:32 +0000</pubDate>
		<dc:creator>Pau Sanchez</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[gae]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[sdk]]></category>

		<guid isPermaLink="false">http://www.codigomanso.com/es/?p=1045</guid>
		<description><![CDATA[Ya está disponible la versión 1.4.0 del SDK de Google App Engine.
Particularmente resaltaría 3 cosas de este release:

Los taskqueues ya forman parte del API oficial, han dejado de ser experimentales  
Han multiplicado por 20 los tiempos máximos de ejecución de las tareas cron y de las tareas del task queue de 30 segundos a [...]]]></description>
			<content:encoded><![CDATA[<p>Ya está disponible la versión 1.4.0 del SDK de Google App Engine.</p>
<p>Particularmente resaltaría 3 cosas de este release:</p>
<ul>
<li>Los <a href="http://code.google.com/appengine/docs/python/taskqueue/">taskqueues</a> ya forman parte del API oficial, han dejado de ser experimentales <img src='http://www.codigomanso.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </li>
<li>Han multiplicado por 20 los tiempos máximos de ejecución de las <a href="http://code.google.com/appengine/docs/python/config/cron.html">tareas cron </a>y de las tareas del <a href="http://code.google.com/appengine/docs/python/taskqueue/">task queue</a> de 30 segundos a 600 segundos (10 minutos). Esto es fantástico, aunque puede ser peligroso. Habrá que usarlo sabiamente <img src='http://www.codigomanso.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </li>
<li>El uso del <a href="http://code.google.com/appengine/docs/python/channel/">Channel API</a> ya está disponible para todo el mundo de forma oficial.</li>
</ul>
<p>El Channel API me impresionó cuando le eché un vistazo por allá por Mayo. A continuación el video del Channel API. Es bastante técnico y sólo tiene sentido si programas en GAE o si por ejemplo quieres hacer un API para comunicación <a href="http://en.wikipedia.org/wiki/Comet_%28programming%29">Comet</a> entre cliente-servidor:</p>
<p><object width="480" height="290"><param name="movie" value="http://www.youtube.com/v/oMXe-xK0BWA&#038;hl=en_US&#038;feature=player_embedded&#038;version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.youtube.com/v/oMXe-xK0BWA&#038;hl=en_US&#038;feature=player_embedded&#038;version=3" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="480" height="290"></embed></object></p>
<p>Enlaces:</p>
<ul>
<li><a href="http://code.google.com/appengine/downloads.html">Google App Engine SDK Download Page</a></li>
<li><a href="http://code.google.com/p/googleappengine/wiki/SdkReleaseNotes">Google App Engine Release Notes</a></li>
<li><a href="http://www.google.com/events/io/2010/sessions/building-real-time-apps-app-engine-feed-api.html">Building real-time web apps with App Engine and the Feed API</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.codigomanso.com/es/2010/12/google-app-engine-sdk-1-4-0-released/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Truco Manso: Obtener la latitud/longitud a partir de una dirección</title>
		<link>http://www.codigomanso.com/es/2010/11/truco-manso-obtener-la-latitudlongitud-a-partir-de-una-localizacion-o-direccion/</link>
		<comments>http://www.codigomanso.com/es/2010/11/truco-manso-obtener-la-latitudlongitud-a-partir-de-una-localizacion-o-direccion/#comments</comments>
		<pubDate>Sat, 13 Nov 2010 11:27:32 +0000</pubDate>
		<dc:creator>Pau Sanchez</dc:creator>
				<category><![CDATA[Programacion]]></category>
		<category><![CDATA[truco manso]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[geocoding]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[latitude]]></category>
		<category><![CDATA[longitude]]></category>

		<guid isPermaLink="false">http://www.codigomanso.com/es/?p=1038</guid>
		<description><![CDATA[Para un proyecto que espero que pronto vea la luz, he estado investigando cómo determinar la localización geográfica de cualquier sitio. Esto es, determinar la latitud/longitud a partir de una frase en plan &#8220;Elche, Alicante, Spain&#8221;
A esto se le llama Geocoding y a poco que he buscado tanto Google como Yahoo tienen APIs REST que [...]]]></description>
			<content:encoded><![CDATA[<p>Para un proyecto que espero que pronto vea la luz, he estado investigando cómo determinar la localización geográfica de cualquier sitio. Esto es, determinar la latitud/longitud a partir de una frase en plan &#8220;Elche, Alicante, Spain&#8221;</p>
<p>A esto se le llama Geocoding y a poco que he buscado tanto Google como Yahoo tienen APIs REST que te permiten enchufar queries en un servidor (aunque con unos términos de uso limitados).</p>
<p>En el caso de Yahoo, hace falta darse de alta para que te den un appid y poder hacer los queries.</p>
<p>En el caso de Google, no es así, y preguntar la latitud y longitud de &#8220;Elche, Alicante, Spain&#8221; es tan fácil como:</p>
<p><a href="http://maps.googleapis.com/maps/api/geocode/json?address=Elche,+Alicante,+Spain&amp;sensor=false">http://maps.googleapis.com/maps/api/geocode/json?address=Elche,+Alicante,+Spain&amp;sensor=false</a></p>
<p>Esto devuelve un churrasco en JSON (también lo puedes pedir en XML) y dentro de este churrasco, dice que la latitud/longitud es:<br />
&#8220;lat&#8221;: 38.2671765,<br />
&#8220;lng&#8221;: -0.6952196</p>
<p>También existe GeoNames, que es menos preciso, pero puede resultar interesante también (ver enlace más abajo).</p>
<p>Para más información:</p>
<ul>
<li>Google Geocoding API:<br />
<a href="http://code.google.com/apis/maps/documentation/geocoding/index.html">http://code.google.com/apis/maps/documentation/geocoding/index.html</a></li>
<li>Yahoo! Place Finder:<br />
<a href="http://developer.yahoo.com/geo/placefinder/">http://developer.yahoo.com/geo/placefinder/</a></li>
<li>GeoNames geographical database:<br />
<a href="http://www.geonames.org/">http://www.geonames.org/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.codigomanso.com/es/2010/11/truco-manso-obtener-la-latitudlongitud-a-partir-de-una-localizacion-o-direccion/feed/</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
		<item>
		<title>Soporte de unicode en Python: Frustraciones y Soluciones</title>
		<link>http://www.codigomanso.com/es/2010/09/unicode-support-in-python-frustrations-and-solutions/</link>
		<comments>http://www.codigomanso.com/es/2010/09/unicode-support-in-python-frustrations-and-solutions/#comments</comments>
		<pubDate>Tue, 21 Sep 2010 23:49:55 +0000</pubDate>
		<dc:creator>Pau Sanchez</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[frustracion]]></category>
		<category><![CDATA[pesadillas]]></category>
		<category><![CDATA[unicode]]></category>

		<guid isPermaLink="false">http://www.codigomanso.com/es/?p=1032</guid>
		<description><![CDATA[Personalmente el soporte de unicode en Python anterior a Python 3, siendo finos, es una puta mierda. Casi prefiero el soporte que tiene PHP 5.x de unicode (cero patatero).
Sinceramente es para volverse loco, porque cosas que a priori van, luego petan, o realmente no petan, sólo petan cuando intentas mostrarlas por la consola haciendo print&#8230;
En [...]]]></description>
			<content:encoded><![CDATA[<p>Personalmente el soporte de unicode en Python anterior a Python 3, siendo finos, es una puta mierda. Casi prefiero el soporte que tiene PHP 5.x de unicode (cero patatero).</p>
<p>Sinceramente es para volverse loco, porque cosas que a priori van, luego petan, o realmente no petan, sólo petan cuando intentas mostrarlas por la consola haciendo print&#8230;</p>
<p>En fin, que tratando de solucionar mis frustraciones con python y el unicode, he encontrado el siguiente enlace:</p>
<p><a href="http://packages.python.org/kitchen/unicode-frustrations.html">Overcoming unicode frustrations in Python 2</a></p>
<p>El enlace anterior es lectura obligada para cualquiera que de vez en cuando le salte una excepción tipo UnicodeEncodeError, como:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">UnicodeEncodeError: <span style="color: #ff0000;">'ascii'</span> codec can<span style="color: #ff0000;">'t encode character u'</span>\xe1<span style="color: #ff0000;">' in position 654: ordinal not in range(128)</span></pre></div></div>

<p>Finalmente, mi esperanza es que en Python 3 todo esto se solucione, y a juzgar por lo que he ido leyendo parece que si&#8230; pero ¡habrá que ver para creer!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codigomanso.com/es/2010/09/unicode-support-in-python-frustrations-and-solutions/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Serializando datos nativos en Python</title>
		<link>http://www.codigomanso.com/es/2010/09/serializing-native-data-variables-in-python/</link>
		<comments>http://www.codigomanso.com/es/2010/09/serializing-native-data-variables-in-python/#comments</comments>
		<pubDate>Tue, 21 Sep 2010 10:47:07 +0000</pubDate>
		<dc:creator>Pau Sanchez</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[serialization]]></category>
		<category><![CDATA[serialize]]></category>
		<category><![CDATA[yaml]]></category>

		<guid isPermaLink="false">http://www.codigomanso.com/es/?p=1026</guid>
		<description><![CDATA[Resulta que para un proyecto en Python en el que estoy trabajando necesitaba serializar algunas estructuras. El tema es que únicamente hacía falta serializar tipos nativos como listas, diccionarios, cadenas, enteros, etc&#8230;
Lo que me hacía falta era:

representación compacta
serialización/deserialización rápida
legible / editable por un humano

Así que después de pensar un rato, he encontrado 3 posibles soluciones [...]]]></description>
			<content:encoded><![CDATA[<p>Resulta que para un proyecto en Python en el que estoy trabajando necesitaba serializar algunas estructuras. El tema es que únicamente hacía falta serializar tipos nativos como listas, diccionarios, cadenas, enteros, etc&#8230;</p>
<p>Lo que me hacía falta era:</p>
<ul>
<li>representación compacta</li>
<li>serialización/deserialización rápida</li>
<li>legible / editable por un humano</li>
</ul>
<p>Así que después de pensar un rato, he encontrado 3 posibles soluciones para serializar datos arbitrarios:</p>
<ul>
<li>pickle/cPickle que serializa cualquier cosa, viene con python, pero no es legible/editable</li>
<li>simplejson que serializa en formato JSON (el resultado es legible y editable)</li>
<li>PyYAML que serializa en YAML (el resultado es legible y editable)</li>
</ul>
<p>El siguiente paso era coger un buen montón de datos, y hacer tests para ver que tal funcionan los encoders/decoders en cada uno de esos módulos. </p>
<p>A continuación puedes ver los gráficos de los tiempos de encoding/decoding para dos conjuntos de datos empleando cada uno de los formatos anteriores:</p>
<p><img src="http://chart.apis.google.com/chart?chxl=1:|YAML|JSON|pickle+raw|pickle+highest&#038;chxp=1,0.5,1.5,2.5,3.5&#038;chxr=1,0,4&#038;chxt=y,x&#038;chbh=a,4,0&#038;chs=500x320&#038;cht=bvs&#038;chco=3072F3,FF9900,FF9900&#038;chd=s:oBBB,,&#038;chdlp=l&#038;chtt=Python+Serialization+Speed+Test+(Tiny+Dataset)&#038;chts=000000,10.5" width="500" height="320" alt="Python Serialization Speed Test (Tiny Dataset)" /></p>
<p><img src="http://chart.apis.google.com/chart?chxl=1:|YAML|JSON|pickle+raw|pickle+highest&#038;chxp=1,0.5,1.5,2.5,3.5&#038;chxr=1,0,4&#038;chxs=0,676767,15.5,-0.5,l,676767&#038;chxt=y,x&#038;chbh=a,4,0&#038;chs=500x320&#038;cht=bvs&#038;chco=3072F3&#038;chd=s:5CBB&#038;chdlp=l&#038;chtt=Python+Serialization+Speed+Test+(Huge+Dataset)&#038;chts=000000,10.5" width="500" height="320" alt="Python Serialization Speed Test (Huge Dataset)" /></p>
<p>A parte de la velocidad, también me interesaba medir la longitud de las cadenas generadas (cuanto menos, mejor):</p>
<ul>
<li>yaml   tiny = 32604  // huge = 912912</li>
<li>json   tiny = 31305 // huge = 876540</li>
<li>pickle-raw    tiny = 34504 // huge = 986531</li>
<li>pickle-highest   tiny = 37541 // huge = 1101480</li>
</ul>
<h5>Conclusión:</h5>
<p>Como se puede ver en las gráficas, y en la tabla anterior, considero que JSON es el que me hace mejor papel.  Codifica / decodifica ligeramente más despacio que pickle (un 4% más despacio) pero la cadena resultante es legible y editable y además ocupa menos espacio que picke y que yaml.</p>
<p>Todos los tests han sido realizados con Python 2.5</p>
<h5>El código:</h5>
<p>Finalmente, aquí dejo un fragmento de código usado para obtener los tiempos que aparecen en los gráficos anteriores:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">    start = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>:
      yaml.<span style="color: black;">safe_load</span> <span style="color: black;">&#40;</span>yaml.<span style="color: black;">safe_dump</span> <span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">write</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;YAML TIME = %.2f<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - start<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    start = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>:
      JSONDecoder<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">decode</span> <span style="color: black;">&#40;</span>JSONEncoder<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">encode</span> <span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">write</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;JSON TIME = %.2f<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - start<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    start = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>:
      <span style="color: #dc143c;">pickle</span>.<span style="color: black;">loads</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">pickle</span>.<span style="color: black;">dumps</span> <span style="color: black;">&#40;</span>data, <span style="color: #dc143c;">pickle</span>.<span style="color: black;">HIGHEST_PROTOCOL</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">write</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PICKLE TIME = %.2f<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - start<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    start = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>:
      <span style="color: #dc143c;">pickle</span>.<span style="color: black;">loads</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">pickle</span>.<span style="color: black;">dumps</span> <span style="color: black;">&#40;</span>data, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">write</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PICKLE-RAW TIME = %.2f<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - start<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.codigomanso.com/es/2010/09/serializing-native-data-variables-in-python/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>bbcodeutils: BBCode parser and BBCode to HTML for Python</title>
		<link>http://www.codigomanso.com/es/2010/09/bbcodeutils-bbcode-parser-and-bbcode-to-html-for-python/</link>
		<comments>http://www.codigomanso.com/es/2010/09/bbcodeutils-bbcode-parser-and-bbcode-to-html-for-python/#comments</comments>
		<pubDate>Wed, 15 Sep 2010 11:54:00 +0000</pubDate>
		<dc:creator>Pau Sanchez</dc:creator>
				<category><![CDATA[Programacion]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[bbcode]]></category>
		<category><![CDATA[bbcode2html]]></category>
		<category><![CDATA[parser]]></category>

		<guid isPermaLink="false">http://www.codigomanso.com/es/?p=947</guid>
		<description><![CDATA[Ayer anduve buscando algún módulo para Python para parsear Bulletin Board Code (bbcode para los amigos) o que fuera capaz de transformarlo en HTML.
Como ninguna solución cumplía mis necesidades al 100% he creado bbcodeutils que no es mas que un conjunto de clases en Python para parsear, generar y transformar bbcode. He intentado que sea [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Ayer anduve buscando algún módulo para Python para parsear Bulletin Board Code (bbcode para los amigos) o que fuera capaz de transformarlo en HTML.</p>
<p style="text-align: justify;">Como ninguna solución cumplía mis necesidades al 100% he creado <strong>bbcodeutils</strong> que no es mas que un conjunto de clases en Python para parsear, generar y transformar bbcode. He intentado que sea lo más simple de usar posible.</p>
<p>Dentro de bbcodeutils encontrarás estas clases:</p>
<ul style="text-align: justify;">
<li><strong>bbcodeparser</strong>: permite parsear y corregir código bbcode</li>
<li><strong>bbcode2html</strong>: permite generar HTML a partir de un código BBCode parseado</li>
<li><strong>bbcodebuilder</strong>: permite generar BBCode a partir de sentencias en Python</li>
</ul>
<p style="text-align: justify;">Aquí teneis el enlace para descargar <a href="http://www.codigomanso.com/archives/python/bbcodeutils-v1.0.tgz">bbcodeutils v1.0</a>. Puedes usar este módulo libremente (ver readme.txt para más detalles).
</p>
<p style="text-align: justify;">A continuación voy a poner algunos ejemplos de uso de las operaciones más típicas.</p>
<h5>Ejemplos:</h5>
<p>En los siguientes ejemplos se asume que habrás hecho algo para cargar los módulos, en plan:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> bbcodeutils <span style="color: #ff7700;font-weight:bold;">import</span> bbcodebuilder, bbcodeparser</pre></div></div>

<h6>Parsear cadenas bbcode</h6>
<p>Parsear una cadena BBCode se puede hacer de dos maneras, usando el constructor, o invocando a parse:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> bbcode = bbcodeparser<span style="color: black;">&#40;</span><span style="color: #483d8b;">'[b]bold string[/b]'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>o bien:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> bbcode = bbcodeparser<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;</span> bbcode.<span style="color: black;">parse</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'[b]first string[/b]'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Esto tampoco tiene más utilidad que la de ilustrar como parsear una cadena, pero al final uno lo que querrá será bien corregir el código BBCode, o bien producir HTML válido a partir de la cadena parseada</p>
<h6>Corregir una cadena BBCode invalida</h6>
<p>Para corregir una cadena BBCode mal formada, símplemente habría que parsear la cadena en cuestión y llamar al método <b>bbcode</b> que construye la cadena de nuevo, o bien transformar el objeto a cadena.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> bbcode = bbcodeparser<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;This is [b]bold and [i]this bold and italics[/b].[/color]&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;</span> bbcode.<span style="color: black;">bbcode</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">&quot;This is [b]bold and [i]this bold and italics[/i][/b].&quot;</span>
&nbsp;
<span style="color: #66cc66;">&gt;</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>bbcode<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">&quot;This is [b]bold and [i]this bold and italics[/i][/b].&quot;</span></pre></div></div>

<p>Nótese como se elimina el tag [/color] y se añade el tag [/i] que faltaba.</p>
<h6>Transformar una cadena BBCode en HTML</h6>
<p>La clase bbcodeparser implementa el método <b>html</b> que transforma el código parseado<br />
en HTML válido.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> bbcode = bbcodeparser<span style="color: black;">&#40;</span><span style="color: #483d8b;">'[b]bold string[/b]'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;</span> bbcode.<span style="color: black;">html</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">&quot;&lt;b&gt;bold string&lt;/b&gt;&quot;</span></pre></div></div>

<h6>Generar código BBCode</h6>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> bbcode = bbcodebuilder<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;</span> bbcode.<span style="color: black;">b</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'string in bold'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">&quot;[b]string in bold[/b]&quot;</span>
&nbsp;
<span style="color: #66cc66;">&gt;</span> bbcode.<span style="color: black;">url</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'http://www.codigomanso.com/'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">&quot;[url]http://www.codigomanso.com/[/url]&quot;</span>
&nbsp;
<span style="color: #66cc66;">&gt;</span> bbcode.<span style="color: black;">url</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Welcome to Codigo Manso'</span>, <span style="color: #483d8b;">'http://www.codigomanso.com/'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">&quot;[url=http://www.codigomanso.com/]Welcome to Codigo Manso[/url]&quot;</span>
&nbsp;
<span style="color: #66cc66;">&gt;</span> bbcode.<span style="color: #008000;">list</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'item 1'</span>, <span style="color: #483d8b;">'item 2'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">&quot;[list]
   [*]item 1
   [*]item 2
[/list]&quot;</span></pre></div></div>

<h6>Operaciones típicas en una linea de código</h6>
<p>Corregir cadenas inválidas en una linea:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>bbcodeparser<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;[color=red]Fix this [b]string&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">&quot;[color=red]Fix this [b]string[/b][/color]&quot;</span></pre></div></div>

<p>Transformar bbcode a HTML en una linea:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>bbcodeparser<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;[color=red]Fix this [b]string&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'&lt;span style=&quot;color: red;&quot;&gt;Fix this &lt;b&gt;string&lt;/b&gt;&lt;/span&gt;'</span></pre></div></div>

<p>Ale, ¡Ya está!</p>
<p>Si alguien se anima a usar este módulo y quiere algún ejemplo más, o tiene alguna duda sobre su utilización, le animo a que deje un comentario en este post.</p>
<p>Enlaces de interés:</p>
<ul>
<li><a href="http://www.codigomanso.com/archives/python/bbcodeutils-v1.0.tgz">bbcodeutils v1.0 for Python</a></li>
<li><a href="http://www.bbcode.org/reference.php">Referencia de BBCode</a></li>
<li><a href="http://en.wikipedia.org/wiki/BBCode">Entrada sobre BBCode en la Wikipedia</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.codigomanso.com/es/2010/09/bbcodeutils-bbcode-parser-and-bbcode-to-html-for-python/feed/</wfw:commentRss>
		<slash:comments>293</slash:comments>
		</item>
		<item>
		<title>[SOLVED] Añadir claves únicas en Google App Engine en 3 lineas</title>
		<link>http://www.codigomanso.com/es/2010/09/solved-anadir-claves-unicas-en-google-app-engine-en-3-lineas/</link>
		<comments>http://www.codigomanso.com/es/2010/09/solved-anadir-claves-unicas-en-google-app-engine-en-3-lineas/#comments</comments>
		<pubDate>Fri, 10 Sep 2010 15:44:31 +0000</pubDate>
		<dc:creator>Pau Sanchez</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[gae]]></category>
		<category><![CDATA[gql]]></category>

		<guid isPermaLink="false">http://www.codigomanso.com/es/?p=931</guid>
		<description><![CDATA[El problema:
Google App Engine mola, y la verdad es que programar en Python se me está empezando a hacer agradable, aunque me sigue gustando más la indentación con llaves&#8230;
En fin, la base de datos que usa Google es superpotente y supersencilla, si bien tiene algunas limitaciones con las que hay que aprender a vivir. Con [...]]]></description>
			<content:encoded><![CDATA[<h5>El problema:</h5>
<p>Google App Engine mola, y la verdad es que programar en Python se me está empezando a hacer agradable, aunque me sigue gustando más la indentación con llaves&#8230;</p>
<p>En fin, la base de datos que usa Google es superpotente y supersencilla, si bien tiene algunas limitaciones con las que hay que aprender a vivir. Con el SDK que Google da, puedes indicar fácilmente qué atributos indexar (indexed=True), puedes forzar a que un atributo sea definido cuando vas a añadir un elemento a la base de datos (required=True), pero no puedes forzar a que un atributo o conjunto de atributos sean únicos (no hay un unique=True).
</p>
<p>Por poner un ejemplo, es el típico campo de nick o e-mail en una base de datos de usuario SQL de toda la vida. No quieres que dos usuarios puedan tener el mismo e-mail o el mismo nick porque quieres identificar univocamente a un usuario por su nick o su e-mail. Es de cajón :p
</p>
<p>¿Putada? El SDK de Google App Engine no te permite hacer esto&#8230; sin embargo la solución es trivial <img src='http://www.codigomanso.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h5>La solución:</h5>
<p>Lo único que hay que hacer es redefinir la función <b>put</b> dentro de nuestro modelo y lanzar una excepción cuando se cree un elemento cuyas restricciones no se cumplan.
</p>
<p>Por simplificar, creemos un modelo <b>User</b> con los atributos <b>name</b>, <b>email</b>, <b>language</b> y <b>creation_date</b>:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> User <span style="color: black;">&#40;</span>db.<span style="color: black;">Model</span><span style="color: black;">&#41;</span>: 
   creation_date = db.<span style="color: black;">DateTimeProperty</span> <span style="color: black;">&#40;</span>auto_now_add=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
   name          = db.<span style="color: black;">StringProperty</span> <span style="color: black;">&#40;</span>required = <span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
   <span style="color: #dc143c;">email</span>         = db.<span style="color: black;">EmailProperty</span> <span style="color: black;">&#40;</span>required = <span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
   language      = db.<span style="color: black;">StringProperty</span> <span style="color: black;">&#40;</span>default=<span style="color: #483d8b;">&quot;en&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Tal y como está definida la clase, si ejecutáramos el siguiente código, Google App Engine crearía dos registros distintos:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">User <span style="color: black;">&#40;</span>name=<span style="color: #483d8b;">&quot;Mark Johnson&quot;</span>, <span style="color: #dc143c;">email</span>=<span style="color: #483d8b;">&quot;test@codigomanso.com&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">put</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
User <span style="color: black;">&#40;</span>name=<span style="color: #483d8b;">&quot;JohnMarkinson&quot;</span>, <span style="color: #dc143c;">email</span>=<span style="color: #483d8b;">&quot;test@codigomanso.com&quot;</span>, language=<span style="color: #483d8b;">&quot;es&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">put</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p><b>No queremos dos usuarios compartiendo el mismo e-mail!!</b> El segundo <b>put</b> debería fallar. ¿Cómo lo arreglamos? Tan simple como parece, redefinimos <b>put</b> para que cuando se vaya a crear un elemento con un atributo duplicado en la base de datos lance una excepción. Por lo tanto, la nueva clase una vez añadido el método <b>put</b> quedaría:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> User <span style="color: black;">&#40;</span>db.<span style="color: black;">Model</span><span style="color: black;">&#41;</span>: 
   creation_date = db.<span style="color: black;">DateTimeProperty</span> <span style="color: black;">&#40;</span>auto_now_add=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
   name          = db.<span style="color: black;">StringProperty</span> <span style="color: black;">&#40;</span>required = <span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
   <span style="color: #dc143c;">email</span>         = db.<span style="color: black;">EmailProperty</span> <span style="color: black;">&#40;</span>required = <span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
   language      = db.<span style="color: black;">StringProperty</span> <span style="color: black;">&#40;</span>default=<span style="color: #483d8b;">&quot;en&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
   <span style="color: #ff7700;font-weight:bold;">def</span> put <span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
     <span style="color: #808080; font-style: italic;"># Make sure e-mails are unique for each user</span>
     <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">is_saved</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: black;">&#40;</span>User.<span style="color: black;">gql</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'WHERE email = :1'</span>, <span style="color: #008000;">self</span>.<span style="color: #dc143c;">email</span><span style="color: black;">&#41;</span>.<span style="color: black;">count</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
       <span style="color: #ff7700;font-weight:bold;">raise</span> DuplicatedInstanceError <span style="color: black;">&#40;</span><span style="color: #483d8b;">'User.email'</span>, <span style="color: #008000;">self</span>.<span style="color: #dc143c;">email</span><span style="color: black;">&#41;</span>
&nbsp;
     <span style="color: #808080; font-style: italic;"># call the parent method</span>
     db.<span style="color: black;">Model</span>.<span style="color: black;">put</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Si te das cuenta, son sólo 3 lineas de código, 4 contando la linea del def&#8230; si es que más fácil no se puede.</p>
<h5>Problemas varios</h5>
<p>Después de meditarlo un poco, esta implementación no es perfecta. Yo le veo principalmente dos inconvenientes:</p>
<ul>
<li>Hay que realizar un query extra cuando se pretende insertar un elemento (si actualizas un elemento la función se comporta como siempre).
</li>
<li>Aún con esta solución puede ocurrir que acabes con dos usuarios con el mismo nick en la base de datos. ¿Cómo puede ser? La operación count-put no es atómica, por lo tanto, pueden llegar dos usuarios al mismo tiempo, realizar un count, la función devolver cero en ambos casos, y luego se insertan los dos.
</li>
</ul>
<p>El primer inconveniente, no lo es tanto, pero es una cosa a tener en cuenta.</p>
<p>El segundo inconveniente puede ser una putada. Para solucionarlo se me ocurre que se podría tratar de ejecutar el count-put dentro de una transacción, o bien crear un mutex (se puede?) y que el count-put se realicen dentro del mútex. En fin, a mi ese caso de momento no me preocupa, pero está bien saber que existe.
</p>
<h5>Apéndice: DuplicatedInstanceError</h5>
<p>Si eres avispado te habrás dado cuenta que he lanzado una excepción de tipo DuplicatedInstanceError. Esta clase no existe. La he definido yo para poder detectar cuando ocurre un caso de este tipo.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> DuplicatedInstanceError <span style="color: black;">&#40;</span><span style="color: #008000;">Exception</span><span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, attrpath, value = <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'
    Accept a dict of attribute and value pairs, or just one attribute and a value:
&nbsp;
    Example:
       # user unique constraint has been violated (User.nick to be unique)
       DuplicatedInstanceError ('</span>User.<span style="color: black;">nick</span><span style="color: #483d8b;">', '</span>jsmith<span style="color: #483d8b;">')
&nbsp;
       # student unique constraint has been violated (student nick'</span>s are fin <span style="color: #ff7700;font-weight:bold;">for</span> different schools<span style="color: black;">&#41;</span>
       DuplicatedInstanceError <span style="color: black;">&#40;</span><span style="color: black;">&#123;</span>
         <span style="color: #483d8b;">'Student.nick'</span>   : <span style="color: #483d8b;">'jsmith'</span>,
         <span style="color: #483d8b;">'Student.school'</span> : <span style="color: #483d8b;">'demo-primary-school'</span>
       <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
    <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'
    self.attrpath = '</span><span style="color: #483d8b;">'
&nbsp;
    # accept a dict as the only parameter
    if isinstance (attrpath, dict):
      for (k, v) in attrpath.items():
        self.attrpath += '</span>, <span style="color: #483d8b;">' + str (k) + '</span> = <span style="color: #483d8b;">' + str(v)
      self.attrpath = self.attrpath[2:]
    # accept a couple of strings
    else:
      self.attrpath = str(attrpath) + '</span> = <span style="color: #483d8b;">' + str(value) 
&nbsp;
    self.attrpath = '</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">' + self.attrpath + '</span><span style="color: black;">&#41;</span><span style="color: #483d8b;">'
    return
&nbsp;
  def __str__ (self):
    return str (self.attrpath)</span></pre></div></div>

<p>Ahora a <a href="http://www.codigomanso.com/en/2010/09/solved-add-unique-constraints-to-google-app-engine-databases">traducir el texto a inglés</a>&#8230; Ale, otro día más!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codigomanso.com/es/2010/09/solved-anadir-claves-unicas-en-google-app-engine-en-3-lineas/feed/</wfw:commentRss>
		<slash:comments>113</slash:comments>
		</item>
		<item>
		<title>[SOLVED] El teclado numérico no funciona en Ubuntu</title>
		<link>http://www.codigomanso.com/es/2010/09/solved-number-pad-not-working-n-ubuntu/</link>
		<comments>http://www.codigomanso.com/es/2010/09/solved-number-pad-not-working-n-ubuntu/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 06:20:10 +0000</pubDate>
		<dc:creator>Pau Sanchez</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[problem]]></category>
		<category><![CDATA[solved]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.codigomanso.com/es/?p=926</guid>
		<description><![CDATA[Es la segunda vez que me toca corregir el problema de que el teclado numérico no funcione en Ubuntu (y por lo que he visto en foros, también pasa en otras distribuciones de linux).
Solución en 4 simples pasos:
  &#8211; Abrir Sistema -> Preferencias -> Teclado
  &#8211; Click en la Pestaña de Teclas del [...]]]></description>
			<content:encoded><![CDATA[<p>Es la segunda vez que me toca corregir el problema de que el teclado numérico no funcione en Ubuntu (y por lo que he visto en foros, también pasa en otras distribuciones de linux).</p>
<p>Solución en 4 simples pasos:<br />
  &#8211; Abrir <strong>Sistema -> Preferencias -> Teclado</strong><br />
  &#8211; Click en la Pestaña de <strong>Teclas del Ratón</strong><br />
  &#8211; Deseleccionar <strong>&quot;Permitir controlar el puntero usando el teclado numérico&quot;</strong><br />
  &#8211; Y finalmente, hacer click en <strong>Cerrar</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.codigomanso.com/es/2010/09/solved-number-pad-not-working-n-ubuntu/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
	</channel>
</rss>

