<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Python on Karpoke - Just Another Blog</title><link>http://karpoke.ignaciocano.com/tags/python/</link><description>Recent content in Python on Karpoke - Just Another Blog</description><generator>Hugo -- 0.159.0</generator><language>es</language><lastBuildDate>Sat, 28 Feb 2026 15:58:32 +0100</lastBuildDate><atom:link href="http://karpoke.ignaciocano.com/tags/python/index.xml" rel="self" type="application/rss+xml"/><item><title>Build a Hash Table in Python With TDD – Real Python</title><link>http://karpoke.ignaciocano.com/2026/02/28/build-a-hash-table-in-python-with-tdd-real-python/</link><pubDate>Sat, 28 Feb 2026 15:58:32 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2026/02/28/build-a-hash-table-in-python-with-tdd-real-python/</guid><description>&lt;blockquote&gt;
&lt;p&gt;In this step-by-step tutorial, you&amp;rsquo;ll implement the classic hash table
data structure using Python. Along the way, you&amp;rsquo;ll learn how to cope
with various challenges such as hash code collisions while practicing
test-driven development (TDD).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;» Real Python | &lt;a href="https://realpython.com/python-hash-table/"&gt;realpython.com&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Implicit string concatenation</title><link>http://karpoke.ignaciocano.com/2026/01/02/implicit-string-concatenation/</link><pubDate>Fri, 02 Jan 2026 01:02:07 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2026/01/02/implicit-string-concatenation/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Python automatically concatenates adjacent string literals thanks to
implicit string concatenation. This feature can sometimes lead to bugs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;» Trey Hunner | &lt;a href="https://www.pythonmorsels.com/implicit-string-concatenation/"&gt;pythonmorsels.com&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Never write for-loops again</title><link>http://karpoke.ignaciocano.com/2016/12/12/never-write-for-loops-again/</link><pubDate>Mon, 12 Dec 2016 00:22:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2016/12/12/never-write-for-loops-again/</guid><description>&lt;blockquote&gt;
&lt;p&gt;It’s been a while since I started exploring the amazing language features in
Python. At the beginning, it’s just a challenge I gave myself to practice
using more language features instead of those I learned from other
programming language. And things are just getting more fun! Not only the code
become shorter and cleaner, but also code looks more structured and
disciplined. I’ll get into those benefits more in this article.&lt;/p&gt;</description></item><item><title>Iniciar sesión en DynDNS desde el terminal</title><link>http://karpoke.ignaciocano.com/2013/06/10/iniciar-sesion-en-dyndns-desde-el-terminal/</link><pubDate>Mon, 10 Jun 2013 01:00:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2013/06/10/iniciar-sesion-en-dyndns-desde-el-terminal/</guid><description>&lt;p&gt;Hace un par de semanas, DynDNS cambió su política de uso de las cuentas
gratuitas para incluir una cláusula por la cual es necesario hacer
mínimo un login al mes si no se quieren perder los dominios que
tengamos:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Starting now, if you would like to maintain your free Dyn account, you
must log into your account once a month. Failure to do so will result
in expiration and loss of your hostname. This activity helps us
eliminate hostnames that are no longer needed and/or dormant. Note
that an update client will not suffice for this monthly login.&lt;/p&gt;</description></item><item><title>Distribución de frecuencias</title><link>http://karpoke.ignaciocano.com/2012/06/22/distribucion-de-frecuencias/</link><pubDate>Fri, 22 Jun 2012 00:53:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2012/06/22/distribucion-de-frecuencias/</guid><description>&lt;h2 id="distribución-de-los-comandos-más-utilizados"&gt;Distribución de los comandos más utilizados&lt;/h2&gt;
&lt;p&gt;Una de esas combinaciones de comandos curiosas es aquella que nos
devuelve un listado de los &lt;a href="http://www.commandlinefu.com/commands/view/604/list-of-commands-you-use-most-often"&gt;comandos más utilizados&lt;/a&gt; ordenados por
frecuencia, en este caso limitado a los más frecuentes:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ history | awk &amp;#39;{a[$2]++} END {for (i in a) { print a[i] &amp;#34; &amp;#34; i }}&amp;#39; | sort -rn | head
62 cd
50 sudo
45 vim
39 ls
32 ssh
25 wget
23 memento.sh
23 cat
9 curl
9 man
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A partir de estos datos, podemos obtener una &lt;a href="http://bayesianbiologist.com/2012/06/01/distribution-of-oft-used-bash-commands/"&gt;distribución de su
frecuencia de uso&lt;/a&gt; en relación al número total de comandos diferentes
utilizando el paquete estadístico R:&lt;/p&gt;</description></item><item><title>AnonTwi, tweets cifrados</title><link>http://karpoke.ignaciocano.com/2012/06/16/anontwi-tweets-cifrados/</link><pubDate>Sat, 16 Jun 2012 13:23:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2012/06/16/anontwi-tweets-cifrados/</guid><description>&lt;p&gt;&lt;a href="http://anontwi.sourceforge.net/"&gt;AnonTwi&lt;/a&gt; es un &lt;em&gt;script&lt;/em&gt; en Python que permite enviar y recibir
&lt;em&gt;tweets&lt;/em&gt; y mensajes cifrados mediante AES y HMAC-SHA1 en Twitter, al que
se conecta mediante SSL. Otras caracterísiticas son la posibilidad de
usar la red TOR, envío de mensajes largos o la falsificación de las
cabeceras que envía.&lt;/p&gt;
&lt;h2 id="instalación"&gt;Instalación&lt;/h2&gt;
&lt;p&gt;AnonTwi está todavía en fase &lt;em&gt;beta&lt;/em&gt; de desarrollo, algo que se debe
tener en cuenta según el uso que queramos darle, pero si queremos
probarlo, podemos usar la última versión descargándola del repositorio:&lt;/p&gt;</description></item><item><title>vimrepress, publicar en WordPress desde vim</title><link>http://karpoke.ignaciocano.com/2012/05/20/vimrepress-publicar-en-wordpress-desde-vim/</link><pubDate>Sun, 20 May 2012 13:54:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2012/05/20/vimrepress-publicar-en-wordpress-desde-vim/</guid><description>&lt;p&gt;&lt;a href="http://www.vim.org/scripts/download_script.php?src_id=16490"&gt;vimrepress&lt;/a&gt; es un complemento para trabajar con WordPress. Esta mañana
he leído sobre él en el blog de CyberHades y me han entrado ganas de
probarlo.&lt;/p&gt;
&lt;h2 id="instalación"&gt;Instalación&lt;/h2&gt;
&lt;p&gt;Para que funcione, además de instalar el complemento deberemos activar el
servicio XML-RPC en WordPress para publicar de forma remota. Para
activarlo vamos a Ajustes &amp;gt; Escritura y marcamos la casilla XML-RCP.&lt;/p&gt;
&lt;p&gt;Ahora vamos a instalar el complemento. Descargamos la última versión
estable, en estos momentos la 2.1.5, y la descomprimimos en el
directorio &lt;code&gt;~/.vim&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Encuentra el hash</title><link>http://karpoke.ignaciocano.com/2011/09/30/encuentra-el-hash/</link><pubDate>Fri, 30 Sep 2011 00:27:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2011/09/30/encuentra-el-hash/</guid><description>&lt;p&gt;Existen herramientas que permiten romper un &lt;em&gt;hash&lt;/em&gt;, aunque a veces puede
ahorrar tiempo y recursos &lt;a href="http://www.pentestit.com/findmyhash/"&gt;buscar si el &lt;em&gt;hash&lt;/em&gt; ya ha sido encontrado&lt;/a&gt;.
Ni siquiera hace falta una &lt;em&gt;rainbow table&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;findmyhash&lt;/code&gt; es un &lt;em&gt;script&lt;/em&gt; escrito en Python que puede buscar
diferentes tipos de &lt;em&gt;hash&lt;/em&gt; en diferentes servicios de &lt;em&gt;cracking online&lt;/em&gt;.
Los algoritmos soportados son los siguientes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MD4&lt;/li&gt;
&lt;li&gt;MD5&lt;/li&gt;
&lt;li&gt;SHA1&lt;/li&gt;
&lt;li&gt;SHA256&lt;/li&gt;
&lt;li&gt;RMD160&lt;/li&gt;
&lt;li&gt;MYSQL&lt;/li&gt;
&lt;li&gt;CISCO7&lt;/li&gt;
&lt;li&gt;LM&lt;/li&gt;
&lt;li&gt;NTLM&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Un ejemplo sencillo. Si no encuentra el &lt;em&gt;hash&lt;/em&gt;, también lo buscará en
Google:&lt;/p&gt;</description></item><item><title>Limitando el número de procesos por usuario</title><link>http://karpoke.ignaciocano.com/2011/08/01/limitando-el-numero-de-procesos-por-usuario/</link><pubDate>Mon, 01 Aug 2011 19:23:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2011/08/01/limitando-el-numero-de-procesos-por-usuario/</guid><description>&lt;p&gt;Mediante el comando &lt;code&gt;ulimit&lt;/code&gt; podemos consultar y controlar el valor de los
recursos disponibles para la consola y los &lt;a href="http://karpoke.ignaciocano.com/2010/12/16/mejora-del-rendimiento-interactivo-agrupando-tareas-por-terminal/"&gt;procesos que puedan ser iniciados
desde ella&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Las diferentes opciones que acepta este comando son:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;-a All current limits are reported
-b The maximum socket buffer size
-c The maximum size of core files created
-d The maximum size of a process’s data segment
-e The maximum scheduling priority (&amp;#34;nice&amp;#34;)
-f The maximum size of files written by the shell and its children
-i The maximum number of pending signals
-l The maximum size that may be locked into memory
-m The maximum resident set size (many systems do not honor this limit)
-n The maximum number of open file descriptors (most systems do not allow this value to be set)
-p The pipe size in 512-byte blocks (this may not be set)
-q The maximum number of bytes in POSIX message queues
-r The maximum real-time scheduling priority
-s The maximum stack size
-t The maximum amount of cpu time in seconds
-u The maximum number of processes available to a single user
-v The maximum amount of virtual memory available to the shell and, on some systems, to its children
-x The maximum number of file locks
-T The maximum number of threads
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Para consultar todos los valores asignados actualmente:&lt;/p&gt;</description></item><item><title>Endianness</title><link>http://karpoke.ignaciocano.com/2011/07/30/endianness/</link><pubDate>Sat, 30 Jul 2011 17:34:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2011/07/30/endianness/</guid><description>&lt;p&gt;&amp;ldquo;&lt;a href="http://secure.wikimedia.org/wikipedia/es/wiki/Endianness"&gt;Endianicidad&lt;/a&gt;&amp;rdquo; designa el formato en el que se almacenan los datos
de más de un byte en un ordenador. El sistema &lt;em&gt;big-endian&lt;/em&gt; adoptado por
Motorola entre otros, consiste en representar los bytes en el orden
&amp;ldquo;natural&amp;rdquo;, así el valor hexadecimal 0x4A3B2C1D se codificaría en memoria
en la secuencia {4A, 3B, 2C, 1D}. En el sistema &lt;em&gt;little-endian&lt;/em&gt; adoptado
por Intel, entre otros, el mismo valor se codificaría como {1D, 2C, 3B,
4A}, de manera que de este modo se hace más intuitivo el acceso a datos,
porque se efectúa fácilmente de manera incremental de menos relevante a
más relevante (siempre se opera con incrementos de contador en la
memoria).&lt;/p&gt;</description></item><item><title>UnicodeDecodeError con Wapiti</title><link>http://karpoke.ignaciocano.com/2011/05/28/unicodedecodeerror-con-wapiti/</link><pubDate>Sat, 28 May 2011 17:32:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2011/05/28/unicodedecodeerror-con-wapiti/</guid><description>&lt;p&gt;&lt;a href="http://wapiti.sourceforge.net/"&gt;Wapiti&lt;/a&gt; es un escáner de vulnerabilidades web basado en
&lt;a href="http://omniumpotentior.wordpress.com/2011/05/18/fuzzing-web-con-wapiti/"&gt;&lt;em&gt;fuzzing&lt;/em&gt;&lt;/a&gt;. En la última versión, &lt;a href="http://wapiti.sourceforge.net/README"&gt;2.2.1&lt;/a&gt;, permite detectar
vulnerabilidades referente a:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Errores de gestión de ficheros (include/require local y remoto,&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;fopen, readfile...)
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Database Injection (PHP/JSP/ASP SQL Injections y XPath Injections)&lt;/li&gt;
&lt;li&gt;XSS (Cross Site Scripting) Injection&lt;/li&gt;
&lt;li&gt;LDAP Injection&lt;/li&gt;
&lt;li&gt;Command Execution detection (eval(), system(), passtru()&amp;hellip;)&lt;/li&gt;
&lt;li&gt;CRLF Injection (HTTP Response Splitting, session fixation&amp;hellip;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sin embargo, si usamos Ubuntu Natty Narwhal, la versión de los
repositorios es la 1.1.6, por lo que es posible que nos encontremos el
siguiente error al escanear páginas que contengan &lt;a href="http://wiki.python.org/moin/UnicodeDecodeError"&gt;caracteres no
ASCII&lt;/a&gt;. Por ejemplo:&lt;/p&gt;</description></item><item><title>¿Dónde está el site-packages?</title><link>http://karpoke.ignaciocano.com/2011/05/28/donde-esta-el-site-packages/</link><pubDate>Sat, 28 May 2011 16:03:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2011/05/28/donde-esta-el-site-packages/</guid><description>&lt;p&gt;&lt;a href="http://docs.djangoproject.com/en/dev/topics/install/?from=olddocs#remove-any-old-versions-of-django"&gt;Nota&lt;/a&gt; mental:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ python -c &amp;#34;from distutils.sysconfig import get_python_lib; print get_python_lib()&amp;#34;
/usr/lib/python2.7/dist-packages
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="ligeramente-relacionado"&gt;Ligeramente relacionado&lt;/h2&gt;
&lt;p&gt;» &lt;a href="http://karpoke.ignaciocano.com/2011/03/27/creando-y-leyendo-codigos-qr-desde-python/"&gt;Creando y leyendo códigos QR desde Python&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A lo mejor, si el intérprete de Python no encuentra un paquete es que no
está donde debería&amp;hellip; :facepalm:&lt;/p&gt;</description></item><item><title>Desordenando listas en Python</title><link>http://karpoke.ignaciocano.com/2011/03/29/desordenando-listas-en-python/</link><pubDate>Tue, 29 Mar 2011 20:00:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2011/03/29/desordenando-listas-en-python/</guid><description>&lt;p&gt;Si tenemos una lista de elementos, por ejemplo:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; l = [ 2, 3, 5, 7, 11, 13, 17, 19 ]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img alt="Deck Card Shuffler" loading="lazy" src="http://karpoke.ignaciocano.com/images/deck_card_shuffler-300x213.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Y queremos desordenarla, pero con la condición de que ningún elemento
ocupe la misma posición que ocupaba originalmente, podemos aplicar el
&lt;a href="http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Sattolo.27s_algorithm"&gt;algoritmo de Sottolo&lt;/a&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; from random import randrange
&amp;gt;&amp;gt;&amp;gt; def sattoloCycle(items):
... i = len(items)
... while i &amp;gt; 1:
... i = i - 1
... j = randrange(i) # 0 &amp;lt; = j &amp;lt;= i-1
... items[j], items[i] = items[i], items[j]
... return
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; sattoloCycle(l)
&amp;gt;&amp;gt;&amp;gt; print l
[5, 17, 3, 2, 7, 11, 13]
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Creando y leyendo códigos QR desde Python</title><link>http://karpoke.ignaciocano.com/2011/03/27/creando-y-leyendo-codigos-qr-desde-python/</link><pubDate>Sun, 27 Mar 2011 19:46:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2011/03/27/creando-y-leyendo-codigos-qr-desde-python/</guid><description>&lt;p&gt;Un código QR (Quick Response Barcode) permite almacenar información en
un código de barras de dos dimensiones.&lt;/p&gt;
&lt;p&gt;&lt;img alt="cc.qr.code.capacity`" loading="lazy" src="http://karpoke.ignaciocano.com/images/cc.qr_.code_.capacity-300x166.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Hay bastantes servicios en la web que nos permiten crear nuestros
propios códigos, por ejemplo &lt;a href="http://code.google.com/apis/chart/infographics/docs/qr_codes.html"&gt;el de Google&lt;/a&gt;, que podemos emplear desde
la línea de comandos:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ curl http://chart.apis.google.com/chart?chs=150x150&amp;amp;cht=qr&amp;amp;chld=H|0&amp;amp;chl=texto -o qr.png
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img alt="QR Code Python" loading="lazy" src="http://karpoke.ignaciocano.com/images/qrcode-python.png"&gt;&lt;/p&gt;
&lt;p&gt;Un pequeño alias para tenerlo siempre a mano:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ alias qrurl=&amp;#39;qrurl() { curl http://chart.apis.google.com/chart?chs=150x150&amp;amp;cht=qr&amp;amp;chld=H|0&amp;amp;chl=${@// /%20} -o qr.$(date +%Y%m%d%H%M%S).png; }; qrurl&amp;#39;
$ qrurl una ranita iba caminando
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Esto creará un fichero con un nombre parecido a &lt;code&gt;qr.20110325161706.png&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>ls sin ls</title><link>http://karpoke.ignaciocano.com/2011/03/12/ls-sin-ls/</link><pubDate>Sat, 12 Mar 2011 13:11:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2011/03/12/ls-sin-ls/</guid><description>&lt;p&gt;En bash:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ for i in *; do echo $i; done
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img alt="ls" loading="lazy" src="http://karpoke.ignaciocano.com/images/ls-300x232.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Fuente: &lt;a href="http://nfosolutions.com/"&gt;nfosolutions.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;En &lt;a href="http://snippets.dzone.com/posts/show/2735"&gt;C&lt;/a&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/*
*
* Esempio che scansiona una cartella stampando a video i file in essa
* contenuti.
*/
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;#include
#include
#include
#include
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;int main(int argc, char *argv[])
{
DIR *dir;
struct dirent *drent;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt; if(argc &amp;lt; 2)
{
fprintf(stderr, &amp;#34;%s \n&amp;#34;, argv[0]);
return EXIT_FAILURE;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt; if((dir = opendir(argv[1])) == NULL)
{
fprintf(stderr, &amp;#34;Errore opendir()\n&amp;#34;);
return EXIT_FAILURE;
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt; while((drent = readdir(dir)) != NULL)
{
fprintf(stdout, &amp;#34;--&amp;gt; %s\n&amp;#34;, drent-&amp;gt;d_name);
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt; if(closedir(dir) &amp;lt; 0)
{
fprintf(stderr, &amp;#34;Errore closedir()\n&amp;#34;);
return EXIT_FAILURE;
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;En Python:&lt;/p&gt;</description></item><item><title>Mystery</title><link>http://karpoke.ignaciocano.com/2011/02/26/mystery/</link><pubDate>Sat, 26 Feb 2011 00:49:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2011/02/26/mystery/</guid><description>&lt;p&gt;Casi parece que está escrito en chino, o mejor dicho en &lt;em&gt;brainfuck&lt;/em&gt;, o
puede que no sea muy &lt;em&gt;&lt;a href="http://karpoke.ignaciocano.com/2011/02/26/python-zen/"&gt;zen&lt;/a&gt;&lt;/em&gt;, pero no deja de ser &lt;em&gt;&lt;a href="http://blog.garlicsim.org/post/3504711416#comment-156082460"&gt;elegante&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;def mystery(n):
a = list(range(n))
[[(yield i) for a[::i] in [([0]*n)[::i]]] for i in a[2:] if a[i]]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;El nombre de la función pretende no dar pistas para que intentemos
averiguar qué hace exactamente esta función. He aquí una pista:&lt;/p&gt;
&lt;p&gt;&lt;img alt="prime numnbers" loading="lazy" src="http://karpoke.ignaciocano.com/images/prime-numbers-300x300.gif" title="prime-numbers"&gt;&lt;/p&gt;
&lt;p&gt;Fuente: &lt;a href="http://www.numberspiral.com/"&gt;numberspiral.com&lt;/a&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; f = mystery(20)
&amp;gt;&amp;gt;&amp;gt; try:
... while True:
... print f.next()
... except StopIteration:
... pass
2
3
5
7
11
13
17
19
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Python Zen</title><link>http://karpoke.ignaciocano.com/2011/02/26/python-zen/</link><pubDate>Sat, 26 Feb 2011 00:40:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2011/02/26/python-zen/</guid><description>&lt;p&gt;&lt;em&gt;Just to keep in mind&amp;hellip;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="zen" loading="lazy" src="http://karpoke.ignaciocano.com/images/zen-300x225.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Author: &lt;em&gt;&lt;em&gt;&lt;a href="http://www.flickr.com/photos/euart/282104427/"&gt;euart&lt;/a&gt;&lt;/em&gt;&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; import this
The Zen of Python, by Tim Peters
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren&amp;#39;t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you&amp;#39;re Dutch.
Now is better than never.
Although never is often better than _right_ now.
If the implementation is hard to explain, it&amp;#39;s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let&amp;#39;s do more of those!
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Descifrando al César en Python</title><link>http://karpoke.ignaciocano.com/2011/02/16/descifrando-al-cesar-en-python/</link><pubDate>Wed, 16 Feb 2011 03:40:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2011/02/16/descifrando-al-cesar-en-python/</guid><description>&lt;p&gt;Si lo que pretendemos es, dada una cadena, sustituir una serie de
caracteres por otra, en Python es tan sencillo como pasarle al método
&lt;code&gt;maketrans&lt;/code&gt; una cadena con los caracteres que queremos cambiar y otra
con los caracteres a utilizar en su lugar. Ambas cadenas deberán tener
la misma longitud. Este método devuelve una tabla de traducción, un
objeto susceptible de ser usado por el método &lt;code&gt;translate&lt;/code&gt; el cual se
aplica sobre un &lt;em&gt;string&lt;/em&gt;, como veremos.&lt;/p&gt;</description></item><item><title>Asignar la IP que queramos a un dominio de DynDNS</title><link>http://karpoke.ignaciocano.com/2010/12/30/asignar-la-ip-que-queramos-a-un-dominio-de-dyndns/</link><pubDate>Thu, 30 Dec 2010 19:12:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2010/12/30/asignar-la-ip-que-queramos-a-un-dominio-de-dyndns/</guid><description>&lt;p&gt;Con el comando &lt;code&gt;inadyn&lt;/code&gt; podemos actualizar la IP de nuestro dominio, o
&lt;a href="http://karpoke.ignaciocano.com/2010/12/11/dyndns-e-inadyn/"&gt;dominios&lt;/a&gt;, en DynDNS, pero la IP no se pasa como argumento sino que
se hace una consulta a un servidor que devuelve la IP pública que
tenemos en ese momento. Por defecto, el servidor es
&lt;code&gt;checkip.dyndns.org:80&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Podemos hacer que el dominio apunte a la IP que queramos utilizando el
argumento &lt;code&gt;--ip_server_name&lt;/code&gt; para especificar un servidor controlado por
nosotros y que devuelva la IP que queramos.&lt;/p&gt;</description></item><item><title>Buscando rootkits y troyanos</title><link>http://karpoke.ignaciocano.com/2010/12/17/buscando-rootkits-y-troyanos/</link><pubDate>Fri, 17 Dec 2010 03:04:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2010/12/17/buscando-rootkits-y-troyanos/</guid><description>&lt;p&gt;Tres herramientas muy útiles: &lt;code&gt;rkhunter&lt;/code&gt;, &lt;code&gt;chkrootkit&lt;/code&gt; y &lt;code&gt;unhide&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="rkhunter"&gt;rkhunter&lt;/h2&gt;
&lt;p&gt;Busca &lt;em&gt;rootkits&lt;/em&gt;, puertas traseras y &lt;em&gt;exploits&lt;/em&gt;. Al instalarlo, se
programa un escaneo diario, pero cuando instalamos las actualizaciones
de algunos programas, &lt;a href="http://www.mail-archive.com/rkhunter-users@lists.sourceforge.net/msg01966.html"&gt;las firmas de &lt;code&gt;rkhunter&lt;/code&gt; quedan obsoletas&lt;/a&gt;, por
lo que empieza a mandar avisos.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Warning: The file properties have changed:
File: /usr/bin/md5sum
Current inode: 1093680 Stored inode: 475456
Current file modification time: 1285094009 (21-sep-2010 20:33:29)
Stored file modification time : 1267759792 (05-mar-2010 04:29:52)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Podemos actualizar las firmas de &lt;code&gt;rkhunter&lt;/code&gt; ejecutando:&lt;/p&gt;</description></item><item><title>Intercambio de los valores de dos variables</title><link>http://karpoke.ignaciocano.com/2010/12/03/intercambio-de-los-valores-de-dos-variables/</link><pubDate>Fri, 03 Dec 2010 21:01:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2010/12/03/intercambio-de-los-valores-de-dos-variables/</guid><description>&lt;p&gt;&lt;img alt="Teleporter" loading="lazy" src="http://karpoke.ignaciocano.com/images/teleporter-300x299.jpg"&gt;&lt;/p&gt;
&lt;p&gt;En algunos lenguajes, intercambiar el valor de la variable &lt;code&gt;a&lt;/code&gt; por el de
la variable &lt;code&gt;b&lt;/code&gt; implica, explícitamente, utilizar una variable temporal:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;t = a;
a = b;
b = t;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;En Python:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;a, b = b, a
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pero esperen, aún hay más:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;a, b, c, d = d, c, b, a
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h4 id="actualizado-el-31-de-julio-de-2011"&gt;Actualizado el 31 de julio de 2011&lt;/h4&gt;
&lt;p&gt;En &lt;a href="http://www.commandlinefu.com/commands/view/8937/multiple-variable-assignments-from-command-output-in-bash"&gt;Bash&lt;/a&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ read a b c &amp;lt;&amp;lt;&amp;lt; $(echo $c $b $a)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="http://www.commandlinefu.com/commands/view/8943/multiple-variable-assignments-from-command-output-in-bash"&gt;Otra manera&lt;/a&gt;:&lt;/p&gt;</description></item><item><title>Cómo publicar directorios en Ubuntu One y Dropbox</title><link>http://karpoke.ignaciocano.com/2010/10/31/como-publicar-directorios-en-ubuntu-one-y-dropbox/</link><pubDate>Sun, 31 Oct 2010 06:28:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2010/10/31/como-publicar-directorios-en-ubuntu-one-y-dropbox/</guid><description>&lt;p&gt;&lt;a href="http://one.ubuntu.com/"&gt;Ubuntu One&lt;/a&gt; es el servicio que ofrece Ubuntu en la nube. Entre otras
cosas, como &lt;a href="http://wiki.ubuntu.com/UbuntuOne/Tutorials/"&gt;sincronizar archivos de configuración o nuestros
favoritos&lt;/a&gt;, permite &lt;a href="http://wiki.ubuntu.com/UbuntuOne/Tutorials/FileSharing"&gt;compartir archivos y directorios&lt;/a&gt; de nuestro
espacio en la nube con las personas que queramos de una forma sencilla.&lt;/p&gt;
&lt;p&gt;Tambíen permite publicar archivos, para cada uno de los cuales se genera
una URL corta, y que sean accesibles por cualquiera. Sin embargo, &lt;a href="http://lists.launchpad.net/ubuntuone-users/msg00523.html"&gt;no
permite publicar directorios&lt;/a&gt;, al menos por ahora.&lt;/p&gt;</description></item><item><title>Actualización recursiva de un diccionario en Python</title><link>http://karpoke.ignaciocano.com/2010/09/28/actualizacion-recursiva-de-un-diccionario-en-python/</link><pubDate>Tue, 28 Sep 2010 13:50:00 +0100</pubDate><guid>http://karpoke.ignaciocano.com/2010/09/28/actualizacion-recursiva-de-un-diccionario-en-python/</guid><description>&lt;p&gt;Cuando actualizamos un diccionario con otro en Pyhton, el método &lt;code&gt;update&lt;/code&gt; copia
las entradas del diccionario fuente en el diccionario destino, sobreescribiendo
las de éste si la entrada existe en ambos diccionarios.&lt;/p&gt;
&lt;p&gt;En particular, si un diccionario contiene una entrada que es a su vez otro
diccionario, no se realiza una actualización sobre ésta, por lo que se pierden
los valores que no estuvieran en el diccionario fuente.&lt;/p&gt;
&lt;p&gt;Ilustremos este comportamiento con un ejemplo:&lt;/p&gt;</description></item></channel></rss>