3ENGINE

Programación y otros cachivaches

Etiqueta: Python

Página 4/6

Tecnologia

argparse: módulo de análisis de línea de comandos para Python


El módulo argparse (PEP389) módulo de análisis de línea de comandos que ofrece más funcionalidad que los módulos de análisis de línea de comandos existentes en la biblioteca estándar.

A partir de la versión Python 2.7 y 3.2 el módulo argparse sustituye al módulo optparse. Existe un tutorial que puedes seguir para saber cómo funciona.

módulo de análisis de línea de comandos

Para un aprendizaje rápido de este módulo he creado una ejemplo con los comandos básicos.

Código

# -*- coding: cp1252 -*-
from argparse import ArgumentParser

# ArgumentParser con una descripción de la aplicación 
# (https://docs.python.org/2/library/argparse.html#argumentparser-objects)
parser = ArgumentParser(description='%(prog)s is an ArgumentParser demo')

# Argumento posicional. Los argumentos posicionales son obligatorios.
parser.add_argument('arg1')

# Un argumento posicional con una descripción 
parser.add_argument('arg2', help='help for arg2')

# Un argumento posicional con un tipo definido de tipo int 
# (https://docs.python.org/2/library/argparse.html#type)
parser.add_argument('arg3', help='help for arg3', type=int)

# Argumento posicional con tres opciones posibles 
# (https://docs.python.org/2/library/argparse.html#choices)
parser.add_argument('arg4', choices=['rock', 'paper', 'scissors'])

# Argumento opcional. Si se pametriza, requiere acompañarlo de un valor
parser.add_argument('-opt1')

# Un argumento opcional puede tener varios nombres
parser.add_argument('-opt2', '--option2')

# Argumento opcional con una descripción. Si se pametriza, requiere 
# acompañarlo de un valor de tipo int
parser.add_argument('-opt3', help='help for opt3', type=int)

# Argumento opcional con una descripción. Si se pametriza, requiere 
# acompañarlo de un valor de tipo int. Por defecto el valor es 10
parser.add_argument('-opt4', help='help for opt4', type=int, default=10)

# Argumento opcional. Con 'action' damos valor si el argumento se parametriza 
# (https://docs.python.org/2/library/argparse.html#action)
parser.add_argument('-opt5', '--option5', help='help for opt5', 
action='store_true', default=False)

# Argumento opcional requerido
parser.add_argument('-opt6', required=True)

# Argumento opcional con tres opciones posibles
# (https://docs.python.org/2/library/argparse.html#choices)
parser.add_argument('-opt7', choices=['rock', 'paper', 'scissors'])

# Argumento opcional que requiere dos argumentos
parser.add_argument('-opt8', nargs=2)

# Argumento opcional que requiere de 1 a N argumentos
parser.add_argument('-opt9', nargs='+')

# Argumento opcional que requiere de 0 a N argumentos
parser.add_argument('-opt10', nargs='*')

# Por último parsear los argumentos
args = parser.parse_args()

# Imprimir los parametros
print 'args.arg1:', args.arg1
print 'args.arg2:', args.arg2
print 'args.arg3:', args.arg3
print 'args.arg2:', args.arg4
print 'args.opt1:', args.opt1
print 'args.opt2:', args.option2
print 'args.opt3:', args.opt3
print 'args.opt4:', args.opt4
print 'args.opt5:', args.option5
print 'args.opt6:', args.opt6
print 'args.opt7:', args.opt7
print 'args.opt8:', args.opt8
print 'args.opt9:', args.opt9
print 'args.opt10:', args.opt10

Ayuda básica

>python argcons.py
usage: argcons.py [-h] [-opt1 OPT1] [-opt2 OPTION2] [-opt3 OPT3] [-opt4 OPT4]
                  [-opt5] -opt6 OPT6 [-opt7 {rock,paper,scissors}]
                  [-opt8 OPT8 OPT8] [-opt9 OPT9 [OPT9 ...]]
                  [-opt10 [OPT10 [OPT10 ...]]]
                  arg1 arg2 arg3 {rock,paper,scissors}
argcons.py: error: too few arguments

Mostrar ayuda extendida

>python argcons.py -h
usage: argcons.py [-h] [-opt1 OPT1] [-opt2 OPTION2] [-opt3 OPT3] [-opt4 OPT4]
                  [-opt5] -opt6 OPT6 [-opt7 {rock,paper,scissors}]
                  [-opt8 OPT8 OPT8] [-opt9 OPT9 [OPT9 ...]]
                  [-opt10 [OPT10 [OPT10 ...]]]
                  arg1 arg2 arg3 {rock,paper,scissors}

argcons.py is an ArgumentParser demo

positional arguments:
  arg1
  arg2                  help for arg2
  arg3                  help for arg3
  {rock,paper,scissors}

optional arguments:
  -h, --help            show this help message and exit
  -opt1 OPT1
  -opt2 OPTION2, --option2 OPTION2
  -opt3 OPT3            help for opt3
  -opt4 OPT4            help for opt4
  -opt5, --option5      help for opt5
  -opt6 OPT6
  -opt7 {rock,paper,scissors}
  -opt8 OPT8 OPT8
  -opt9 OPT9 [OPT9 ...]
  -opt10 [OPT10 [OPT10 ...]]

Ejemplo de uso

>python argcons.py  a b 15 rock -opt6 c -opt7 rock -opt8 1 2 -opt9 1 2 3 d e f -opt10
args.arg1: a
args.arg2: b
args.arg3: 15
args.arg2: rock
args.opt1: None
args.opt2: None
args.opt3: None
args.opt4: 10
args.opt5: False
args.opt6: c
args.opt7: rock
args.opt8: ['1', '2']
args.opt9: ['1', '2', '3', 'd', 'e', 'f']
args.opt10: []



Tecnologia

Stemming con Python


Stemming

Según la wikipedia Stemming es un método para reducir una palabra a su raíz o (en inglés) a un stem o lema. Hay algunos algoritmos de stemming que ayudan en sistemas de recuperación de información. Stemming aumenta el recall que es una medida sobre el número de documentos que se pueden encontrar con una consulta. Por ejemplo una consulta sobre bibliotecas también encuentra documentos en los que solo aparezca bibliotecario porque el stem de las dos palabras es bibliotec. Mas información en la Wikipedia.

Lematización

Existe otro método llamado Lematización que se diferencia del Stemming en que dada una forma flexionada (es decir, en plural, en femenino, conjugada, etc), halla el lema que por convenio se acepta como representante de todas las formas flexionadas de una misma palabra. Es decir, el lema de una palabra es la palabra que nos encontraríamos como entrada en un diccionario tradicional: singular para sustantivos, masculino singular para adjetivos, infinitivo para verbos. Por ejemplo, decir es el lema de dije, pero también de diré o dijéramos; guapo es el lema de guapas; mesa es el lema de mesas. Mas información en la Wikipedia.

Implementación de Stemming en Python

Es posible realizar Stemming mediante un algoritmo que use reglas gramaticales de derivación morfológica para el idioma en cuestión, o bien usando un diccionario informatizado que asocie a cada forma su lema (palabra) representante. Para el primera solución Snowball (Github) es un pequeño lenguaje de procesamiento implementado en ANSI C para la creación y uso de algoritmos de stemming. Después disponemos de PyStemmer (Github) que es un wrapper de Snowball para python.

Instala PyStemmer con Pip

pip install pystemmer

Nota: Si durante la instalación de PyStemmer se produce un error de este estilo es porque PyStemmer necesita un compilador de C++ para Python. Sigue las instrucciones :

error: Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall.bat). 
Get it from http://aka.ms/vcpython27

Test:

# idiomas disponibles
>>> import Stemmer
>>> print(Stemmer.algorithms())
[u'danish', u'dutch', u'english', u'finnish', u'french', u'german', u'hungarian',
 u'italian', u'norwegian', u'porter', u'portuguese', u'romanian', u'russian',
 u'spanish', u'swedish', u'turkish']

# stem de la palabra en inglés 'cycling'
>>> import Stemmer
>>> stemmer = Stemmer.Stemmer('english')
>>> print(stemmer.stemWord('cycling'))
cycl

# stem de varias palabras en inglés 
>>> import Stemmer
>>> stemmer = Stemmer.Stemmer('english')
>>> print(stemmer.stemWords(['cycling', 'cyclist']))
['cycl', 'cyclist']

# Permite codificación UTF-8
>>> import Stemmer
>>> stemmer = Stemmer.Stemmer('english')
>>> print(stemmer.stemWords(['cycling', u'cyclist']))
['cycl', u'cyclist']

# Por defecto la caché de palabras es de 10000, pero
# se puede modificar
>>> import Stemmer
>>> print(stemmer.maxCacheSize)
10000
>>> stemmer.maxCacheSize = 1000
>>> print(stemmer.maxCacheSize)
1000

# Otro ejemplo en español
>>> import Stemmer
>>> stemmer = Stemmer.Stemmer('spanish')
>>> print stemmer.stemWords(['camionero','camiones','camion','camionera'])
>>> print stemmer.stemWords(['frutal','frutas','frutivoro','abcde'])
['camioner', 'camion', 'camion', 'camioner']
['frutal', 'frut', 'frutivor', 'abcde']

Ejemplo busqueda por palabra clave

import Stemmer

pelis = {u"La reina de Montana": u"Sierra Nevada Jones llega a Montana con su padre para tomar posesión de unas tierras que han pertenecido a sus familias durante generaciones",
         u"La carpa invisible": u"Historia de una circo familiar Los Magote Pablo el director y maestro de ceremonias su esposa la payasa y acróbata Margarita y sus hijos",
         u"Familia": u"Santiago después de levantarse baja a la cocina donde lo espera su familia para felicitarlo es su cumpleaños"}
keywrd = "familiar"

stemmer = Stemmer.Stemmer('spanish')
lemkw = stemmer.stemWord(keywrd)
print "keyword:", keywrd
print "keyword lem:", lemkw
print
for peli in pelis:
    lems = stemmer.stemWords(pelis[peli].split())
    print "title:",
    print "argument", pelis[peli]
    print "argument lem:", lems
    if lemkw in lems:
        print "keyword lem", lemkw, "encontrado en argument lem"
    print

Resultado:

keyword: familiar
keyword lem: famili

title: argument Historia de una circo familiar Los Magote Pablo el director y maestro de ceremonias su esposa la payasa y acróbata Margarita y sus hijos
argument lem: [u'Histori', u'de', u'una', u'circ', u'famili', u'Los', u'Magot', u'Pabl', u'el', u'director', u'y', u'maestr', u'de', u'ceremoni', u'su', u'espos', u'la', u'payas', u'y', u'acrobat', u'Margarit', u'y', u'sus', u'hij']
keyword lem famili encontrado en argument lem

title: argument Sierra Nevada Jones llega a Montana con su padre para tomar posesión de unas tierras que han pertenecido a sus familias durante generaciones
argument lem: [u'Sierr', u'Nev', u'Jon', u'lleg', u'a', u'Montan', u'con', u'su', u'padr', u'par', u'tom', u'posesion', u'de', u'unas', u'tierr', u'que', u'han', u'pertenec', u'a', u'sus', u'famili', u'durant', u'gener']
keyword lem famili encontrado en argument lem

title: argument Santiago después de levantarse baja a la cocina donde lo espera su familia para felicitarlo es su cumpleaños
argument lem: [u'Santiag', u'despues', u'de', u'levant', u'baj', u'a', u'la', u'cocin', u'dond', u'lo', u'esper', u'su', u'famili', u'par', u'felicit', u'es', u'su', u'cumplea\xf1']
keyword lem famili encontrado en argument lem

Como se puede apreciar en el ejemplo al buscar por la palabra clave familiar encuentra coincidencias en el argumento de las tres peículas: familiar, familias y familia.

Este es un ejemplo muy simple. Se podria mejorar eliminando previamente las palabras vacias (stop words), ordenar el resultado según número de coincidencias mediante un algoritmo Tf-idf, o un sistema de retroalimentación aportada por el usuario para indicar la relevancia de los resultados como Rocchio y así mejorar las busquedas.

overstemming y understemming

El stemning presenta dos problemas básicos. El overstemming cuando se reduce demasiado se representa con un mismo stem formas que deberían ser representadas con varios stems y el understemming cuando se reduce poco y se obtienen distintas formas para representar unicamente a una.

Un ejemplo

import Stemmer

stemmer = Stemmer.Stemmer('spanish')
lems = stemmer.stemWords(["familiar", "familias", "familia", "familiares",
                          "familiaridad", "familiaridades"])
print lems
lems = stemmer.stemWords(lems)
print lems

Resultado

['famili', 'famili', 'famili', 'familiar', 'familiar', 'familiar']
['famili', 'famili', 'famili', 'famili', 'famili', 'famili']

Del ejemplo vemos que si aplico dos veces stemming, coinciden las seis formas. Si se aplica sólo una vez se produce un efecto de understemming.




Tecnologia

Cómo buscar videos en Youtube con Python


Si quieres buscar videos de Youtube de manera totalmente automática, Google ofrece su API de Youtube. Una alternativa a esta API es hacer uso de técnicas de Web Scraping para simular que nuestra aplicación es un humano navegando por la Web y recopilar información de forma automática.

buscar videos en Youtube con Python

Vamos a ver como se hace mediante la escritura de un sencillo código Python y el apoyo de la libreria pyquery que permite realizar consultas de manera similar a como lo hace jQuery en documentos XML y HTML.

Si despues te interesa descargar videos de youtube entonces te interesa esta entrada donde explico cómo hacerlo. En cambio, si lo que te interesa es descargar el thumbnail entonces te puede interesar esta otra entrada donde explico cómo bajar una imagen de la web con python.

Código:

# -*- coding: cp1252 -*-
from pyquery import PyQuery as Pq
from urllib import urlencode

def search_youtube_video(title, pages):
    for page in range(pages):
        params = urlencode({'search_query':'intitle:"%s", video, long' % title, 'page':page})
        jq = Pq(url="http://www.youtube.com/results?%s" % params,
                headers={"user-agent": "Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20140129 Firefox/24.0"})
        jq.make_links_absolute("http://www.youtube.com")
        for video in jq("ol.item-section").children().items():
            url = video.find("a.yt-uix-tile-link").attr("href")
            title = video.find("a.yt-uix-tile-link").text()
            time = video.find("span.video-time").text()   
            if time:
                tsecs = 0
                items = time.split(':')
                items.reverse()
                for i in range(len(items)):
                    tsecs += int(items[i])*(60**i)          
            description = video.find("div.yt-lockup-description").text()
            thumb = video.find("div.yt-thumb img").attr("data-thumb")
            if not thumb:
                thumb = video.find("div.yt-thumb img").attr("src")
            if thumb:
                thumb = thumb.lstrip("//")     
            published = video.find("ul.yt-lockup-meta-info li").eq(0).html()
            views = video.find("ul.yt-lockup-meta-info li").eq(1).html()

            print
            print "url:", url
            print "title:", title
            print "time:", time
            print "time in seconds:", tsecs
            print "description:", description
            print "thumbnail:", thumb
            print "published:", published
            print "views:", views

if __name__ == '__main__':
    search_youtube_video("la guerra del opio", 1)

La función search_youtube_video acepta dos parámetros. title es el texto a buscar y pages el número de páginas de resultados a procesar. El código hace uso de selectores jqyery para encontrar la información en la página de resultados.

El código siempre buscar videos de mas de 20 minutos, para eliminar esta restricción deberás eliminar el keyword «long» del parámetro search_query quedando así:

params = urlencode({'search_query':'intitle:"%s", video' % title, 'page':page})

Resultado ejemplo:

url: http://www.youtube.com/watch?v=436qM17mKok
title: la guerra del opio 1997 dvdripspanishwww zonatorrent com
time: 1:46:38
time in seconds: 6398
description: 
thumbnail: i.ytimg.com/vi/436qM17mKok/mqdefault.jpg
published: Hace 2 años
views: 23.792 visualizaciones

url: http://www.youtube.com/watch?v=0L7l7j9r1hs
title: Escenas para uso didáctico: La Guerra del Opio
time: 47:51
time in seconds: 2871
description: Escenas para explicar el imperialismo colonial. Más información:...
thumbnail: i.ytimg.com/vi/0L7l7j9r1hs/mqdefault.jpg
published: Hace 2 años
views: 5.833 visualizaciones

url: http://www.youtube.com/watch?v=bhnXgV-ZRS0
title: La Guerra del Opio
time: 32:18
time in seconds: 1938
description: mi proyecto Brenda Elena Segura Maza "A"
thumbnail: i.ytimg.com/vi/bhnXgV-ZRS0/mqdefault.jpg
published: Hace 1 año
views: 230 visualizaciones



Tecnologia

Colección de temas para el IDLE de Python


La verdad es que IDLE de Python es fantastico, pero el esquema de color que trae por defecto es un poco soso. Para facilitaros un poco la vida os dejo en descarga el fichero de configuración con una colección de temas para el IDLE recopilados por Google. Los temas que contiene son los siguientes:

  • Tango
  • Desert
  • Obsidiana
  • Solarized Dark
  • Solarized Light
  • Black
  • CodeIt
  • Codecademy UI
  • UbuntuLike

Sigue estos pasos para añadir los temas para el IDLE de Python:

  1. Cierra el IDLE de Python
  2. Descarga y descomprime config-highlight.cfg
  3. Buscar la carpeta /.idlerc y pega allí el fichero. Normalmente en Linux esta carpeta se encuentra en el directorio Home, mientras que en Windows es posible que se encuentre en la carpeta de configuración de usuario. Prueba a escribir la orden cd /D %userprofile%\.idlerc
  4. Abre de nuevo el IDLE de Python
  5. Vete a la pestaña highlight de la opción de menu Options > Configure IDLE y selecciona uno de los temas

temas para el IDLE de Python

6. Si seleccionastes el tema Obsidiana ahora tu IDLE debería parecerse a esto:

temas para el IDLE de Python