Mostrando entradas con la etiqueta python. Mostrar todas las entradas
Mostrando entradas con la etiqueta python. Mostrar todas las entradas

jueves, junio 28, 2018

Dos enlaces a libros gratuitos sobre Software Defined Radio y Tratamiento de señales en Python

Si os gusta el tratamiento de señales usando Python, se ha publicado en PDF Think DSP escrito por Allen B. Downey para los que queráis introduciros en el tratamiento de señales usando Python. El libro se divide en los siguientes capítulos:

  • Chapter 1 - Sounds and signals
  • Chapter 2 - Harmonics
  • Chapter 3 - Non-periodic signals
  • Chapter 4 - Noise
  • Chapter 5 - Autocorrelation
  • Chapter 6 - Discrete Cosine Transform
  • Chapter 7 - Discrete Fourier Transform
  • Chapter 8 - Filtering and Convolution
  • Chapter 9 - Differentiation and Integration
  • Chapter 10 - LTI systems
  • Chapter 11 - Modulation and sampling

Para aquellos que os guste el Software Defined Radio, Software-Defined Radio for Engineers, de Travis F. Collins, Robin Getz, Di Pu y Alexander M. Wyglinski. El libro se divide en los siguientes capítulos:

  • Chapter 1 – Introduction to Software-Defined Radio
  • Chapter 2 – Signals and Systems
  • Chapter 3 – Probability in Communications
  • Chapter 4 – Digital Communications Fundamentals
  • Chapter 5 – Understanding SDR Hardware
  • Chapter 6 – Timing Synchronization
  • Chapter 7 – Carrier Synchronization
  • Chapter 8 – Frame Synchronization and Channel Coding
  • Chapter 9 – Channel Estimation and Equalization
  • Chapter 10 – Orthogonal Frequency Division Multiplexing
  • Chapter 11 – Applications for Software-Defined Radio

lunes, julio 31, 2017

Renderizar Markdown en Python: Las extensiones

Lo que hace interesante al módulo de Markdown en Python es la incorporación de un API que permite añadir extensiones y adaptarlo a las necesidades específicas. Existe todo un conjunto de extensiones oficiales, aquellas que son soportadas por los autores del módulo markdown y un buen conjunto de extensiones de terceros que pueden servir para añadir el comportamiento que nos interese al sistema.

Por ejemplo, si se quiere usar alguna de los añadidos a markdown de github, se puede hacer con la extensión py-gfm:

$ virtualenv markdown
$ cd markdown
$ source bin/activate
$ # Se instala markdown automáticamente
$ pip install py-gfm

Para renderizar ficheros que use esta extensión, se puede usar el siguiente código:

import markdown
from mdx_gfm import GithubFlavoredMarkdownExtension
import sys

md = markdown.Markdown(extensions=[GithubFlavoredMarkdownExtension()])
for filename in sys.argv[1:]:
    with open(filename, mode="r") as f:
        content = f.read()
        html = md.convert(content.decode('utf-8'))
        print html.encode('utf-8')

Al igual que ocurre con el módulo normal, desde la propia línea de comandos es posible indicar que se cargue una extensión, para el ejemplo anterior:

python  g-m markdown -x mdx_gfm file1 file2 ...

La opción -x especifica el path hasta el módulo donde se encuentra la extensión.

Existe documentación para crear una extensión y añadirla al sistema de markdown. No es demasiado complicado desarrollar una extensión, aunque desde mi punto de vista la documentación no es del todo clara. Un ejemplo de extensión, que añade a todas las etiquetas una clase parrafo sería el siguiente código. Dejo para otra entrada mis notas de como desarrollar nuevas extensiones.

from markdown.util import etree
from markdown.treeprocessors import Treeprocessor
from markdown.extensions import Extension

class ParagraphProcessor(Treeprocessor):
    def __init__(self, md):
        super(ParagraphProcessor, self).__init__(md)
    def set_paragraph_style(self, element):
        for child in element:
            if child.tag == "p":
                child.set("class", "parrafo") #set the class attribute
            self.set_paragraph_style(child)
    def run(self, root):
        self.set_paragraph_style(root)

class ParagraphClassExtension(Extension):
     def extendMarkdown(self, md, md_globals):
         md.treeprocessors.add('paragraphProcessor', ParagraphProcessor(md),">inline")

Si suponemos que el código anterior está en un módulo llamado pproc y que está en nuestro PYTHONPATH se puede usar con:

import markdown
from mdx_gfm import GithubFlavoredMarkdownExtension
from pproc import ParagraphClassExtension
import sys

md = markdown.Markdown(extensions=[GithubFlavoredMarkdownExtension(), ParagraphClassExtension()])
for filename in sys.argv[1:]:
    with open(filename, mode="r") as f:
        content = f.read()
        html = md.convert(content.decode('utf-8'))
        print html.encode('utf-8')

miércoles, julio 26, 2017

Renderizar Markdown en Python

Markdown es un lenguaje de marcas creado por John Grubber, que buscaba un formato de texto estructurado que fuera fácil de escribir y de leer. Un fichero escrito en este formato se procesa con la utilidad del mismo nombre para generar contenido en XHTML / HTML válido. Con el paso del tiempo, el uso de este formato se ha hecho muy popular y plataformas como Git Hub han desarrollado su propia versión adaptada a sus sistema de comentarios y documentación.

Un ejemplo de fichero de este tipo:

# Encabezado 1
## Encabezado 2

 * Elemento 1
 * Elemento 2 
 * Elemento 3 

Esto es un [Enlace a Google](www.google.com)

El módulo de Python Python-Markdown implementa la especificación de John Grubber - con algunos detalles diferentes - y proporciona un API para añadir extensiones. De esta manera, es sencillo adaptarse a diferentes versiones de Markdown.

Si se trabaja con un entorno virtual, se puede instalar con:

$ virtualenv markdown
$ cd markdown
$ source bin/activate
$ pip install markdown

Un script sencillo que hará la conversión a html de un fichero UTF-8 que usa markdown que se pase como parámetros

import markdown
import sys

md = markdown.Markdown()
for filename in sys.argv[1:]:
    with open(filename, mode="r") as f:
        content = f.read()
        html = md.convert(content.decode('utf-8'))
        print html.encode('utf-8')

Si se aplica al ejemplo anterior, el código HTML resultante es:

<h1>Encabezado 1</h1>
<h2>Encabezado 2</h2>
<ul>
<li>Elemento 1</li>
<li>Elemento 2</li>
<li>Elemento 3</li>
</ul>
<p>Esto es un <a href="www.google.com">Enlace a Google</a></p>

Comentar que el módulo de Python ya tiene una utilidad para hacer lo mismo, se llama de la siguiente manera:

python -m markdown fichero.md

viernes, marzo 31, 2017

Lorem Ipsum en Python y LaTeX

Lorem ipsum es un texto que se suele usar para probar el formato tipográfico de un diseño. Por extensión, hace referencia a cualquier texto aleatorio que se usa para comprobar el correcto funcionamiento de un programa. Así, que es raro que no exista alguno de esos generadores para diversos lenguajes de programación o entornos de edicción de texto. Dos ejemplos de su uso en python y LaTeX, donde estos generadores me han sido útiles:

Python

En Python la librería que he usado para generar este tipo de textos es loremipsum. Puede instalarse de manera muy sencilla con pip y su documentación es muy sencilla de seguir, con varios ejemplos:

from loremipsum import get_sentences, get_paragraphs
# Generate a list of n sentences
list_sentences = get_sentences(10)
print list_sentences
# Generate n paragraphs
paragraphs = get_paragraphs(4)
print paragraphs

Si se quiere obtener estadísticas de los párrafos generados se puede usar las funciones con prefijo generate_ Por ejemplo:

from loremipsum import generate_sentence
(total_sentences, total_words, sentence) = generate_sentence()
print total_sentences, total_words
print sentence

LaTeX

En LaTeX se puede usar el paquete lipsum para generar este tipo de textos de prueba. Suele venir con la mayoría de las instalaciones de LaTeX. Su uso es sencillo. Cargamos el paquete y usamos la macro \lipsum con un intervalo que señala los párrafos que se quieren generar:

\documentclass[10pt,a4paper]{article}
% UTF-8 and friends
\usepackage[utf8]{inputenc}
\usepackage[spanish]{babel}
\usepackage{lipsum}
\begin{document}
\section*{First section}
\lipsum[1-2]
\section*{Second section}
\lipsum[1-3]
\end{document}

martes, enero 24, 2017

boto3: Colecciones y acceso a S3

Estos últimos días estoy empezando a usar el Amazon Web Services (AWS) SDK for Python, llamado boto3. Una de las cosas interesantes de esta versión del SDK es la disponibilidad de las colecciones, gracias a las cuales es muy sencillo iterar sobre conjuntos de datos o filtrar los mismos sin necesidad de usar los paginadores, ya que el sistema se encarga de hacerlo por nosotros.

Por ejemplo, obtener todos los objetos que hay en un bucket S3 es tan sencillo como:

bucket = s3.Bucket(TARGET_BUCKET)
for obj in bucket.objects.all():
    print(obj)

Recordar, que aunque parezca extraño, el espacio de nombres de un bucket S3 es plano. Todos los objetos están identificados por una clave única, sólo que por convención, se usa un separador de path (normalmente "/") para dar la ilusión de la existencia de directorios.

Es más, con ayudas de las colecciones se puede filtra para que nos devuelva todos los objetos cuya clave coincida con un prefijo determinado y pertenezca a un bucket:

TARGET_KEYS="list_3000_objects"
KEY_SEPARATOR="/"
s3 = boto3.resource('s3')
bucket = s3.Bucket(TARGET_BUCKET)
for obj in bucket.objects.filter(Bucket=TARGET_BUCKET, Prefix=TARGET_KEYS + KEY_SEPARATOR):
    print(obj)

La información la saqué de esta pregunta sobre boto3 en StackOverflow que hice.

viernes, febrero 13, 2015

youtube-dl: Bajar videos de Youtube (y cientos de sitios más)

youtube-dl es una utilidad de Python que permite bajar vídeos de Youtube y multitud de sitios desde la línea de comandos. Es Python puro, con lo cual lo único que necesita es tener instalado en intérprete, pudiéndose instalar en cualquier sistema operativo. En el README tiene el proceso de instalación. Sin embargo, yo prefiero instalarlo dentro de un entorno virtual con ayuda de virtualenv y pip:

baldurgate: terron$virtualenv youtube-dl
baldurgate: terron$source youtube-dl/bin/activate
(youtube-dl)baldurgate:terron$pip install youtube-dl

Utilizarlo es muy sencillo. Lo único que hay que hacer es pasar la URL de Youtube - o del servicio que nos interese -, youtube-dl se conectará, bajará el HTML lo analizará y bajará los distintos videos. Se puede llamar a la utilidad con youtube-dl url. En el caso de Youtube, que es donde lo he probado, puede bajarse listas o vídeos individuales. Por ejemplo, si me quiero bajar todos los vídeos de la lista del 75 aniversario Ejército del Aire, basta con pasar como url la lista:

(youtube-dl)baldurgate:terron$youtube-dl "https://www.youtube.com/playlist?list=PLFoJHJL75dfY42pevKzfeuhFG8iNq8QzL"

Para bajar un vídeo bastaría con introducir la url

(youtube-dl)baldurgate:terron$youtube-dl "https://www.youtube.com/watch?v=LF0rKW1DEMo"

El uso de la " es para evitar problemas con el shell a la hora de interpratar algunos caracteres especiales que pueden aparecer en las urls de los videos.

Esto es el uso básico, lo interesante de la utilidad es la multitud de opciones que tiene, que nos permite filtrar los videos que nos queremos bajar en base a fechas o expresiones regulares, procesar los vídeos si tenemos el ffmpeg o avconv instalado, soporte para distintos esquemas de autentificación, proxies, ... se puede consultar las opciones con ayuda de -h o --help. Comentar que en el fichero de documetación hay instruciones para poder extender el programa con nuevos sites y como compilarlo para que se pueda distribuir fácilmente. Por último decir que el programa es de dominio público, pudiéndose usar para lo que se desee.

viernes, marzo 16, 2012

El historial de Safari: Uso de plist desde Python


Tenía la curiosidad por saber como el navegador de Apple - Safari - almacena el historial en la cuenta de cada usuario. Pensaba que iba a usar sqlite, como hace por ejemplo Firefox, pero tras mirar en ~/Library/Safari el fichero que contiene el historial es History.plist. Esta es un archivo en formato plist binario.

Para poder curiosear con él, lo primero que hay que hacer es pasarlo a formato de texto, que es un xml codificado con el formato utf-8. Para facilitar la conversión MacOS X tiene la herramienta en línea de comandos plutil. La conversión de salida está controlada por la opción -convert, así que si queremos pasar la plist binaria a una plist en XML, se puede
hacer con la siguiente orden:


swordcoast:~ terron$ plutil -convert xml1 -o history_xml.plist History.plist

La order anterior habrá creado el fichero history_xml.plist que se puede ver con cualquier editor de texto que soporte codificaciones utf-8 como vim

Como muchos sabréis, si se tiene el Xcode instalado, se puede abrir la lista en formato binario sin problemas. Con un simple open History.plist en la línea de comandos se puede ver el contenido de la misma y editarlo si se desea - suponiendo que el sistema tenga asociado la extensión .plist a Xcode -.

Me gusta bastante Python, y quería procesar el contenido de la lista - una vez convertida a formato XML - para ver las entradas que había ido visitando. No es necesario parsear el XML, puesto que Python tiene un módulo oficial, plistlib que nos permite leer y procesar los ficheros plist de MacOS X. Por ejemplo el siguiente script lee el historial en XML, escribe la URL y la fecha de la última visita.


#!/usr/bin/python
import plistlib
import sys
import time
import calendar

def dump_files (filepath):
    pl = plistlib.readPlist(filepath)
    history = pl['WebHistoryDates']
    for entry in history:
            url = entry['']
            lastdate = float(entry['lastVisitedDate'])
            toffset = calendar.timegm(time.strptime("01/01/2001", "%d/%m/%Y"))
            print "%s;'%s'" % (time.ctime(lastdate),url)+toffset
for f in sys.argv[1:]:
        dump_files(f)

Como puede verse, plist.readPlist() nos devuelve una lista donde cada una de las entradas es un diccionario. En este caso, cada entrada tiene una serie de claves que se puede obtener:

ClaveDescripción
vacíaLa URL del historial.
displayTitleTítulo de la página a la que se ha visitado.
lastVisitedDateFecha de la última visita
titleTítulo de la página tal como se ha obtenido del servicor
visitCountNúmero de visitas
lastVisitWasFailureBoleano que indica que la última visita ha fallado

Aparte, existe otros campos que son arrays como W y D que no se lo que son. Un detalle sobre el campo lastVisitedDate es que implica el número de segundos desde el 1 de enero del 2001, ya que corresponde con el tipo de datos CFAbsoluteTime que mide el tiempo desde el 1 de enero del 2001 GMT. Por eso el script suma toffset a la hora de convertir el tiempo para la referencia de Unix


Technorati Tags: ,

viernes, marzo 27, 2009

Google investiga en la mejora de rendimiento de Python

(vía Ars Technica) Python siempre ha sido un lenguaje importante dentro de Google. La actual implementación del lenguaje se ejecuta sobre una máquina virtual propia. Ahora los ingenieros de Google quieren diseñar un JIT (just in time compiler), usando como base para el mismo el compilador LLVM Compiler Infrastructure. Esta nueva implementación de Python se agrupa bajo el proyecto unladen-swallow. Los objetivos del mismo son:
  • Implementar Python de tal manera que sea capaz de aumentar la velocidad de ejecución de la actual hasta cinco veces.
  • Conservar la estabilidad de la versión actual.
  • Compatibilidad a nivel de fuentes con las aplicaciones y módulos actuales.
  • Quieren donar esta rama al repositorio general.

Google quiere usar Python en proyectos que necesiten rendimiento en vez de C, puesto que es un lenguaje que da al usuario herramientas de mucho más alto nivel para implementar las funciones que desee amén de una amplia librería de módulos con funciones probadas.

Technorati Tags: , ,

martes, febrero 03, 2009

Novedades de Python 3.x en Developer Works

La gente de IBM ha publicado un par de artículos sobre las próximas novedades de Python 3.x. En el primero de ellos, Python 3 primer, Part 1: What's new en Python 3 primer, Part 2: Advanced topics se habla sobre:
  • La nueva función print()
  • El cambio de raw_input() a input()
  • Un nuevo tipo, bytes para almacenar enteros entre 0 y 127, es decir, caracteres ASCII no extendidos.
  • Permite identificadores que sean cadenas Unicode y evitar la conversión a ASCII de la función repr()
  • Aparece una nueva manera de utilizar cadenas formateadas, aparte del operador %. Los objetos tienen ahora un o format
  • Cambios en los diccionarios. Desaparecen algunos métodos.
  • Nuevo modelo de entrada y salida
  • Class decorators
  • Metaclasses
  • Abstract base classes
  • Cambio en la sintaxis de las excepciones.
  • Se añade la represantación binaria a los posibles literales numéricos y se modifica el octal
  • Anotación de funciones
Puede verse en los dos artículos de Developer Works pueden verse varios ejemplos de lo anterior. Espero poco a poco, ir viéndolas y experimentando con ellas, aunque la versión 3.0 tardará en estar generalizada y convivirá mucho tiempo con la 2.x, es interesante ver las novedades, es especial porque poco a recibido alguna de las características de la versión 3.x para que se pueda ir adaptando el código.

Technorati Tags: