10 snippets super útiles de Python

Muchos desarrolladores contamos con lo que se suele denominar como, memoria atrofiada, somos capaces de recordar procedimientos y algoritmos para realizar ciertas tareas, pero a la hora de recordar sintaxis o nombre específicos de funciones, nos quedamos totalmente en blanco. Es por eso que un programador debe trabajar siempre con una conexión a Internet, para en los momentos de ayuda, poder consultar la comunidad del lenguaje en el que estemos desarrollando.

Personalmente cuento con una hoja de texto en la que guardo aquellos snippets de código que más suelo utilizar y cuya sintaxis no suelo recordar nunca. Este documento, que a la mayoría de la gente le puede parecer una tontería, ni os imagináis las veces que me ha sacado de un apuro y sobretodo, lo que me ha ayudado a optimizar tiempos.

Siempre es bueno contar con una chuleta para mejorar la productividad. Es por eso que he decidido compartir mi chuleta con todos vosotros, para que vosotros también os podáis aprovechar de ella. Esta vez nos acercamos a uno de los lenguajes de programación más populares, Python.

En este artículo os muestro 10 snippets de Python que harán las delicias de todo programador.

Calcular el tamaño de una imagen mediante una URL

Este snippet es muy útil para saber cuánto pesa una imagen proporcionada mediante una URL.

import requests
from PIL import Image
from io import BytesIO


def get_image_size(url):
    data = requests.get(url).content
    im = Image.open(BytesIO(data))    
    return im.size


if __name__ == "__main__":
    url = "http://4.bp.blogspot.com/_A2NamGQmyCc/TO1nWedGQQI/AAAAAAAAAnA/WxBVyEGHxjc/s1600/sbn_pic_2.jpg"
    width, height = get_image_size(url)
    print width, height

Eliminar espacios delante y atrás en una cadena

¿Cuenta Python con una función como la función trim de PHP para eliminar los espacios delante de una cadena y detrás? La respuesta es sí, y se llama strip. Aquí tienes el código:

>>> str = ' aa b cde  '
>>> str
' aa b cde  '
>>> str.strip()
'aa b cde'
>>> str = str.strip()
>>> str
'aa b cde'
>>> 

Calcular la edad mediante la fecha de nacimiento

Esta función calcula la edad a partir de la fecha de nacimiento. Es una función muy simple, y que ha sido implementada basándose en respuestas en Stackoverflow.

def calculate_age(born):
    today = date.today()
    try: 
        birthday = born.replace(year=today.year)
    except ValueError: # raised when birth date is February 29 and the current year is not a leap year
        birthday = born.replace(year=today.year, day=born.day-1)
    if birthday > today:
        return today.year - born.year - 1
    else:
        return today.year - born.year


if __name__ == "__main__":
    day, month, year = [int(x) for x in "7/11/1982".split("/")]
    born = date(year, month, day)
    print calculate_age(born)

Buscar tweets en Twitter

Este snippet busca palabras clave en Twitter y extrae los tweets relacionados. Para ello utilizo el API de Twitter Search. Supongo que muchos de vosotros encontraréis este snippet muy útil.

import requests  
 import sys  
 import time  
 from datetime import datetime  
   
   
   
 def store_tweets(keyword, results, max_id):  
   tweet_list = []  
     
   for item in results:  
     tweet_id = item['id_str']  
     tweet_text = item['text'].encode('utf-8', 'ignore')  
     if len(tweet_text) > 255:  
       tweet_text = tweet_text[0:255]  
     from_user = item['from_user'].encode('utf-8', 'ignore')  
     from_user_id = item['from_user_id']  
     from_user_name = item['from_user_name'].encode('utf-8', 'ignore')  
     profile_image = item['profile_image_url'].encode('utf-8', 'ignore')  
     created_at = datetime.strptime(item['created_at'][:-6], "%a, %d %b %Y %H:%M:%S")  
       
     tweet_list.append((keyword, tweet_id, tweet_text, from_user, from_user_id, from_user_name, profile_image, created_at))  
       
   # Now store the tweet list in a database or file  
   return  
   
   
   
 def search_tweets(keyword, max_id = '', result_type = 'mixed'):  
   url = 'http://search.twitter.com/search.json'  
     
   params = {'q': keyword, 'rpp': '100'}  
     
   if len(max_id) > 0:  
     params['since_id'] = max_id  
       
   params['result_type'] = result_type  
   r = requests.get(url, params=params)  
   time.sleep(5)  
     
   if r.status_code != 200:  
     print r.status_code  
     print r.text  
     time.sleep(30)  
     return r.status_code  
   
   json_content = r.json  
     
   max_id = json_content['max_id_str']  
     
   while True:  
     results = json_content['results']  
     if len(results) == 0:  
       print "no result"  
       break  
         
     store_tweets(keyword, results, max_id)  
       
     if 'next_page' in json_content.keys():  
       next_page = json_content['next_page']  
     else:  
       break  
       
     r = requests.get(url + next_page)  
     time.sleep(5)  
     print r.status_code  
     if r.status_code != 200:  
       print r.status_code  
       print r.text  
       time.sleep(30)  
       return r.status_code  
   
     json_content = r.json  
       
     
     
 if __name__ == "__main__" :  
   keyword = 'python'  
   search_tweets(keyword)  
     

Concatenar dos diccionarios

Si quieres concatenar dos diccionarios en Python (añadir un diccionario a otro diccionario), hay una manera sencilla de hacerlo. Utiliza el método update() que es muy similar a la función extend(), la cual se suele utilizar para concatenar las listas.

>>> dict_1 = {1: 'a', 2: 'b', 3: 'c'}
>>> dict_2 = {4: 'd', 5: 'e', 6: 'f'}
>>> dict_1
{1: 'a', 2: 'b', 3: 'c'}
>>> dict_2
{4: 'd', 5: 'e', 6: 'f'}
>>> dict_1.update(dict_2)
>>> dict_2
{4: 'd', 5: 'e', 6: 'f'}
>>> dict_1
{1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f'}
>>>

Buscar comentarios en YouTube

Este snippet busca comentarios en un video de youtube y los almacena en una base de datos (postgresql en este snippet). Para ello he utilizado la API de YouTube. En lugar de describir el código en detalle, creo que se explica suficientemente solo. Si tienes alguna pregunta o sugerencia para mejorar el código, no dudes en comentárnoslo.

import gdata.youtube  
 import gdata.youtube.service  
 import psycopg2  
 import sys  
 from datetime import datetime  
 import time  
 import re  
   
   
   
   
 try:  
   # you should read these from a config file  
   conn = psycopg2.connect(host='localhost', database='databae_name', user='user', password='pass')  
   conn.autocommit = True  
   cursor = conn.cursor()  
 except psycopg2.DatabaseError, e:  
   print 'Error %s' % e    
   sys.exit(1)  
   
   
    
 def since_epoch(date_string):  
   return int(time.mktime(datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%S.%fZ").timetuple()) * 1000)  
    
   
   
 def comments_generator(client, video_id):  
   comment_feed = client.GetYouTubeVideoCommentFeed(video_id=video_id)  
   while comment_feed is not None:  
     for comment in comment_feed.entry:  
       yield comment  
     next_link = comment_feed.GetNextLink()  
     if next_link is None:  
       comment_feed = None  
     else:  
       comment_feed = client.GetYouTubeVideoCommentFeed(next_link.href)  
   
   
   
 def search_and_store_comments(client, keyword, video_id):  
   query = "SELECT MAX(updated) FROM yt_comments WHERE keyword = %s AND video_id = %s"  
   cursor.execute(query, (keyword, video_id))  
   result = cursor.fetchone()  
   if len(result) > 0:  
     last_update = result[0]  
   if last_update is None:  
     last_update = '0'  
   if last_update == '':  
     last_update = '0'  
   for comment in comments_generator(client, video_id):  
     author_name = comment.author[0].name.text.strip()  
     text = comment.content.text.strip()  
     update_time = comment.updated.text.strip()  
     update_time = since_epoch(update_time)  
     if update_time <= int(last_update):  
       break  
     print (keyword, video_id, author_name, text, update_time)  
     try:  
       cursor.execute("INSERT INTO yt_comments (keyword, video_id, author, text, updated) VALUES (%s, %s, %s, %s, %s)", (keyword, video_id, author_name, text, update_time))  
     except psycopg2.DatabaseError, e:  
       print 'Error %s' % e  
     
   
   
   
 def search_yt(keyword):  
   client = gdata.youtube.service.YouTubeService()  
     
   vid_pat = re.compile(r'videos/(.*?)/comments')  
   vid_list = []  
   
   for start_index in range(1, 1000, 50):  
     query = gdata.youtube.service.YouTubeVideoQuery()  
     query.vq = keyword  
     query.max_results = 50  
     query.start_index = start_index  
     query.orderby = 'relevance'  
     print start_index  
     feed = client.YouTubeQuery(query)  
       
     if len(feed.entry) == 0:  
       break  
   
     for entry in feed.entry:  
       if entry.comments is None:  
         continue  
       comment_url = entry.comments.feed_link[0].href            
       result = re.findall(vid_pat, comment_url)  
       if len(result) > 0:  
         video_id = result[0]  
       else:  
         continue  
       if video_id not in vid_list:  
         vid_list.append(video_id)   
       print video_id  
         
     time.sleep(1)  
         
   vid_list = list(set(vid_list))  
   for vid in vid_list:  
     search_and_store_comments(client, keyword, vid)  
   
   
     
 def main():  
   query = "SELECT keyword FROM yt_keywords"  
   cursor.execute(query)  
   result = cursor.fetchall()  
   for item in result:  
     keyword = item[0]  
     print "Searching for keyword:", keyword  
     search_yt(keyword)  
     time.sleep(1)  
       
     
     
 if __name__ == "__main__" :  
   main()  
   print "done" 

Obtener el próximo elemento de una lista

A veces tendrás que mantener algunos elementos de una lista y obtener el siguiente elemento. Se puede llevar a cabo de forma sencillo usando una variable como rastreador de la posición actual. Echa un vistazo al código de abajo:

current_position = 0    
 my_li = [1, 2, 3, 4, 5]    
 for i in range(0, 8):    
     value = my_li[current_position % (len(my_li))]    
     current_position += 1        
     print value    
 for i in range(0, 5):    
     value = my_li[current_position % (len(my_li))]    
     current_position += 1        
     print value    

De HTML a texto

Este snippet elimina todos los tags de HTML, todos los códigos javascript, CSS, comentarios de HTML... Es algo así como el strip_tags() de PHP, para que me entendáis.

def html_to_text(data):        
    # remove the newlines
    data = data.replace("n", " ")
    data = data.replace("r", " ")
   
    # replace consecutive spaces into a single one
    data = " ".join(data.split())   
   
    # get only the body content
    bodyPat = re.compile(r'< body[^<>]*?>(.*?)< / body >', re.I)
    result = re.findall(bodyPat, data)
    data = result[0]
   
    # now remove the java script
    p = re.compile(r'< script[^<>]*?>.*?< / script >')
    data = p.sub('', data)
   
    # remove the css styles
    p = re.compile(r'< style[^<>]*?>.*?< / style >')
    data = p.sub('', data)
   
    # remove html comments
    p = re.compile(r'')
    data = p.sub('', data)
   
    # remove all the tags
    p = re.compile(r'<[^<]*?>')
    data = p.sub('', data)
   
    return data

Generar fechas dentro de un rango dado

import datetime

def generate_dates(start_date, end_date):
    td = datetime.timedelta(hours=24)
    current_date = start_date
    while current_date <= end_date:
        print current_date
        current_date += td

start_date = datetime.date(2010, 1, 25)
end_date = datetime.date(2010, 3, 5)
generate_dates(start_date, end_date)

Eliminar elementos duplicados de una lista

Un problema común en los novatos de Python es eliminar los elementos duplicados de una lista. En Python se puede llevar a cabo fácilmente.

myList = list(set(myList))
>>> myList = [1, 2, 3, 3, 2, 2, 4, 5, 5]
>>> myList
[1, 2, 3, 3, 2, 2, 4, 5, 5]
>>> myList = list(set(myList))
>>> myList
[1, 2, 3, 4, 5]
>>>

Fuente: love-python.blogspot.com.es

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP