Gana Dinero con las Nuevas Criptomonedas solo con Registrarte

Muchas empresas que se están lanzando al mundo de las Cryptomonedas se han dado cuenta que la mejor publicidad la hace el usuario final, contándole a sus amigos lo mucho que han ganado en este mundo.
Hoy puedes ganar mucho dinero refiriendo a tus amigos y conocidos a las nuevas cryptomonedas entre mas amigos refieras mas dinero ganaras.
Para la mayoría de las monedas que te dejare aquí necesitas un WALET que pueda contener TOKENs puedes crearte 1 en https://www.myetherwallet.com.
Estas campañas pueden estar por terminar pero cada 1 o 3 días colocare campañas activas donde puedas ganar dinero solo con registrarte y verificar el EMAIL, ojo quizás hayan mas formas de ganar mas TOKENs por ejemplo haciendo publicidad y siguiéndoles en las redes sociales.
Registrate en Steemit y sígueme steemit.com/@sethroot  enterate en lo que estoy ganando dinero ahora.
Fuente de la imagen Pixabay
Aquí una lista de Campañas Activas y mas o menos de que va la ICO y cuanto están pagando al día de Hoy:

1 — Gran OPORTUNIDAD ICO WCX

ICO WCX PRELANZAMIENTO RECIBE 50 tokens equivalente a 5 dolares y 10 por cada Referido.
Resumen: WCX es un exchange de criptomonedas con bajo costo. SOLO POR REGISTRARTE Y COMO ESTA EN PRELANZAMIENTO RECIBE 50 tokens equivalente a 5 dolares ADEMAS Por seguir a WCX en twuiter y rellenar una encuesta recibe otros 100 tokens equivalente a 10 USD. CONSIGUES 10 Dolares mas por referidos.
Anima a tus amigos y familiares a registrarse y gana dinero!!!

2 — Gran OPORTUNIDAD ICO CryptoKami

OBTENGA 50 TOKEN GRATIS REGISTRATE EN EL PROGRAMA DE BONIFICACIÓN
Resumen: CryptoKami es un sistema de reserva descentralizada.  La plataforma CryptoKami es como la plataforma Ethereum, pero solo está pensada para ser utilizada por terceros en el sector financiero.*
  • REGISTRaTE Y GANA 50 token KAMI 10 por cada referido
Aquí puedes seguirle en las diferentes redes sociales
Anima a tus amigos y familiares a registrarse y gana dinero!!!
3 — Gran OPORTUNIDAD ICO Affiliatecoin

Link de Referido: AFILIATECOIN

Resumen: La Red de Afiliados Descentralizada AffiliateCoin está regalando monedas AFL gratuitas a cada registro.
  • Si te registras recibirás 25 monedas AFL gratuitas.
  • Obtendrás 50 monedas AFL por referido
Anima a tus amigos y familiares a registrarse y gana dinero!!!

4 Gran OPORTUNIDAD CRNC

Link de Referido: CRNC

  • Gana hasta 100 Dolares en tokens CRNC gratis invitando amigos
  • Obtendrás 5 CRNC por cada amigo que invites a la red. Hasta 400 CRNC,

5 Gran oportunidad por 3 dias mas sphere.social

Es una red social que pagara por contenido ademas mejorara la seguridad eso dicen!
  • Dan 50 SAT por registrarte y 50 por referido

NEXO es un sistema de Prestamos, Link de Referidos

Tenemos Mas en la noche o mañana se las ire pasando voy revisando que estén activas y se las paso, Recuerden pagan cuando sale el ICO, deben crear una WALLET en https://www.myetherwallet.com.
Saludos Dios les Bendiga, Dios bendiga a Venezuela
Anima a tus amigos y familiares a registrarse y gana dinero!!!

 

 

 

A minar Bitcoins Gratis que aun es posible!!!

Mina en la Nube Bitcoins o Satoshis  gratis aun  es posible y Fácil, Sin necesidad de Abrir molestas paginas ni hacer tarea alguna, entras te registras y ya estas minando con 50GHs gratis que te dan así sin mas complicaciones.

Ademas este sitio ofrece no cambiar la dificultad de minado por lo que siempre vas a minar la misma cantidad o aproximadamente. Tengo mas de Año y medio y es totalmente Confiable por eso lo recomiendo.

En 1 año aproximadamente tienes para sacar 1.000.000 de Satoshis sin invertir.

Solo debes invertir  en 20GHs de Poder para sacar mas de 80$

Lo mejor  es uno de los pocos sitios que permite invertir para 3 meses o 6 meses yo compre 2 paquetes de 3 meses y 1 de 6 meses llegando a tener ahora mismo 3913 GHz.

No quiero repetir el Post Anterior, ahora quiero que veas que he sacado dinero de este sitio y cada ves lo recomiendo mas!!!!

Una imagen vale mas que mil palabras!!! Bueno eso quería compartir, que esta Pagando y esta para quedarse a invertir que esperas???

Recuerda Registrarte con mi numero de referido para mantenerlos informados de sitios como estos!!!

https://www.cryptomining.farm/signup/?referrer=56970C219BFAE

 

Gracias que Dios les Bendiga!

 

Derrotado a La Inflacion en Venezuela

Primero que nada siempre han habido tiempos malos en nuestra sociedad, quizá nunca hayamos tenido ningún tiempo como el presente pero eso es otra historia, en la biblia dice que aprovechemos el tiempo por que los días son malos… En conclusión Dios siempre esta al control de todo, y es por esto que debemos encomendar nuestros planes según su Buena Voluntad…

Bueno quizá estas pensando  que hacer con ese dinero que tienes de las utilidades o algún dinero extra que tengas y pensándolo bien con el Dolar subiendo mas y mas cada día si lo metes en el Banco es posible que lo absorba la inflación y por ejemplo 200BsF hoy mañana sean solo 190 y así cada día no estoy exagerando en 2 idas el dolar a pasado de 2100 a 2479 BsF según Dolar Today es terrible la situación que vivimos en Venezuela..

No me gusta suponer ni mucho menos decirte que hacer con tu dinero pero a mi me gusta arriesgar(confiando en que Dios ponga en mi corazón discernimiento, en realidad de arriesgar quizá tenga muy poco jejeje) y es por eso que voy a hablar de finanza en este Blog debido a la Gran Crisis de Venezuela, Recuerda que Dios tiene un plan para todos… y bueno imagina comprar 100 dolares hace 3 meses cuando el dolar valía cerca de 1200BsF habrías Gastado 120.000BsF y ahora mismo tendrías cerca de 240.000BsF en realidad no habrías ganado mucho ya que los precios de los productos van en aumento a medida que el dolar se va estabilizando… Dios lo puede todo, te invito a leer 2 Reyes 7 del 1 al 3, claro que nosotros debemos buscar la manera de no malgastar nuestro dinero y meterlo al banco es malgastarlo ahora mismo

Y bueno comprar dolares solo sirve para mantener tus activos pero que tal si te digo que podríamos agregar una variable mas aunque es ligeramente arriesgado, El Bitcoin, si el Bitcoin es una moneda Digital mas cara que el ORO por algo sera, mucha gente teme usar la moneda pero es una moneda mas peor son los billetes de Venezuela que tienen ídolos de la Santería y aun así debemos usarlos pero no adorarlos ojo…

Y bueno si hacemos la misma cuenta, pero ahora incluimos comprar Bitcoins con los dolares que teníamos hace 3 meses, hace 3 meses 1 Bitcoin costaba entre 500 y 600 dolares, es decir que por encima podriamos comprar 1/6 de Bitcoins o lo que es lo mismo 16.666.667 Satoshis y ahora mismo el Bitcoin cuesta 750 Dolares, es decir habríamos ganado con 1 Bitcoin 1/4 de lo invertido es decir 25 Dolares ahora si  te tome la atención 😀

Tu dirás el Hubiera es pasado ahora es que quiero invertir :S, hace poco empresas como BBVA, Movistar, Grupo Santander, hasta Google y Facebook segun rumores estan invirtiendo en esta tecnología y la buena noticia es que mientras vaya aumentando el comercio Digital el valor del Bitcoin sera mas alto, Claro si no Viene Nuestro Señor Jesucristo Antes, pero imagina que te pregunte que hiciste con el Dinero que te Dio? no lo donaste, no ofrendaste, ni nada, dejaste que se lo comiera la inflación…

Bueno yo espero que a finales del año que viene el Bitcoin se coloque en 1500 Dolares, y el Dolar Baje por lo menos en Venezuela a 1500BsF… y entonces Diras por que invertir en Dolares o Bitcoin entonces, simple no pienso en comprar y vender como hace la mayoría de la gente eso mas bien destruye el Pais, ya que las Divisas salen del País y no hay retorno… Lo que quiero hacer es invertir por ejemplo  en Minería en la nube para comenzar con planes de 1 año y asi como esta el retorno seria en 5 a 7 meses y lo demas es ganancia es decir ganarías si inviertes 100 Dolares como mínimo 70 dolares mas lo que pueda subir el Bitcoin… en la proxima entrada espero tener mi Cloud ya funcionando para mostrarle como invertir en las mejores y ams fiables Cloud como mover su dinero de Bitcoins a Dolares o Bolivares y un par de calculadoras de suposiciones que pienso hacer para ver la trazabilidad de LA INVERSION, dicen que lleva riesgos epro en el peor de los casos en 4 meses tendras casi toda tu inversion…

Hace 1 año exactamente le dije a un tío que dice el tiene mucho Dinero, pero para mi es realmente Pobre por que no sabe de números y lo mas importante no tiene a Dios en su Corazón, le dije que invirtiera 360$ en 1 Bitcoin con lo que podía comprar un AntMiner S5 y de 5 a 7 meses tendría el retorno y luego ganaría Dividendos hasta que el Antminer muera es decir de 3 a 5 años como mínimo, y estaba un poco dispuesto y todo el mundo no hubo uno solo le dijo que si estaba loco, bueno con el dolar a 700BsF mas o menos y el Bitcoin a 360$ imagínate cuanto no tendría ahora mismo de Retorno… Bueno cosas asi me han pasado por no tener Dinero jeje, pero ahora mismo Dios esta Bendiciendo mi vida y quiero invertir no para mi si no para ayudar a tanta gente que no tiene la visión que Dios me ha dado, no económicamente si no mas bien usar el dinero para cursos seminarios Teológicos y de Tecnología, para las misiones y otras cosas… Bueno es lo que quiero esperemos que Dios me lo permita según su Buena y perfecta Voluntad…

Saludos Dios les Bendiga

 

 

Python Scraping NFL [Parte 1]

Al final decidí hacer la parte 1 de esta interesante serie, estamos bastante desfasados :S, pero esta semana creo que podre terminar esta serie hasta la parte del scraping… ya la parte del análisis espero tenerla este año, y sera para la próxima temporada que podremos usarla a tope… Hoy vamos a ver el codigo de como extraer los datos para cada juego, solo vamos a extraer los score de cada equipo por separado, ya luego podemos hacer un for para que nos los agrupe de 2 en 2 y asi saber a quien se enfrento cada equipo….

Aqui el codigo, aunque pienso cambiarlo un poco en como aplicar el get.TEXT, luego algun comentario del codigo:

import requests, urllib2
from bs4 import BeautifulSoup
import re

import math

lista_regular_season = [range(1, 6)]

### Pagina primaria para buscar los datos

url_1er = 'http://www.nfl.com/scores/2016/REG'
for semana in lista_regular_season[0]:
  
    print "      " 
    print "      " 

    print "      " 
    print "Que semana esta: ", semana 
    print "      " 
    print "      " 
    print "      " 

    url_1er = 'http://www.nfl.com/scores/2016/REG'+str(semana)
    
    print url_1er

    url_1er = 'http://www.nfl.com/scores/2016/REG'

            
    page_1era = urllib2.urlopen(url_1er)
            
    soup_1er = BeautifulSoup(page_1era, 'lxml')

    divicion_Diviciones = soup_1er.find_all('div',class_="new-score-box-wrapper" )
    
    quarters_total = soup_1er.find_all('p',class_="total-score" )
    if "--" in quarters_total:
      print "Este juego No se ha jugado"
      pass
    else:
      
      
        results_total = []
        results_first = []
        results_second = []
        results_third = []
        results_fourth = []
        nombres_equipos = []

        ### Total
        quarters_total = soup_1er.find_all('p',class_="total-score" )
        results_total.append([headers.get_text() for headers in quarters_total])
        results_total = results_total[0]


        ### nombre Equipo
        nombre_equipo= soup_1er.find_all('p',class_="team-name" )
        nombres_equipos.append([headers.get_text() for headers in nombre_equipo])
        nombres_equipos = nombres_equipos[0][2:]
        
        ### Primer cuarto
        first_qt = soup_1er.find_all('span',class_="first-qt" )
        results_first.append([data.get_text() for data in first_qt])
        results_first = results_first[0][2:]

        ### segundo cuarto

        second_qt = soup_1er.find_all('span',class_="second-qt" )
        results_second.append([data.get_text() for data in second_qt])
        results_second = results_second[0][2:]

        ### tercer cuarto

        third_qt = soup_1er.find_all('span',class_="third-qt" )
        results_third.append([data.get_text() for data in third_qt])
        results_third = results_third[0][2:]

        ### cuarto cuarto

        fourth_qt = soup_1er.find_all('span',class_="fourth-qt" )
        results_fourth.append([data.get_text() for data in fourth_qt])
        
        ## Debo cambiar la linea anterior para obtener 1 sola lista 😀
        results_fourth = results_fourth[0][2:]





        i = 0
        for datos in nombres_equipos:
                print "Nombre Equipo", datos
                primer_cuarto =  results_first[i]
                primer_cuarto =  int(primer_cuarto)
        

                segundo_cuarto = results_second[i]
                segundo_cuarto =  int(segundo_cuarto)

        
                tercer_cuarto =  results_third[i]
                tercer_cuarto =  int(tercer_cuarto)

        
                cuarto_cuarto =  results_fourth[i]
                cuarto_cuarto =  int(cuarto_cuarto)
                print "1er Cuarto:  ", primer_cuarto,"2do Cuarto:  " ,segundo_cuarto,"3er Cuarto:  ", tercer_cuarto,"4to Cuarto:  ", cuarto_cuarto
        

                total_total = primer_cuarto + segundo_cuarto +tercer_cuarto + cuarto_cuarto
                total = results_total[i]
                
                print "Total", total_total
        
        
        

                i += 1

No hay mucho que comentar solo que la pagina usada para extraer los datos es http://www.nfl.com/scores/2016/REG y se le agrega un numero que corresponde a la semana o jornada de la temporada…

También la linea data.get_text() debo modificarla para hacer el código mas viable 😀

Las otras partes son faciles de entender si has seguido mis entradas 😀

Hasta luego Feliz Dia y que Dios te Bendiga

Pensando en la Proxima entrada y cosas que nos quedan por hacer en Python

Les cuento que esta semana he estado trabajando Full Time programando en Openerp v7, aunque me gustaría subir por lo menos el vídeo de lo que hice debo preguntar si puedo :S… mas o menos los tiros van así, he estado rehaciendo una API de una Aerolinea para extraer los datos de unos archivos llamados PNR, vaya que ni me imaginaba ese mundillo :S, al final todo salio bien gracias a Dios con muchos momentos de frustración al estar en terreno desconocido, pero al final corrió el código y aunque le faltan bastantes detalles(esto es bueno por que tengo trabajo :D) ya esta consumiendo los archivos en cuestión 😀

Debo comunicarles que me he decidido implementar la Base de Datos directamente a ODOO, les hablo del scrapping de la NFL que estaba haciendo, les cuento que tengo mas de 1 semana con una Otitis terrible y ya Gracias a Dios se me esta pasando, Voy a implementarla directamente en ODOO por que asi tendremos un mapeo de la base de datos y vistas interesantes en ODOO ojo que pronto subo un Vídeo 😀

Voy a ir subiendo Vídeos de entradas anteriores para los que no les gusta leer(aunque háganlo un habito :D), voy a comenzar con un Cursito de Python para Dummies en vídeo, así como también un vídeo de buenas practicas debugueando código en python si Dios nos lo permite claro 😀

Hay varias series que hay que retomar si o si, pero ahora trabajo 8 horas al día, y otras 3 copadas, mas 2 en otros proyectos me quedan como 3 libres :S bueno algo haré :D, por ejemplo Criptografia, APIS le tengo el ojo a Google :D, entre otras……. hay bastante que elegir en este blog :S

Bueno hasta aquí esta micro entrada informativa, me despido que Dios les bendiga les ilumine sus pasos y les de discernimiento…

Manejando SQL (Sqlite3) en Python [Parte 1]

Les cuento he estado haciendo algunas pruebas para optar en un trabajo en BairesDev y de verdad me he dado cuenta que me faltan conocimientos en: Javascript, Jquery(claro), SQL y algunos otros pero no tanto como en estas 3, podría trabajar en un proyecto pero mas pronto que tarde tendría que estar buscando la manera de hacer algo que nunca he hecho en estos 3 lenguajes(por darles un nombre) y tendría que recurrir a libros o ayuda online lo que retrasaría un poco mi desempeño, es por esto que voy a comenzar esta serie, ya que estoy leyendo este tutorial de SQL http://sql-principiantes.blogspot.com/ claro que entiendo el código pero aveces se me olvida y el manual esta dirigido a Windows, y también algunos de Python y sqlite3 :S por lo que decidí crear la entrada para tener la información y practicar….

El primer código consiste en crear una Base de Datos e insertar unos datos aquí el código, que con los conocimientos obtenidos en La especialización de python Genere(Claro vamos a ir haciéndole mejoras :D):


import sqlite3

conn = sqlite3.connect('empresa.sqlite3')

cur = conn.cursor()

cur.execute('DROP TABLE IF EXISTS personas ')
cur.execute('''CREATE TABLE Personas ( id INTEGER PRIMARY KEY AUTOINCREMENT, Nombre char(20) NOT NULL, Apellidos char(30) NOT NULL, Direccion char(40) NOT NULL, Ciudad char(10) NOT NULL) ''')

cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)',('Marco Antonio','Trejo Lemus','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)',('Martha Beatriz','Trejo Lemus','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)', ('Juana Elvira','Trejo Lemus','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)', ('Nora Zulma','Trejo Lemus','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)',('Laura Lucero','Sobrevilla Trejo','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)',('Maria de la luz','Trejo Campos','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)', ('Trinidad','Trejo Bautista','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)',('Marcel Abisag','Sobrevilla Trejo','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)', ('Jose Abraham','Sobrevilla Trejo','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)', ('Samuel Salomon','Olmeda Trejo','Calle E 822','Tampico'))
cur.execute('select * from Personas')

for row in cur:
print row

conn.close()

Recuerda esto es python y esta es la salida:

(1, u'Marco Antonio', u'Trejo Lemus', u'Calle E 822', u'Tampico')
(2, u'Martha Beatriz', u'Trejo Lemus', u'Calle E 822', u'Tampico')
(3, u'Juana Elvira', u'Trejo Lemus', u'Calle E 822', u'Tampico')
(4, u'Nora Zulma', u'Trejo Lemus', u'Calle E 822', u'Tampico')
(5, u'Laura Lucero', u'Sobrevilla Trejo', u'Calle E 822', u'Tampico')
(6, u'Maria de la luz', u'Trejo Campos', u'Calle E 822', u'Tampico')
(7, u'Trinidad', u'Trejo Bautista', u'Calle E 822', u'Tampico')
(8, u'Marcel Abisag', u'Sobrevilla Trejo', u'Calle E 822', u'Tampico')
(9, u'Jose Abraham', u'Sobrevilla Trejo', u'Calle E 822', u'Tampico')
(10, u'Samuel Salomon', u'Olmeda Trejo', u'Calle E 822', u'Tampico')

Ya logramos una parte del ejercicio pero en python siempre hay una manera mas fácil de hacer las cosas :D, si por ejemplo tenemos los datos en una lista y los vamos agregando así:


import sqlite3

conn = sqlite3.connect('empresa.sqlite3')

cur = conn.cursor()

cur.execute('DROP TABLE IF EXISTS personas  ')


cur.execute('''CREATE TABLE Personas ( id INTEGER PRIMARY KEY AUTOINCREMENT, Nombre char(20) NOT NULL, Apellidos char(30) NOT NULL, Direccion char(40) NOT NULL, Ciudad char(10) NOT NULL) ''')


datos = [
    ('Marco Antonio','Trejo Lemus','Calle E 822','Tampico'),
    ('Martha Beatriz','Trejo Lemus','Calle E 822','Tampico'),
    ('Juana Elvira','Trejo Lemus','Calle E 822','Tampico'),
    ('Nora Zulma','Trejo Lemus','Calle E 822','Tampico'),
    ('Laura Lucero','Sobrevilla Trejo','Calle E 822','Tampico'),
    ('Maria de la luz','Trejo Campos','Calle E 822','Tampico'),
    ('Trinidad','Trejo Bautista','Calle E 822','Tampico'),
    ('Marcel Abisag','Sobrevilla Trejo','Calle E 822','Tampico'),
    ('Jose Abraham','Sobrevilla Trejo','Calle E 822','Tampico'),    
    ('Samuel Salomon','Olmeda Trejo','Calle E 822','Tampico'),
]
for dato in datos:
    cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)', dato)
  


cur.execute('select * from Personas')

for row in cur:
    print row

conn.close()


La salida es la misma solo quería agregarlos datos con un ciclo for sin necesidad de agregar linea por linea, aunque ya algo hemos visto en la otra serie de Twitter, les recuerdo que voy a comenzar  a hablar  de Javascript en el blog y en un futuro cercano colocar algunas entradas en ingles 😀

Saludos Dios les Bendiga e Ilumine sus caminos

 

De Json a Histogramas con Matplotlib[Parte 1]

Al pensar en crear gráficas con los datos de la API de Twitter, estaba meditando en que serie de este Blog colocar esta tan interesante entrada y me dije por que no crear una serie nueva para que las personas que no estén interesadas en la API de Twitter puedan disfrutar del código que aquí voy a exponer:

 
### Autor Cesar Chirinos
### Fecha 22 Agosto 2016
### publicado en https://stickybitshell.wordpress.com/2016/08/22/de-json-a-histogramas-con-matplotlibparte-1-2/


### http://pybonacci.org/tag/tutorial-matplotlib-pyplot/

### http://python-para-impacientes.blogspot.com/2014/08/graficos-en-ipython.html
from collections import Counter

from prettytable import PrettyTable

import matplotlib.pyplot as plt

import numpy as np 


hashtags = [u'Deportes', u'Rio2016', u'YoRio', u'YoRio', u'Soyfandelupita', u'Paralimpicos', u'YoRio', u'fb', u'olimpiadas', u'yorio', u'vacaciones', u'tirolesas', u'YoRio', u'Tokio2020', u'YoRio', u'YoRio', u'YoRio', u'YoRio', u'Oro', u'YoRio', u'yorio', u'YoRio', u'YoRio', u'YoRio', u'yoRio', u'olympics', u'YoRio', u'YoRioxESPN', u'yoRio', u'GraciasRioPor', u'Rio2016', u'YoRio', u'YoRioxESPN', u'yorio', u'JuegosOlimpicos', u'GraciasRioPor', u'YoRio', u'YoRioxESPN', u'Rio2016', u'GraciasRio', u'Tokio2020', u'YoRio', u'GraciasRioPor', u'YoRio', u'Rio2016', u'JuegosOlimpicosRio2016', u'YoR\xedo', u'YoRio', u'paraolimpiadas', u'YoRio', u'YoRio', u'AndresBustamante', u'Tokio2020', u'YoRio', u'TodosSomosSuiza', u'TodosSomosTercerSet', u'YoRio', u'YoRio', u'GraciasRioPor', u'YoRioxESPN', u'YoRio', u'yorio', u'GraciasRioPor', u'YoRioxESPN', u'YoRio', u'YoRio', u'Japon2020', u'YoRio', u'GraciasRioPor', u'YoRioxESPN', u'YoRio', u'YoRioxESPN', u'YoR\xedo', u'GraciasRioPor', u'YoRioxESPN', u'YoRio', u'GraciasRioPor', u'YoRioxESPN', u'YoRio', u'GraciasRioPor', u'YoRio', u'YoRioxESPN', u'YoRio', u'rioxespn', u'YoRio', u'YoRio', u'YoRioxESPN', u'olimpicosrio2016', u'ESPN', u'YoRio', u'balondividido', u'YoRioxESPN', u'YoRio', u'rio2016', u'olympics', u'olympics2016', u'paralimpico', u'paralimpic', u'goo', u'yorioxespn', u'yorio', u'YoRio', u'YoRio', u'Rio2016', u'CeremoniaDeClausura', u'Tokio2020', u'RiotoTokyo', u'oro', u'Plata', u'Bronce', u'Olympics', u'YoRioxESPN', u'YoRio', u'YoRio', u'YoRio', u'Leyendas', u'IAmTheMan', u'YoRio', u'Rio2016', u'Olympics', u'R\xedo', u'RiodeJaneiro', u'Brasil', u'YoRio', u'Ol\xedmpicos', u'ESPN', u'YoRio', u'YoRioxESPN', u'YoRioxESPN', u'ESPN', u'GraciasRioPorESPN', u'YoRio', u'yorio', u'YoRioxESPN', u'condicional', u'yorio', u'YoRio', u'CeremoniaDeClausura', u'YoRio', u'GraciasRio', u'Tokio2020', u'YoRio', u'YoRio', u'yo', u'GraciasRio', u'Tokio2020', u'YoRio', u'YoRio', u'tokio2020', u'yorio', u'juegosolimpicos', u'Brasil', u'Brasil', u'YoRio', u'YoRio', u'yorio', u'YoRio', u'Fail', u'yorio', u'YoRioxESPN', u'yorio', u'YoRio', u'CeremoniaDeClausura', u'YoRio', u'YORIO', u'YoRio', u'YoR\xedo', u'YoRio', u'MX', u'yorio', u'Rio2016', u'YoRio', u'YoRioxESP', u'COL', u'Rio2016', u'YoRio', u'OlimpiadeRio2016', u'YoRio', u'YoRio', u'YoRio', u'YoRei', u'YoReire', u'Rio2016', u'CeremoniaDeClausura', u'YoRio', u'Rio2016', u'freethenipples', u'yoRio', u'YoRio', u'CeremoniaDeClausura', u'YoRio', u'Olimp\xedadas', u'YoRio', u'YoRio', u'Yo_corro', u'nikeplus', u'YoRio', u'YoRio', u'YoRio', u'R\xedo', u'RiodeJaneiro', u'Brasil', u'YoRio', u'Ol\xedmpicos', u'YoRio', u'YoRio', u'YoRio', u'Tokio2020', u'JuegosOlimpicos', u'yorio', u'YoRioxESPN', u'YoR\xedo', u'TuR\xedes', u'ElR\xede', u'EllaR\xede', u'EllosR\xeden', u'NosotrosRe\xedmos', u'UstedesR\xeden', u'Rio2016', u'Tokio2020', u'Tokio2020', u'CeremoniadeClausura', u'Rio2016xFOX', u'YoRio', u'Rio2016', u'JuegosOlimpicos', u'YoRioxESPN', u'YoLloro', u'YoRio', u'YoRio', u'YoRio']

screen_names = [u'ESPNmx', u'ESPNmx', u'ClaroSports', u'ClaroSports', u'ESPNmx', u'Faitelson_ESPN', u'Palomo_ESPN', u'espn', u'Rio2016', u'9GAG', u'joserra_espn', u'ESPNmx', u'werevertumorro', u'Faitelson_ESPN', u'ESPNmx', u'espn', u'ESPNmx', u'joserra_espn', u'chockoleiro', u'espn', u'EddyRios_', u'AnaGGuevara', u'Faitelson_ESPN', u'joapeca', u'TheMorrisMx', u'EPN', u'mexico', u'ESPNmx', u'ESPNmx', u'SoyUnStrapp', u'joserra_espn', u'MichaelPhelps', u'usainbolt', u'Deb_Estrella', u'AstroTerry', u'ESPNArgentina', u'espn', u'PresidenciaMX', u'CONADE', u'chockoleiro', u'joserra_espn', u'Faitelson_ESPN', u'joapeca', u'TheMorrisMx', u'EPN', u'mexico', u'ESPNmx', u'TheMorrisMx', u'EPN', u'mexico', u'YodaFath', u'EPN', u'mexico', u'CanalOnce11', u'joserra_espn', u'DavidFailtelson', u'ESPNmx', u'Lemocarv', u'PachoBenitezGol', u'ESPNmx', u'joserra_espn', u'CarolinaPadron', u'mauriciopedroza', u'Palomo_ESPN', u'cprocuna', u'paugr', u'puig_ricardo', u'Faitelson_ESPN', u'joserra_espn', u'Faitelson_ESPN', u'NTelevisa_com', u'CarlosLoret', u'espn', u'ElPrincipeDice', u'EPN', u'Wmichell', u'pelud0wn', u'EPN', u'giss1209', u'Deb_Estrella', u'AstroTerry', u'Javo__O', u'EPN', u'mexico', u'moriuper', u'giss1209']

words = [u'Si', u'estamos', u'hablando', u'de', u'#Deportes', u'tenemos', u'que', u'decir', u'#Rio2016', u'Los', u'Mejores', u'momentos', u'de', u'#YoRio', u'https://t.co/U9svEFTjfS', u'@ESPNmx', u'#YoRio', u'mi', u'momento:', u'la', u'plata', u'de', u'Lupita!', u'#Soyfandelupita', u'Terminaron', u'Ios', u'JJOO,', u'espero', u'que', u'@ESPNmx', u'y', u'@ClaroSports', u'transmitan', u'los', u'#Paralimpicos', u'de', u'la', u'misma', u'manera', u'#YoRio', u'#fb', u'https://t.co/OcJTLCUZIb', u'#olimpiadas', u'#yorio', u'#vacaciones', u'#tirolesas', u'https://t.co/g1TMTsUMzd', u'Gracias', u'@ClaroSports', u'por', u'mantenernos', u'tan', u'cerca', u'de', u'R\xedo,', u'lo', u'que', u'no', u'vi', u'por', u'TV', u'lo', u'vi', u'desde', u'su', u'gran', u'App.', u'#YoRio', u'nos', u'vemos', u'en', u'#Tokio2020', u'\U0001f3c5', u'Gracias', u'Rio!', u'#YoRio', u'@ESPNmx', u'#YoRio', u'emotivo', u'mensaje', u'del', u'final', u'de', u'R\xedo', u'2016', u'narrando', u'por', u'@Faitelson_ESPN.', u'Como', u'siempre', u'haciendo', u'un', u'excelente', u'trabajo,', u'gracias', u'ESPN!', u'viendo', u'la', u'clausura', u'de', u'los', u'juegos', u'Ol\xedmpicos', u'con', u'alitas!', u'(no', u'puedo', u'escuchar', u'porque', u'tienen', u'a', u'todo', u'volumen', u'la', u'musica', u'en', u'el', u'restaurante)', u'#YoRio', u'Misi\xf3n', u'cumplida', u'@Palomo_ESPN', u'#YoRio', u'@espn', u'@Rio2016', u'\U0001f44f', u'\U0001f1e7\U0001f1f7', u'#Oro', u'\U0001f44f', u'Juegos', u'Paral\xedmpicos', u'de', u'Rio', u'2016,', u'un', u'encanto', u'de', u'video', u'<3', u'#YoRio', u"We're", u'The', u'Superhumans', u'|', u'Rio', u'Paralympics', u'2016', u'https://t.co/fmqPZMlQbK', u'C\xf3mo', u'busco', u'al', u'tr\xedo?', u'quiero', u'esa', u'rola', u'#yorio', u'#YoRio', u'-', u'Best', u'celebration', u'ever', u'https://t.co/6x2Jd6soPk', u'v\xeda', u'@9GAG', u'@joserra_espn', u'@ESPNmx', u'incluido', u'el', u'@werevertumorro', u'o', u'a', u'ese', u'hijo', u'lo', u'sigues', u'desconociendo???', u'Ah,', u'solo', u'@Faitelson_ESPN', u'lo', u'chikiteas!', u'#YoRio', u'Excelente', u'cobertura', u'#YoRio', u'ESPN,', u'la', u'mejor', u'que', u'haya', u'visto', u'en', u'ol\xedmpicos', u'Pocas', u'cosas', u'como', u'los', u'deportes', u'generan', u'tantas', u'y', u'tantas', u'emociones', u'que', u'actualmente', u'necesitamos', u'para', u'no', u'olvidar', u'quienes', u'somos.', u'#yoRio', u'#olympics', u'hace', u'tanto', u'que', u'no', u've\xeda', u'una', u'cobertura', u'tan', u'buena', u'de', u'unos', u'Juegos', u'Ol\xedmpicos.', u'Felicidades', u'@ESPNmx', u'Maravilloso', u'programa', u'#YoRio', u'#YoRioxESPN', u'\U0001f44f\U0001f3fc\U0001f44f\U0001f3fc\U0001f44f\U0001f3fc', u'Vi', u'lo', u'mejor', u'en', u'#yoRio', u'21', u'd\xedas', u'Juegos', u'Ol\xedmpicos', u'cerca', u'del', u'mar', u'nadie', u'me', u'lo', u'va', u'borrar', u'#GraciasRioPor', u'esas', u'panor\xe1micas', u'extraordinarias', u'de', u'#Rio2016', u'trabajo', u'de', u'@espn.Belleza', u'total.Arrobo.Excelente', u'transmisi\xf3n.', u'#YoRio', u'#YoRioxESPN', u'#yorio', u'voy', u'a', u'extra\xf1ar', u'no', u'volver', u'a', u'ver', u'nunca', u'm\xe1s', u'el', u'monopolio', u'televisivo', u'gracias', u'@ESPNmx', u'magn\xedfica', u'transmisi\xf3n', u'mis', u'8vos', u'#JuegosOlimpicos', u'tnks', u'#GraciasRioPor', u'palabras', u'hermosas', u'de', u'@joserra_espn', u'"Unos', u'Juegos', u'profundamente', u'hermosos,de', u'cara', u'al', u'mar."', u'Gracias', u'#YoRio', u'#YoRioxESPN', u'#Rio2016', u'RT', u'@chockoleiro:', u'#GraciasRio', u'ahora', u'a', u'esperar', u'a', u'#Tokio2020', u'suena', u'bien,', u'no?', u'#YoRio', u'https://t.co/xxJQJlIze4', u'#GraciasRioPor', u'que', u'lloro', u'de', u'emoci\xf3n', u'con', u'#YoRio', u'de', u'despedida.', u'Excelente', u'@espn', u'\xa1Nunca', u'me', u'olvidar\xe9', u'de', u'#Rio2016', u'#JuegosOlimpicosRio2016!', u'Nada', u'malos', u'esos', u'cantores', u'en', u'#YoR\xedo,', u'no', u'los', u'conoc\xeda.', u'#YoRio', u'waoo', u'que', u'momentos', u'vivieron', u'estos', u'atletas,', u'me', u'siento', u'triste', u'porque', u'ay', u'que', u'esperar', u'4', u'a\xf1os'
, u'mas', u'para', u'ver', u'estos', u'atletlas', u'hacer', u'historia', u'Nunca', u'he', u'estado', u'de', u'acuerdo', u'en', u'q', u'apaguen', u'la', u'llama', u'olimpica', u'si', u'siguen', u'las', u'#paraolimpiadas', u'#YoRio', u'Ya', u'falto', u'el', u'g\xfciri', u'g\xfciri', u'en', u'los', u'#YoRio', u'y', u'si', u'hace', u'un', u'canal', u'de', u'YouTube', u'#AndresBustamante', u'para', u'#Tokio2020', u'#YoRio', u'lo', u'que', u'm\xe1s', u'me', u'gust\xf3', u'fue', u'#TodosSomosSuiza', u'y', u'#TodosSomosTercerSet', u'haaaaaaaaa....', u'que', u'maravilla....', u'RT', u'@EddyRios_:', u'Tuve', u'la', u'oportunidad', u'de', u'comenzar', u'con', u'#YoRio', u'desde', u'enero', u'y', u'tristemente', u'no', u'pude', u'concluir.', u'A\xfan', u'as\xed', u'fue', u'una', u'gran', u'experiencia', u'que\u2026', u'Tuve', u'la', u'oportunidad', u'de', u'comenzar', u'con', u'#YoRio', u'desde', u'enero', u'y', u'tristemente', u'no', u'pude', u'concluir.', u'A\xfan', u'as\xed', u'fue', u'una', u'gran', u'experiencia', u'que', u'me', u'dej\xf3', u'mucho.', u'#GraciasRioPor', u'hacerme', u'parte', u'de', u'la', u'historia', u'\xa1Los', u'viv\xed,los', u'viv\xed!', u'La', u'emocion', u'de', u'ver', u'grandes', u'leyendas', u'del', u'deporte', u'despedirse', u'#YoRioxESPN', u'#YoRio', u'@AnaGGuevara', u'@Faitelson_ESPN', u'excelente', u'transmisi\xf3n', u'en', u'#yorio', u'esperemos', u'puedas', u'ayudar', u'al', u'deporte', u'de', u'mx,', u'eres', u'la', u'ideal', u'para', u'dirigir', u'el', u'rumbo!', u'#GraciasRioPor', u'Ver', u'tanta', u'belleza', u'interna', u'y', u'externa', u'de', u'hombres', u'y', u'mujeres', u'\xa1Y', u'esos', u'tacos', u'de', u'ojo', u'con', u'tanto', u'guapo!', u'Por', u'qu\xe9', u'no', u'#YoRioxESPN', u'#YoRio', u'Pues', u'se', u'nos', u'termino', u'#YoRio', u'nos', u'vemos', u'en', u'#Japon2020', u'\U0001f44d', u'RT', u'@joapeca:', u'@TheMorrisMx', u'A', u'las', u'diez', u'mis', u'@EPN', u'Boots,a', u'las', u'diez,@mexico', u'no', u'debe', u'saber', u'que', u'yo', u'soy', u'uno', u'de', u'ustedes', u'#YoRio', u'https://t.co/26YdPZVk\u2026', u'#GraciasRioPor', u'\xa1Hacerme', u'VIVIR', u'Y', u'VIBRAAARRR!', u'\xa1Esas', u'finales', u'de', u'nerrrrvios!', u'Gracias', u'hermanos', u'de', u'Brasil', u'po', u'su', u'gran', u'esfuerzo', u'#YoRioxESPN', u'#YoRio', u'@ESPNmx', u'gracias', u'por', u'llevarnos', u'una', u'transmisi\xf3n', u'de', u'primer', u'nivel', u'de', u'los', u'juegos', u'ol\xedmpicos', u'esperemos', u'que', u'en', u'4', u'a\xf1os', u'vuelvan', u'#YoRioxESPN', u'#YoR\xedo', u'#GraciasRioPor', u'motivarme,', u'ense\xf1arme,', u'por', u'el', u'paseo', u'hermoso', u'por', u'R\xedo,', u'sentir', u'que', u'ah\xed', u'estaba', u'apoyando', u'a', u'los', u'j\xf3venes', u'atletas.', u'#YoRioxESPN', u'#YoRio', u'#GraciasRioPor', u'hacerme', u'emocionarme', u'hasta', u'las', u'l\xe1grimas', u'al', u'ver', u'a', u'nuestros', u'j\xf3venes', u'atletas', u'triunfando', u'\xa1Me', u'motiva', u'tanto!', u'#YoRioxESPN', u'#YoRio', u'#GraciasRioPor', u'hacerme', u'saber', u'que', u'nunca', u'es', u'tarde', u'para', u'superarme', u'a', u'm\xed', u'misma', u'y', u'motivarme', u'a', u'trabajar', u'y', u'luchar.#YoRio', u'#YoRioxESPN', u'Thanks', u'ESPN', u'FOR', u'#YoRio', u'2016...muchas', u'gracias', u'@ESPNmx', u'tip', u'para', u'el', u'futuro:', u'no', u'metan', u'comerciales', u'en', u'las', u'ceremonias,', u'cualquiera', u'que', u'sea...los', u'himnos', u'tambi\xe9n', u'son', u'importantes', u'#rioxespn', u'#YoRio', u'@SoyUnStrapp', u'Dicen', u'que', u'las', u'imagenes', u'dicen', u'mas', u'que', u'un', u'mill\xf3n', u'de', u'Twitters,', u'\xbfO', u'no?', u'Por', u'eso', u'#YoRio', u'https://t.co/xGBDzyhiAF', u'Gracias', u'#YoRioxESPN', u'Por', u'llevarme', u'a', u'Los', u'#olimpicosrio2016', u'a', u'travez', u'de', u'la', u'pantalla', u'de', u'mi', u'TV!', u'\u26bd\U0001f6b4\U0001f3c7\U0001f3c0\u26be\U0001f3ca\U0001f3be\U0001f46f', u'#ESPN', u'#YoRio', u'#balondividido', u'#YoRioxESPN', u'#YoRio', u'https://t.co/TpkZOA37IU', u'#rio2016', u'#olympics', u'#olympics2016', u'#paralimpico', u'#paralimpic', u'\
u263a\U0001f64c\U0001f64b\u2764\U0001f44d\u270c\U0001f44b', u'#goo', u'#yorioxespn', u'#yorio\u2026', u'https://t.co/Dei7iL0Ukk', u'RT', u'mauriciopedroza:', u'Por', u'entrar', u'con', u'joserra_espn', u'y', u'Faitelson_ESPN', u'a', u'hablar', u'de', u'lo', u'que', u'nos', u'dej\xf3', u'la', u'nataci\xf3n', u'en', u'#YoRio\u2026', u'https://t.co/RnDcBAS4hJ', u'#YoRio', u'#Rio2016', u'#CeremoniaDeClausura', u'#Tokio2020', u'#RiotoTokyo', u'#oro', u'#Plata', u'#Bronce', u'#Olympics', u'#YoRioxESPN', u'https://t.co/Ai6g6U80rQ', u'Esta', u'semana', u'muchos', u'tendremos', u'sindrome', u'de', u'abstinencia', u'olimpica', u'#YoRio', u'RT', u'mauriciopedroza:', u'Por', u'entrar', u'con', u'joserra_espn', u'y', u'Faitelson_ESPN', u'a', u'hablar', u'de', u'lo', u'que', u'nos', u'dej\xf3', u'la', u'nataci\xf3n', u'en', u'#YoRio\u2026', u'https://t.co/dHr01K1ted', u'@joserra_espn', u'#YoRio', u'gran', u'video', u'de', u'@MichaelPhelps', u'@usainbolt', u'subanlo', u'a', u'youtube', u'#Leyendas', u'#IAmTheMan', u'#YoRio', u'\U0001f64f\U0001f3fc\U0001f622', u'#Rio2016', u'#Olympics', u'RT', u'@Deb_Estrella:', u'#R\xedo', u'#RiodeJaneiro', u'#Brasil', u'desde', u'el', u'espacio.', u'Soberbia', u'foto', u'del', u'astronauta', u'@AstroTerry', u'#YoRio', u'#Ol\xedmpicos', u'https://t.co/YyAC\u2026', u'Siempre', u'los', u'programas', u'y', u'las', u'cadenas', u'donde', u'este', u'joserra', u'ser\xe1n', u'los', u'mejores', u'#ESPN', u'#YoRio', u'#YoRioxESPN', u'\U0001f44b\U0001f3fd\U0001f63f', u'#YoRioxESPN', u'Gracias', u'Totales!', u'Cobertura', u'de', u'clase', u'mundial,', u'ORO', u'para', u'#ESPN', u'#GraciasRioPorESPN', u'#YoRio', u'@ESPNArgentina', u'#yorio', u'#YoRioxESPN', u'una', u'verg\xfcenza', u'la', u'conductora', u'ri\xe9ndose', u'de', u'la', u'ca\xedda', u'del', u'corredor,', u'una', u'falta', u'de', u'respeto', u'incre\xedble', u'\U0001f621\U0001f621\U0001f621', u'Me', u'gustar\xeda', u'que', u'@ESPN', u'se', u'exprese,', u'como', u'se', u'expresa', u'y', u'habla', u'de', u'Phelps,', u'de', u'los', u'paral\xedmpicos', u'en', u'especial', u'de', u'Gustavo', u'S\xe1nchez', u'#condicional', u'#yorio', u'@PresidenciaMX', u'Han', u'promovido', u'tanto', u'al', u'SNA', u'que', u'aparte', u'del', u'departamento', u'de', u'la', u'Gaviota', u'el', u'fracaso', u'de', u'@CONADE', u',Si', u'no', u'impera', u'la', u'impunidad', u'#YoRio', u'Ya', u'las', u'vi', u'criticando', u'la', u'clausura,', u'como', u'si', u'hubieran', u'uds.', u'Tenido', u'una', u'mejor', u'idea,', u'que', u'esperaban!?', u'Es', u'Rio.', u'#CeremoniaDeClausura', u'#YoRio', u'RT', u'@chockoleiro:', u'#GraciasRio', u'ahora', u'a', u'esperar', u'a', u'#Tokio2020', u'suena', u'bien,', u'no?', u'#YoRio', u'https://t.co/xxJQJlIze4', u'@joserra_espn', u'eres', u'grande', u'y', u'que', u'bueno', u'q', u'callas', u'a', u'@Faitelson_ESPN', u'#YoRio', u'#yo', u'#GraciasRio', u'ahora', u'a', u'esperar', u'a', u'#Tokio2020', u'suena', u'bien,', u'no?', u'#YoRio', u'https://t.co/xxJQJlIze4', u'RT', u'@joapeca:', u'@TheMorrisMx', u'A', u'las', u'diez', u'mis', u'@EPN', u'Boots,a', u'las', u'diez,@mexico', u'no', u'debe', u'saber', u'que', u'yo', u'soy', u'uno', u'de', u'ustedes', u'#YoRio', u'https://t.co/26YdPZVk\u2026', u'"Ah\xed', u'podemos', u'ver', u'la', u'bandera', u'de', u'Chihuahua"', u'Gracias', u'a', u'todos', u'los', u'cronistas', u'de', u'@espnmx', u'#tokio2020', u'#yorio', u'Se', u'acabaron', u'los', u'#juegosolimpicos', u'#Brasil', u'd', u'retos,', u'nostalgia,', u'admiraci\xf3n,', u'esfuerzo,', u'oportunidades,', u'talentos,', u'festejos.', u'Gracias', u'#Brasil', u'#YoRio', u'@TheMorrisMx', u'A', u'las', u'diez', u'mis', u'@EPN', u'Boots,a', u'las', u'diez,@mexico', u'no', u'debe', u'saber', u'que', u'yo', u'soy', u'uno', u'de', u'ustedes', u'#YoRio', u'https://t.co/26YdPZVkbj', u'#yorio', u'gracias', u'x', u'esos', u'juegos', u'tan', u'maravillosos', u'e', u'inolvidables', u'\U0001f1e7\U0001f1f7\U0001f1e7\U0001f1f7\U0001f1e7\U0001f1f7', u'@YodaFath', u'Pobres', u'@EPN', u'Boots', u'el', u'felicita', u'a', u'los', u'atletas', u'y', u'ustedes', u'a', u'el,\
xa1que', u'veo', u'si', u'si', u'compiti\xf3', u'por', u'@mexico', u'!', u'#YoRio', u'https://t.co/jznPQI8PfD', u'Quien', u'es', u'el', u'comunicador', u'de', u'@CanalOnce11', u'que', u'esta', u'en', u'contra', u'de', u'la', u'clausura', u'de', u'los', u'JO?', u'Osea', u'es', u'una', u'fiesta', u'mundial', u'#Fail', u'canal', u'11', u'Bien', u'#yorio', u'#YoRioxESPN', u'#yorio', u'porque', u'siempre', u'estan', u'de', u'pleito', u'@joserra_espn', u'y', u'@DavidFailtelson', u'https://t.co/NxaCn7jB8T', u'#YoRio', u'Se', u'acabaron', u'los', u'juegos', u'#CeremoniaDeClausura', u'#YoRio', u'volvamos', u'a', u'la', u'lucha', u'diaria,', u'esperemos', u'4', u'a\xf1os.', u'https://t.co/JXhJF8LnKJ', u'@ESPNmx', u'LA', u'NETA,', u'LA', u'NETA...', u'EXCELENTE', u'COBERTURA', u'LA', u'QUE', u'GENER\xd3', u'ESPN;', u'ENHORABUENA.', u'#YORIO', u'RT', u'@Lemocarv:', u'@PachoBenitezGol', u'gran', u'trabajo', u'en', u'#YoRio', u'comentarios', u'claros', u'profesionales', u'excelente', u'cobertura', u'y', u'sobre', u'todo', u'la', u'emoci\xf3n', u'@ESPNmx', u'#YoR\xedo', u'@joserra_espn', u'@CarolinaPadron', u'@mauriciopedroza', u'@Palomo_ESPN', u'@cprocuna', u'@paugr', u'@puig_ricardo', u'@Faitelson_ESPN', u'GRACIAS!!!', u'#YoRio', u'@joserra_espn', u'@Faitelson_ESPN', u'excelentes', u'programas.', u'Los', u'esperamos', u'para', u're\xedr', u'en', u'Jap\xf3n.', u'@NTelevisa_com', u'@CarlosLoret', u'califiquen', u'con', u'datos,', u'desde', u'84', u'es', u'el', u'3er', u'mejor', u'resultado', u'de', u'#MX', u'y', u'el', u'5\xba', u'mejor', u'en', u'su', u'historia', u'#yorio', u'#Rio2016', u'Un', u'GRACIAS', u'Gigante', u'a', u'@ESPN', u'#YoRio', u'#YoRioxESP', u'porque', u'apoyaron', u'a', u'los', u'colombianos', u'#COL', u'con', u'el', u'coraz\xf3n', u'\u2764', u'en', u'todas', u'sus', u'transmisiones', u'#Rio2016', u'Y', u'ahora??', u'De', u'que', u'van', u'hablar???', u'#YoRio', u'Me', u'encant\xf3', u'la', u'apertura', u'pero', u'le', u'faltaba', u'carnaval...', u'Ahora', u'si!!!!', u'Hermoso', u'cierre!!!', u'#OlimpiadeRio2016', u'Felicidades', u'a', u'los', u'5', u'campeones,', u'por', u'sus', u'medallas', u'y', u'a', u'todos', u'los', u'que', u'nos', u'representaron,', u'por', u'su', u'gran', u'esfuerzo!', u'#YoRio', u'https://t.co/mPP7NWgZmS', u'@ElPrincipeDice', u'Jovenes', u'creativos', u'los', u'@EPN', u'Boots,en', u'el', u'mar', u'de', u'oportunidades', u'recibieron', u'la', u'suya', u'por', u'eso', u'#YoRio', u'https://t.co/9QCbKeWRix', u'#YoRio', u'#YoRei', u'y', u'#YoReire', u'con', u'#Rio2016', u'RT', u'@Wmichell:', u'Detallazo', u'homenajear', u'a', u'los', u'voluntarios!!.Los', u'casi', u'anonimos', u'que', u'hacen', u'funcionar', u'las', u'cosas', u'por', u'puro', u'coraz\xf3n!!', u'#CeremoniaDeClaus\u2026', u'\xbfEs', u'idea', u'm\xeda', u'o', u'el', u'cierre', u'de', u'#Rio2016', u'fue', u'una', u'dosis', u'de', u'#freethenipples?', u'#yoRio', u'Se', u'acabo', u'\U0001f622', u'#YoRio', u'Que', u'lujo', u'de', u'olimpiadas', u',', u'que', u'buena', u'#CeremoniaDeClausura', u'.', u'Felicidad!', u'#YoRio', u'A', u'esperar', u'otros', u'cuatro', u'a\xf1os', u'para', u'ver', u'las', u'#Olimp\xedadas...', u'#YoRio', u'Mientras', u'#YoRio', u'llega', u'a', u'su', u'fin', u'#Yo_corro....!!!', u'Acabo', u'de', u'correr', u'6.07', u'km', u'a', u'un', u'ritmo', u'de', u"5'13''", u'con', u'Nike+', u'https://t.co/Q2zB6vsQsd', u'#nikeplus', u'Los', u'veo', u'en', u'Tokio', u'#YoRio', u'@pelud0wn', u'Es', u'hermoso', u'ver', u'que', u'a', u'los', u'@EPN', u'Boots', u'les', u'gusta', u'lo', u'grande', u'lo', u'm\xe1s', u'grande,\xa1', u'lo', u'grandototote!', u'Por', u'eso', u'#YoRio', u'https://t.co/De5yikxL7E', u'RT', u'@giss1209:', u'Ser\xe1', u'que', u'el', u'de', u'ESPN', u'puede', u'dejar', u'de', u'hablar', u'de', u'M\xe9xico?', u'Es', u'Brazil', u'#YoRio', u'RT', u'@Deb_Estrella:', u'#R\xedo', u'#RiodeJaneiro', u'#Brasil', u'desde', u'el', u'espacio.', u'Soberbia', u'foto', u'del', u'astronauta', u'@AstroTerry', u'#YoRio', u'#Ol\xedmpicos', u'https://t.co/YyAC\u2026', u'El', u'pa\xeds', u'm\xe1s', u'alegre', u'y', u'
maravilloso', u'del', u'mundo', u',', u'despide', u'su', u'mega', u'evento', u'#YoRio', u'#YoRio', u'muy', u'buena', u'transmisi\xf3n,', u'esperemos', u'que', u'as\xed', u'sea', u'la', u'de', u'los', u'juegos', u'paralimpicos', u'@Javo__O', u'@EPN', u'\xa1Silencio', u'!', u'@mexico', u'los', u'ni\xf1os', u'est\xe1n', u'haciendo', u'su', u'tarea,mientras', u'les', u'tendr\xedamos', u'su', u'frutsi', u'#YoRio', u'https://t.co/SqT3PAH9wl', u'RT', u'@moriuper:', u'La', u'presentaci\xf3n', u'de', u'#Tokio2020', u'estuvo', u'demasiado', u'cool', u'#JuegosOlimpicos', u'#yorio', u'#YoRioxESPN', u'#YoR\xedo', u'#TuR\xedes', u'#ElR\xede', u'#EllaR\xede', u'#EllosR\xeden', u'#NosotrosRe\xedmos', u'#UstedesR\xeden', u'#Rio2016', u'#Tokio2020', u'https://t.co/LkE4azl1ZF', u'Si', u'la', u'presentaci\xf3n', u'de', u'#Tokio2020', u'fue', u'as\xed...', u'Ya', u'quiero', u'ver', u'la', u'inauguraci\xf3n.', u'#CeremoniadeClausura', u'#Rio2016xFOX', u'#YoRio', u'Pues', u'ya', u'se', u'acabo', u'#Rio2016', u'#JuegosOlimpicos', u'#YoRioxESPN', u'ahora', u'ser\xe1', u'#YoLloro', u'ya', u'no', u'es', u'#YoRio', u'#YoRio', u'el', u'cierre', u'de', u'los', u'juegosolimpicos', u'fue', u'mejor', u'que', u'el', u'opening...', u'RT', u'@giss1209:', u'Ser\xe1', u'que', u'el', u'de', u'ESPN', u'puede', u'dejar', u'de', u'hablar', u'de', u'M\xe9xico?', u'Es', u'Brazil', u'#YoRio']




coleccion_hashtags = Counter(hashtags).most_common()[:15]  ### de la lista hashtags importamos una lista de tuplas con las 15 palabras mas comunes

coleccion_screen_names = Counter(screen_names).most_common()[:15]  ### de la lista screen_names importamos una lista de tuplas con las 15 palabras mas comunes

coleccion_words = Counter(words).most_common()[:15]  ### de la lista words importamos una lista de tuplas con las 15 palabras mas comunes



count_coleccion_hashtags = len(coleccion_hashtags) ### Solo vamos a ver el grafico de los hashtags, por lo q contamos cuanttos elementos hay
diccionario = dict() # creamos el diccionario
i = 0 # inicializamos la variable
lista_nueva1 =[]   # creamos la lsita1
lista_nueva2 = []  # creamos la lsita2

for i in  range(0,count_coleccion_hashtags): # creamos el bucle for para pasar por cada uno de los elementos de hashtags
        
        llave = coleccion_hashtags[i][0]  ### Llamamos llave el primer elemento de la tupla para cada elemento de la lista, creo q esta es la parte dificil de programar saber que es que cosa en el codigo
        valor = coleccion_hashtags[i][1]  ### llamamos clave a el segundo elemento de la tupla para cada i
        
        ### Necesitamos 2 lsitas para graficar X y Y
        lista_nueva1.append(llave)     # Esta es la palabra
        lista_nueva2.append(valor)     # este es el numero de veces que aparece en la lista hashtags
        

posicion_y = np.arange(len(lista_nueva1))
plt.barh(posicion_y, lista_nueva2, align = "center")
plt.yticks(posicion_y, lista_nueva1)
plt.xlabel('Palabras')
plt.title("Numero de Repeticiones")
plt.show()


explode = [0.1, 0, 0, 0, 0, 0, 0, 0.1, 0.1, 0, 0, 0, 0, 0, 0.] # Para mi esto es lo mas importante de explicar por ejemplo ay 0 y 0,1
                                           ###  Los que son mayores que 0 se veran un poco mas separados y es una funcion para hacer notar algo
plt.pie(lista_nueva2, explode=explode, labels=lista_nueva1, autopct='%1.1f%%', shadow=True) # Aqui se construyte como queremos ver el Grafico
plt.title("Histograma de una clase Twitter", bbox={"facecolor":"0.8", "pad":5}) ### Este es el titulo
plt.legend()
plt.show()


En esta entrada decidí comentar lo mas interesante e importante del código…. En resumen, se crean 2 Gráficos de los Hashtags de la etiqueta #YoRio, aunque decidí colocar la lista que habíamos obtenidos de imprimir hashtags «print hashtags» del código de la entrada anterior, el primero es de barras y  el segundo es de Torta ademas se saca la fracción de cada elemento involucrado en el 100% o total de las palabras estudiadas que fueron 15 y no el total real….

Con esta entrada comenzamos esta serie en la que vamos solo a analizar las salidas de cada cuenta con el programa que vamos a ir construyendo en las otras series….

La salida de este programa es la siguiente:

grafico1

Al cerrar la ventana nos aparece este:

grafico2

De verdad es que me parece muy interesante ver los datos en gráficas par aprender mas 😀

Que Dios les Bendiga, hasta pronto, recuerda ahora puedes darle me gusta y ratear las entradas de este blog, ademas deja tus dudas en estos temas, podrían convertirse en algo interesante para otros…

Información de interés que a mi me pareció de mucha ayuda:

Pybonacci como siempre un sitio donde aprender y deleitarse con buenas practicas de Python: http://pybonacci.org/tag/tutorial-matplotlib-pyplot/

Python para impacientes, de aqui saque la forma de imprimir el grafico, no soy un experto en eso :S

http://python-para-impacientes.blogspot.com/2014/08/graficos-en-ipython.html

 

 

Jugando con la API de Twitter [Parte 4]

En esta entrada vamos a ver nuestras primeras tablas, no te emociones aun, vamos a ver como python le da formato a datos sencillos, aunque en la siguiente entrada si vamos a ver gráficos de lo que hemos ido haciendo hasta ahora con la otra serie que te recuerdo va paralela a esta Manejando los datos de la API Twitter en Python [Parte 1]  ademas aquí te tengo mi nuevo repositorio de GitHub que hasta ahora solo tiene 2 de las series del Blog pero las voy a ir subiendo poco a poco y para este año espero tener de 10 a 15 series en el repo, solo voy a subir repositorios míos no voy a hacer fork de ningún repo de otra persona, así que aquí esta mi nuevo repo: https://github.com/Seth-Root No me entusiasma mucho los 2 repos que he subido pero son los mas completos y el código esta interesante.

Bueno a lo que nos interesa, «PrettyTable es una biblioteca de Python sencilla para visualizar fácilmente los datos tabulares en un formato de tabla ASCII visualmente atractivo.

PrettyTable es una biblioteca de Python simple diseñada para que sea fácil y rápido para representar datos tabulares en las tablas ASCII visualmente atractivos. Se inspira en las tablas ASCII utilizados en la cáscara de psql de PostgreSQL. PrettyTable permite la selección de las columnas que se van a imprimir, la alineación independiente de columnas (izquierda o derecha o centrado) y la impresión de «sub-tablas» especificando un rango fila.»

Información de aquí

Como aun estamos con nuestros programas en linea de comandos, tenemos que buscar la manera de ver la salida lo mas interesante, fácil y educativa posible y es por esto que me he permitido colocar este formato aquí, ademas en el libro que venimos siguiendo de minando las web sociales tienen un ejemplo de esto y lo coloque aquí 😀

Vamos a visualizar los datos que podemos ver con el siguiente código:


import twitter, json

from collections import Counter

from prettytable import PrettyTable


# Datos de autenticacion
CONSUMER_KEY = 'Datos de A'

CONSUMER_SECRET = 'Datos de B'

OAUTH_TOKEN = 'Datos de C'

OAUTH_SECRET = 'Datos de D'



auth = twitter.oauth.OAuth( OAUTH_TOKEN , OAUTH_SECRET, CONSUMER_KEY , CONSUMER_SECRET )

api = twitter.Twitter(auth=auth)

q =  '#yorio' # Coloca aqui la cuenta a estudiar


count = 100

search_results = api.search.tweets(q=q, count =count)

statuses = search_results['statuses']


  
retweet_counts = [status['retweet_count']
	 for status in statuses ]

status_texts = [status['text']
	 for status in statuses ]


screen_names = [user_mention['screen_name']
	 for status in statuses 
	     for user_mention in status ['entities']['user_mentions'] ]


hashtags = [hashtag['text']
	 for status in statuses 
	     for hashtag in status ['entities']['hashtags'] ]

words = [ w
	 for t in status_texts
	    for w in t.split()
  ]

for item in [words, screen_names, hashtags]:
    c = Counter(item)
    print c.most_common()[:20]
    print



for label, data in (('Word', words), ('Screen Name', screen_names), ('Hashtag', hashtags)):
    pt = PrettyTable(field_names=[label, 'Count'])
    c = Counter(data)
    [ pt.add_row(kv) for kv in c.most_common()[:20] ]
    pt.align[label], pt.align['Count'] = 'l', 'r' # Set column alignment
    print pt


    

La salida de este programa es sumamente importante, y consta de 2 partes interesantes para nosotros y debemos estudiarlas a fondo aunque aquí solo diré que las vamos a estudiar a fondo en la otra serie, lo que si me interesa tocar es los bloques de código del bucle for que generan esta salida


[(u'en', 103), (u'de', 76), (u'#YoRio', 73), (u'del', 62), (u'a', 61), (u'RT', 53), (u'Diego', 52), (u'Tendremos', 40), (u'a\xf1os', 40), (u'4to', 40), (u'lugar', 40), (u'NOCHE', 40), (u'22', 40), (u'fue', 40), (u'Con', 40), (u'lanzamiento', 40), (u'ESTA', 40), (u'Real.', 40), (u'#YoRioxESPN', 39), (u'martillo.', 34)]

[(u'Leonlec', 33), (u'ACC_Castillo', 8), (u'EPN', 6), (u'CONADE', 4), (u'joserra_espn', 4), (u'ESPNmx', 4), (u'PaolaEspinosaOf', 2), (u'Faitelson_ESPN', 2), (u'gobmx', 1), (u'mexico', 1), (u'yllenhot1', 1), (u'aristeguicnn', 1), (u'AnaGGuevara', 1), (u'INEMexico', 1), (u'PresidenciaMX', 1), (u'merizemborain', 1), (u'apmakeup', 1), (u'matsinfronteras', 1), (u'Pajaropolitico', 1), (u'Valencia_Guzman', 1)]

[(u'YoRio', 80), (u'YoRioxESPN', 40), (u'YoR\xedo', 15), (u'Rio2016', 3), (u'HondurasLlora', 2), (u'NoTeMuerasNunca', 2), (u'MePongoDePie', 2), (u'YoLloro', 2), (u'Idolo', 2), (u'Grandisima', 2), (u'lupitadeoro', 2), (u'YoRIO', 2), (u'EllaRie', 1), (u'TodosReimos', 1), (u'yorio', 1), (u'COL', 1), (u'Olimpiadas2016', 1), (u'Plata', 1), (u'LupitaMentality', 1), (u'yoRio', 1)]

+-------------+-------+
| Word        | Count |
+-------------+-------+
| en          |   103 |
| de          |    76 |
| #YoRio      |    73 |
| del         |    62 |
| a           |    61 |
| RT          |    53 |
| Diego       |    52 |
| Tendremos   |    40 |
| años        |    40 |
| 4to         |    40 |
| lugar       |    40 |
| NOCHE       |    40 |
| 22          |    40 |
| fue         |    40 |
| Con         |    40 |
| lanzamiento |    40 |
| ESTA        |    40 |
| Real.       |    40 |
| #YoRioxESPN |    39 |
| martillo.   |    34 |
+-------------+-------+
+-----------------+-------+
| Screen Name     | Count |
+-----------------+-------+
| Leonlec         |    33 |
| ACC_Castillo    |     8 |
| EPN             |     6 |
| CONADE          |     4 |
| joserra_espn    |     4 |
| ESPNmx          |     4 |
| PaolaEspinosaOf |     2 |
| Faitelson_ESPN  |     2 |
| gobmx           |     1 |
| mexico          |     1 |
| yllenhot1       |     1 |
| aristeguicnn    |     1 |
| AnaGGuevara     |     1 |
| INEMexico       |     1 |
| PresidenciaMX   |     1 |
| merizemborain   |     1 |
| apmakeup        |     1 |
| matsinfronteras |     1 |
| Pajaropolitico  |     1 |
| Valencia_Guzman |     1 |
+-----------------+-------+
+-----------------+-------+
| Hashtag         | Count |
+-----------------+-------+
| YoRio           |    80 |
| YoRioxESPN      |    40 |
| YoRío           |    15 |
| Rio2016         |     3 |
| HondurasLlora   |     2 |
| NoTeMuerasNunca |     2 |
| MePongoDePie    |     2 |
| YoLloro         |     2 |
| Idolo           |     2 |
| Grandisima      |     2 |
| lupitadeoro     |     2 |
| YoRIO           |     2 |
| EllaRie         |     1 |
| TodosReimos     |     1 |
| yorio           |     1 |
| COL             |     1 |
| Olimpiadas2016  |     1 |
| Plata           |     1 |
| LupitaMentality |     1 |
| yoRio           |     1 |
+-----------------+-------+

Los 2 bucles son estos:


### Bloque 1

for item in [words, screen_names, hashtags]:
    c = Counter(item)
    print c.most_common()[:20]
    print


### Bloque 2
for label, data in (('Word', words), ('Screen Name', screen_names), ('Hashtag', hashtags)):
    pt = PrettyTable(field_names=[label, 'Count'])
    c = Counter(data)
    [ pt.add_row(kv) for kv in c.most_common()[:20] ]
    pt.align[label], pt.align['Count'] = 'l', 'r' # Set column alignment
    print pt


    

Si analizamos bien el código anterior lo que estamos imprimiendo para el primer bloque es una lista con 1 diccionario adentro, esto debido a que la API nos proporciona una lista de muchos diccionarios y como estamos sobre esta, es decir no hemos creado diccionarios nuevos esto lo hacemos en la otra serie :D, la salida es lógica una lista de 1 diccionario con los items mas comunes que estamos evaluando.

Se me olvidaba también tenemos importada una librería llamada Counter que nos facilita el tener que contar los items mas comunes de una clase o método python como es nuestro caso tenemos 3 diccionario y el bloque 1 nos permite encontrar los mas comunes de cada diccionario, yo le coloque 20, aquí la linea en cuestión:


    print c.most_common()[:20]

El siguiente Bloque es mas interesante, nos permite visualizar los datos en una tabla para tener mejor percepción ademas los ordena 😀 de mayor a menor, podemos visualizar como para cada etiqueta tenemos 1 dato que vayamos agregando no sin antes contar con la librería Counter, Y a ti que se te ocurre hacer con estos datos 😀

Bueno a mi se me ocurrió que no me interesaban los datos con menos de 4 caracteres  y le coloque un condicional sencillo así:


for item in [words, screen_names, hashtags]:

    for palabra in item:
        if len(palabra) >= 4 :
            frecuencia[palabra] = frecuencia.get(palabra,0)+1 #esto nos cuenta todas las palabras
            
            
    print frecuencia
    print "  ############  "
    print "  ############  "
    print "  ############  "
    print "  ############  "



    

Que es lo que hice, simple crear un nuevo diccionario para imprimir en un diccionario las palabras que tengan mas de 4 caracteres y los agregue a un diccionario, con este mismo diccionario voy a imprimir lo que necesito, ojo pude usar el otro bloque que ya tenia pero me parece mas fácil de explicar así, puedes correr el siguiente programa y ver la salida(en la otra entrada):


for item in [words, screen_names, hashtags]:
    frecuencia = {}
    coleccion = {}
    lista_nueva=[]
    for palabra in item:
        if len(palabra) >= 4 :
	  frecuencia[palabra] = frecuencia.get(palabra,0)+1 #esto nos cuenta todas las palabras
	  lista_nueva.append(palabra)
    c = Counter(lista_nueva)
    print c.most_common()[:10]    
    print "  ############  "
    print "  ############  "    
    

    coleccion = c.most_common()[:10] 
    frecuencia_10 = len(coleccion)
    i = 0
    diccionario = dict()
    for i in range(0, frecuencia_10):
        key = coleccion[i][0]
        value = coleccion[i][1]
        diccionario[key] = value
     
    print diccionario


    t = PrettyTable(['key', 'value'])
    for key, val in diccionario.items():
        t.add_row([key, val])
    print t
            
            
    print "  ############  "
    print "  ############  "
    print "  ############  "
    print "  ############  "



    

Estaba tratando de hacer lo mas sencillo posible el código pasando por la librería operator hasta prettytables, pero me di cuenta que era mejor crear todo de nuevo o mejor dicho hacerlo lo mas sencillo pero largo posible, hoy no voy a comentar el código incluso falta colocarle las etiquetas al prettytable pero lo haré el lunes, ya a partir de ahora a descansar 😀

Fíjate que hay un solo ciclo FOR y para la siguiente entrada de la serie voy a dividirlos, incluso no se si la parte del prettytable quedara así, ya que a pesar de tener las 10 palabras mas usadas en cada Diccionario no están ordenados :S

Hasta la Próxima Feliz fin de Semana. Que Dios les Bendiga y le deje ver su Gloria en cada momento de Sus Vidas…

 

 

Jugando con la API de Twitter [Parte 3.2]

Con los datos recolectados en el programa de la entrada anterior podemos ir haciéndonos una idea de que tanto podemos avanzar y que información podemos obtener en Las Redes Sociales, pero en realidad no tenemos ni idea de que podemos hacer, ya que podemos hacer mucho mas con esta información, por ejemplo del Libro Mining-the-Social-Web-2nd-Edition en el capitulo que sigue podremos saber el léxico de una persona según sus twitter, no es un dato exacto pero hasta allá podemos llegar, en la especialización, hoy acabo de terminar el curso 4 que trata sobre el manejo de datos de la Red y Bases de datos, hemos usado un programa muy interesante para modelar datos en un mapa usando la geo-localización  de Google, mas adelante vamos a usar este mismo programa para visualizar diferentes datos en el mapa usando google y claro los datos que vamos a modelar son datos de las redes sociales, en primera instancia los datos que saquemos de la API de Twitter y posiblemente complementar  con otros datos de otras redes Sociales…

Ojo tenemos que tener en la misma carpeta los siguientes códigos, para que el código que vamos a estudiar funcione, primero creamos el archivo twurl.py, este programa es una conexión a la API de Twitter llamando a la pagina con parámetros interesantes:



import urllib
import oauth
import hidden

def augment(url, parameters) :
    secrets = hidden.oauth()
    consumer = oauth.OAuthConsumer(secrets['consumer_key'], secrets['consumer_secret'])
    token = oauth.OAuthToken(secrets['token_key'],secrets['token_secret'])

    oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, 
        token=token, http_method='GET', http_url=url, parameters=parameters)
    oauth_request.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(), consumer, token)
    return oauth_request.to_url()


def test_me() :
    print '* Calling Twitter...'
    url = augment('https://api.twitter.com/1.1/statuses/user_timeline.json',
        {'screen_name': 'drchuck', 'count': '2'} )
    print url
    connection = urllib.urlopen(url)
    data = connection.read()
    print data
    headers = connection.info().dict
    print headers
      

También necesitamos un archivo para manejar las claves llamado oauth.py:


"""
The MIT License

Copyright (c) 2007 Leah Culver

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""

import cgi
import urllib
import time
import random
import urlparse
import hmac
import binascii


VERSION = '1.0' # Hi Blaine!
HTTP_METHOD = 'GET'
SIGNATURE_METHOD = 'PLAINTEXT'


class OAuthError(RuntimeError):
    """Generic exception class."""
    def __init__(self, message='OAuth error occured.'):
        self.mymessage = message

def build_authenticate_header(realm=''):
    """Optional WWW-Authenticate header (401 error)"""
    return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}

def escape(s):
    """Escape a URL including any /."""
    return urllib.quote(s, safe='~')

def _utf8_str(s):
    """Convert unicode to utf-8."""
    if isinstance(s, unicode):
        return s.encode("utf-8")
    else:
        return str(s)

def generate_timestamp():
    """Get seconds since epoch (UTC)."""
    return int(time.time())

def generate_nonce(length=8):
    """Generate pseudorandom number."""
    return ''.join([str(random.randint(0, 9)) for i in range(length)])


class OAuthConsumer(object):
    """Consumer of OAuth authentication.

    OAuthConsumer is a data type that represents the identity of the Consumer
    via its shared secret with the Service Provider.

    """
    key = None
    secret = None

    def __init__(self, key, secret):
        self.key = key
        self.secret = secret

   
class OAuthToken(object):
    """OAuthToken is a data type that represents an End User via either an access
    or request token.
    
    key -- the token
    secret -- the token secret

    """
    key = None
    secret = None

    def __init__(self, key, secret):
        self.key = key
        self.secret = secret

    def to_string(self):
        return urllib.urlencode({'oauth_token': self.key,
            'oauth_token_secret': self.secret})
 
    def from_string(s):
        """ Returns a token from something like:
        oauth_token_secret=xxx&oauth_token=xxx
        """
        params = cgi.parse_qs(s, keep_blank_values=False)
        key = params['oauth_token'][0]
        secret = params['oauth_token_secret'][0]
        return OAuthToken(key, secret)
    from_string = staticmethod(from_string)

    def __str__(self):
        return self.to_string()


class OAuthRequest(object):
    """OAuthRequest represents the request and can be serialized.

    OAuth parameters:
        - oauth_consumer_key 
        - oauth_token
        - oauth_signature_method
        - oauth_signature 
        - oauth_timestamp 
        - oauth_nonce
        - oauth_version
        ... any additional parameters, as defined by the Service Provider.
    """
    parameters = None # OAuth parameters.
    http_method = HTTP_METHOD
    http_url = None
    version = VERSION

    def __init__(self, http_method=HTTP_METHOD, http_url=None, parameters=None):
        self.http_method = http_method
        self.http_url = http_url
        self.parameters = parameters or {}

    def set_parameter(self, parameter, value):
        self.parameters[parameter] = value

    def get_parameter(self, parameter):
        try:
            return self.parameters[parameter]
        except:
            if parameter == "oauth_token" : return None
            raise OAuthError('Parameter not found: %s' % parameter)

    def _get_timestamp_nonce(self):
        return self.get_parameter('oauth_timestamp'), self.get_parameter(
            'oauth_nonce')

    def get_nonoauth_parameters(self):
        """Get any non-OAuth parameters."""
        parameters = {}
        for k, v in self.parameters.iteritems():
            # Ignore oauth parameters.
            if k.find('oauth_') < 0: parameters[k] = v return parameters def to_header(self, realm=''): """Serialize as a header for an HTTPAuth request.""" auth_header = 'OAuth realm="%s"' % realm # Add the oauth parameters. if self.parameters: for k, v in self.parameters.iteritems(): if k[:6] == 'oauth_': auth_header += ', %s="%s"' % (k, escape(str(v))) return {'Authorization': auth_header} def to_postdata(self): """Serialize as post data for a POST request.""" return '&'.join(['%s=%s' % (escape(str(k)), escape(str(v))) \ for k, v in self.parameters.iteritems()]) def to_url(self): """Serialize as a URL for a GET request.""" return '%s?%s' % (self.get_normalized_http_url(), self.to_postdata()) def get_normalized_parameters(self): """Return a string that contains the parameters that must be signed.""" # Chuck - Make a copy of the parameters so we can modify them params = dict(self.parameters) try: # Exclude the signature if it exists. del params['oauth_signature'] except: pass # Escape key values before sorting. key_values = [(escape(_utf8_str(k)), escape(_utf8_str(v))) \ for k,v in params.items()] # Sort lexicographically, first after key, then after value. key_values.sort() # Combine key value pairs into a string. return '&'.join(['%s=%s' % (k, v) for k, v in key_values]) def get_normalized_http_method(self): """Uppercases the http method.""" return self.http_method.upper() def get_normalized_http_url(self): """Parses the URL and rebuilds it to be scheme://host/path.""" parts = urlparse.urlparse(self.http_url) scheme, netloc, path = parts[:3] # Exclude default port numbers. if scheme == 'http' and netloc[-3:] == ':80': netloc = netloc[:-3] elif scheme == 'https' and netloc[-4:] == ':443': netloc = netloc[:-4] return '%s://%s%s' % (scheme, netloc, path) def sign_request(self, signature_method, consumer, token): """Set the signature parameter to the result of build_signature.""" # Set the signature method. self.set_parameter('oauth_signature_method', signature_method.get_name()) # Set the signature. self.set_parameter('oauth_signature', self.build_signature(signature_method, consumer, token)) def build_signature(self, signature_method, consumer, token): """Calls the build signature method within the signature method.""" return signature_method.build_signature(self, consumer, token) def from_request(http_method, http_url, headers=None, parameters=None, query_string=None): """Combines multiple parameter sources.""" if parameters is None: parameters = {} # Headers if headers and 'Authorization' in headers: auth_header = headers['Authorization'] # Check that the authorization header is OAuth. if auth_header.index('OAuth') > -1:
                auth_header = auth_header.lstrip('OAuth ')
                try:
                    # Get the parameters from the header.
                    header_params = OAuthRequest._split_header(auth_header)
                    parameters.update(header_params)
                except:
                    raise OAuthError('Unable to parse OAuth parameters from '
                        'Authorization header.')

        # GET or POST query string.
        if query_string:
            query_params = OAuthRequest._split_url_string(query_string)
            parameters.update(query_params)

        # URL parameters.
        param_str = urlparse.urlparse(http_url)[4] # query
        url_params = OAuthRequest._split_url_string(param_str)
        parameters.update(url_params)

        if parameters:
            return OAuthRequest(http_method, http_url, parameters)

        return None
    from_request = staticmethod(from_request)

    def from_consumer_and_token(oauth_consumer, token=None,
            http_method=HTTP_METHOD, http_url=None, parameters=None):
        if not parameters:
            parameters = {}

        defaults = {
            'oauth_consumer_key': oauth_consumer.key,
            'oauth_timestamp': generate_timestamp(),
            'oauth_nonce': generate_nonce(),
            'oauth_version': OAuthRequest.version,
        }

        defaults.update(parameters)
        parameters = defaults

        if token:
            parameters['oauth_token'] = token.key

        return OAuthRequest(http_method, http_url, parameters)
    from_consumer_and_token = staticmethod(from_consumer_and_token)

    def from_token_and_callback(token, callback=None, http_method=HTTP_METHOD,
            http_url=None, parameters=None):
        if not parameters:
            parameters = {}

        parameters['oauth_token'] = token.key

        if callback:
            parameters['oauth_callback'] = callback

        return OAuthRequest(http_method, http_url, parameters)
    from_token_and_callback = staticmethod(from_token_and_callback)

    def _split_header(header):
        """Turn Authorization: header into parameters."""
        params = {}
        parts = header.split(',')
        for param in parts:
            # Ignore realm parameter.
            if param.find('realm') > -1:
                continue
            # Remove whitespace.
            param = param.strip()
            # Split key-value.
            param_parts = param.split('=', 1)
            # Remove quotes and unescape the value.
            params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"'))
        return params
    _split_header = staticmethod(_split_header)

    def _split_url_string(param_str):
        """Turn URL string into parameters."""
        parameters = cgi.parse_qs(param_str, keep_blank_values=False)
        for k, v in parameters.iteritems():
            parameters[k] = urllib.unquote(v[0])
        return parameters
    _split_url_string = staticmethod(_split_url_string)

class OAuthServer(object):
    """A worker to check the validity of a request against a data store."""
    timestamp_threshold = 300 # In seconds, five minutes.
    version = VERSION
    signature_methods = None
    data_store = None

    def __init__(self, data_store=None, signature_methods=None):
        self.data_store = data_store
        self.signature_methods = signature_methods or {}

    def set_data_store(self, data_store):
        self.data_store = data_store

    def get_data_store(self):
        return self.data_store

    def add_signature_method(self, signature_method):
        self.signature_methods[signature_method.get_name()] = signature_method
        return self.signature_methods

    def fetch_request_token(self, oauth_request):
        """Processes a request_token request and returns the
        request token on success.
        """
        try:
            # Get the request token for authorization.
            token = self._get_token(oauth_request, 'request')
        except OAuthError:
            # No token required for the initial token request.
            version = self._get_version(oauth_request)
            consumer = self._get_consumer(oauth_request)
            self._check_signature(oauth_request, consumer, None)
            # Fetch a new token.
            token = self.data_store.fetch_request_token(consumer)
        return token

    def fetch_access_token(self, oauth_request):
        """Processes an access_token request and returns the
        access token on success.
        """
        version = self._get_version(oauth_request)
        consumer = self._get_consumer(oauth_request)
        # Get the request token.
        token = self._get_token(oauth_request, 'request')
        self._check_signature(oauth_request, consumer, token)
        new_token = self.data_store.fetch_access_token(consumer, token)
        return new_token

    def verify_request(self, oauth_request):
        """Verifies an api call and checks all the parameters."""
        # -> consumer and token
        version = self._get_version(oauth_request)
        consumer = self._get_consumer(oauth_request)
        # Get the access token.
        token = self._get_token(oauth_request, 'access')
        self._check_signature(oauth_request, consumer, token)
        parameters = oauth_request.get_nonoauth_parameters()
        return consumer, token, parameters

    def authorize_token(self, token, user):
        """Authorize a request token."""
        return self.data_store.authorize_request_token(token, user)

    def get_callback(self, oauth_request):
        """Get the callback URL."""
        return oauth_request.get_parameter('oauth_callback')
 
    def build_authenticate_header(self, realm=''):
        """Optional support for the authenticate header."""
        return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}

    def _get_version(self, oauth_request):
        """Verify the correct version request for this server."""
        try:
            version = oauth_request.get_parameter('oauth_version')
        except:
            version = VERSION
        if version and version != self.version:
            raise OAuthError('OAuth version %s not supported.' % str(version))
        return version

    def _get_signature_method(self, oauth_request):
        """Figure out the signature with some defaults."""
        try:
            signature_method = oauth_request.get_parameter(
                'oauth_signature_method')
        except:
            signature_method = SIGNATURE_METHOD
        try:
            # Get the signature method object.
            signature_method = self.signature_methods[signature_method]
        except:
            signature_method_names = ', '.join(self.signature_methods.keys())
            raise OAuthError('Signature method %s not supported try one of the '
                'following: %s' % (signature_method, signature_method_names))

        return signature_method

    def _get_consumer(self, oauth_request):
        consumer_key = oauth_request.get_parameter('oauth_consumer_key')
        consumer = self.data_store.lookup_consumer(consumer_key)
        if not consumer:
            raise OAuthError('Invalid consumer.')
        return consumer

    def _get_token(self, oauth_request, token_type='access'):
        """Try to find the token for the provided request token key."""
        token_field = oauth_request.get_parameter('oauth_token')
        token = self.data_store.lookup_token(token_type, token_field)
        if not token:
            raise OAuthError('Invalid %s token: %s' % (token_type, token_field))
        return token

    def _check_signature(self, oauth_request, consumer, token):
        timestamp, nonce = oauth_request._get_timestamp_nonce()
        self._check_timestamp(timestamp)
        self._check_nonce(consumer, token, nonce)
        signature_method = self._get_signature_method(oauth_request)
        try:
            signature = oauth_request.get_parameter('oauth_signature')
        except:
            raise OAuthError('Missing signature.')
        # Validate the signature.
        valid_sig = signature_method.check_signature(oauth_request, consumer,
            token, signature)
        if not valid_sig:
            key, base = signature_method.build_signature_base_string(
                oauth_request, consumer, token)
            raise OAuthError('Invalid signature. Expected signature base '
                'string: %s' % base)
        built = signature_method.build_signature(oauth_request, consumer, token)

    def _check_timestamp(self, timestamp):
        """Verify that timestamp is recentish."""
        timestamp = int(timestamp)
        now = int(time.time())
        lapsed = now - timestamp
        if lapsed > self.timestamp_threshold:
            raise OAuthError('Expired timestamp: given %d and now %s has a '
                'greater difference than threshold %d' %
                (timestamp, now, self.timestamp_threshold))

    def _check_nonce(self, consumer, token, nonce):
        """Verify that the nonce is uniqueish."""
        nonce = self.data_store.lookup_nonce(consumer, token, nonce)
        if nonce:
            raise OAuthError('Nonce already used: %s' % str(nonce))


class OAuthClient(object):
    """OAuthClient is a worker to attempt to execute a request."""
    consumer = None
    token = None

    def __init__(self, oauth_consumer, oauth_token):
        self.consumer = oauth_consumer
        self.token = oauth_token

    def get_consumer(self):
        return self.consumer

    def get_token(self):
        return self.token

    def fetch_request_token(self, oauth_request):
        """-> OAuthToken."""
        raise NotImplementedError

    def fetch_access_token(self, oauth_request):
        """-> OAuthToken."""
        raise NotImplementedError

    def access_resource(self, oauth_request):
        """-> Some protected resource."""
        raise NotImplementedError


class OAuthDataStore(object):
    """A database abstraction used to lookup consumers and tokens."""

    def lookup_consumer(self, key):
        """-> OAuthConsumer."""
        raise NotImplementedError

    def lookup_token(self, oauth_consumer, token_type, token_token):
        """-> OAuthToken."""
        raise NotImplementedError

    def lookup_nonce(self, oauth_consumer, oauth_token, nonce):
        """-> OAuthToken."""
        raise NotImplementedError

    def fetch_request_token(self, oauth_consumer):
        """-> OAuthToken."""
        raise NotImplementedError

    def fetch_access_token(self, oauth_consumer, oauth_token):
        """-> OAuthToken."""
        raise NotImplementedError

    def authorize_request_token(self, oauth_token, user):
        """-> OAuthToken."""
        raise NotImplementedError


class OAuthSignatureMethod(object):
    """A strategy class that implements a signature method."""
    def get_name(self):
        """-> str."""
        raise NotImplementedError

    def build_signature_base_string(self, oauth_request, oauth_consumer, oauth_token):
        """-> str key, str raw."""
        raise NotImplementedError

    def build_signature(self, oauth_request, oauth_consumer, oauth_token):
        """-> str."""
        raise NotImplementedError

    def check_signature(self, oauth_request, consumer, token, signature):
        built = self.build_signature(oauth_request, consumer, token)
        return built == signature


class OAuthSignatureMethod_HMAC_SHA1(OAuthSignatureMethod):

    def get_name(self):
        return 'HMAC-SHA1'
        
    def build_signature_base_string(self, oauth_request, consumer, token):
        sig = (
            escape(oauth_request.get_normalized_http_method()),
            escape(oauth_request.get_normalized_http_url()),
            escape(oauth_request.get_normalized_parameters()),
        )

        key = '%s&' % escape(consumer.secret)
        if token and token.secret:
            key += escape(token.secret)
        raw = '&'.join(sig)
        return key, raw

    def build_signature(self, oauth_request, consumer, token):
        """Builds the base signature string."""
        key, raw = self.build_signature_base_string(oauth_request, consumer,
            token)

        # HMAC object.
        try:
            import hashlib # 2.5
            hashed = hmac.new(key, raw, hashlib.sha1)
        except:
            import sha # Deprecated
            hashed = hmac.new(key, raw, sha)

        # Calculate the digest base 64.
        return binascii.b2a_base64(hashed.digest())[:-1]


class OAuthSignatureMethod_PLAINTEXT(OAuthSignatureMethod):

    def get_name(self):
        return 'PLAINTEXT'

    def build_signature_base_string(self, oauth_request, consumer, token):
        """Concatenates the consumer key and secret."""
        sig = '%s&' % escape(consumer.secret)
        if token:
            sig = sig + escape(token.secret)
        return sig, sig

    def build_signature(self, oauth_request, consumer, token):
        key, raw = self.build_signature_base_string(oauth_request, consumer,
            token)
        return key


      

Y hemos creado un archivo donde vamos a guardar todas nuestras llaves llamado hidden.py:

# Keep this file separate

def oauth() :
    return { "consumer_key" : "Coloca tus datos aqui",
        "consumer_secret" : "Coloca tus datos aqui",
        "token_key" : "Coloca tus datos aqui",
        "token_secret" : "Coloca tus datos aqui" }

En esta entrada voy a seguir trabajando con uno de los ejemplos del curso(ojo no son los ejercicios propuestos), en el siguiente código tenemos un programa muy pero muy limpio que con algunos detalles podría ser una excelente base para una aplicación completa, este es el programa:

import urllib, twurl, json, sqlite3


TWITER_URL = 'https://api.twitter.com/1.1/friends/list.json'


conn = sqlite3.connect('amigos.sqlite3')

cur = conn.cursor()

cur.execute('''CREATE TABLE IF NOT EXISTS Personas (id INTEGER PRIMARY KEY, nombre TEXT UNIQUE, recuperado INTEGER)''')
cur.execute('''CREATE TABLE IF NOT EXISTS Seguimientos (desde_id INTEGER, hacia_id INTEGER, UNIQUE(desde_id,hacia_id))''')

while True:
  
    cuenta = raw_input('Introduzca una cuenta de Twitter, o salir: ')
  
    if (cuenta == 'salir') : break

    if (len (cuenta) < 1):
    
        cur.execute('''SELECT id, nombre FROM Personas WHERE recuperado = 0 LIMIT 1''')
        try:
            (id, cuenta) = cur.fetchone()
        except:
            print "No se hab encontrado cuentas de Twitter sin recuperar"
      
            continue
    else:
        cur.execute('SELECT id FROM Personas WHERE nombre = ? LIMIT 1', (cuenta, ))
    
        try:
      
            id = cur.fetchone()[0]
      
        except:
      
            cur.execute('''INSERT OR IGNORE INTO Personas (nombre, recuperado) VALUES (?,0) ''', (cuenta, ))
            conn.commit()
      
            if cur.rowcount != 1 :
                print "Error insertando cuenta: ", cuenta
	
                continue
      
            id = cur.lastrowid
      
    url = twurl.augment(TWITER_URL, {'screen_name': cuenta, 'count': '20'})
  
    print "Recuperando cuenta: " , cuenta
  
    conexion = urllib.urlopen(url)
  
    datos = conexion.read()
  
    cabeceras = conexion.info().dict
  
    print "Restantes" , cabeceras['x-rate-limit-remaining']
  
    js = json.loads(datos)
  
    # print json.dumps(js.indent=4)
  
    cur.execute('UPDATE Personas SET recuperado=1 WHERE nombre = ?', (cuenta, ))
  
    contnuevas = 0
  
    contantiguas = 0
  
    for u in js['users']:
    
        amigo = u['screen_name']
    
        print amigo
    
        cur.execute('SELECT id FROM Personas WHERE nombre = ? LIMIT 1', (amigo, ))
        try:
            
            amigo_id = cur.fetchone()[0]
     
            contantiguas = contantiguas + 1
     
        except:
     
            cur.execute('''INSERT OR IGNORE INTO Personas (nombre, recuperado) VALUES (?,0)''', (amigo, ))
            conn.commit()
     
            if cur.rowcount != 1:
                print 'Error al insertar cuenta:', amigo
                continue
            amigo_id = cur.lastrowid
     
            contnuevas = contnuevas + 1
        cur.execute('''INSERT OR IGNORE INTO Seguimientos (desde_id, hacia_id) VALUES(?,?)''', (id, amigo_id))
    print 'Cuentas nuevas= ', contnuevas,' ya visitadas=', contantiguas
    
    conn.commit()
cur.close()
      
      

Como podemos observar y gracias  a python, al leer por encima el codigo vemos varios bloques interesantes y es de estos bloques que nos vamos a ocupar en esta entrada, para comenzar el bloque 1 de interés

import urllib, twurl, json, sqlite3


TWITER_URL = 'https://api.twitter.com/1.1/friends/list.json'


conn = sqlite3.connect('amigos.sqlite3')

cur = conn.cursor()

cur.execute('''CREATE TABLE IF NOT EXISTS Personas (id INTEGER PRIMARY KEY, nombre TEXT UNIQUE, recuperado INTEGER)''')
cur.execute('''CREATE TABLE IF NOT EXISTS Seguimientos (desde_id INTEGER, hacia_id INTEGER, UNIQUE(desde_id,hacia_id))''')
      

 Las primeras lineas no necesitan muchos comentarios, primero importamos las librerías necesarias , nos conectamos al API específicamente a Friends y creamos la base de datos  (‘amigos.sqlite3’), luego creamos la tabla personas y creamos la tabla seguimientos, hasta aquí todo muy sencillo….

Luego tenemos un bucle while desde la linea 15 hasta la 99, no te asustes, el código no es tan complejo y básicamente tenemos 2 bloques que vamos a comentar un poco, por ejemplo tenemos este:


 cuenta = raw_input('Introduzca una cuenta de Twitter, o salir: ')
 
 if (cuenta == 'salir') : break

 if (len (cuenta) < 1):
 
 cur.execute('''SELECT id, nombre FROM Personas WHERE recuperado = 0 LIMIT 1''')
 try:
 (id, cuenta) = cur.fetchone()
 except:
 print "No se han encontrado cuentas de Twitter sin recuperar"
 
 continue
 else:
 cur.execute('SELECT id FROM Personas WHERE nombre = ? LIMIT 1', (cuenta, ))
 
 try:
 
 id = cur.fetchone()[0]
 
 except:
 
 cur.execute('''INSERT OR IGNORE INTO Personas (nombre, recuperado) VALUES (?,0) ''', (cuenta, ))
 conn.commit()
 
 if cur.rowcount != 1 :
 print "Error insertando cuenta: ", cuenta
 
 continue
 
 id = cur.lastrowid
 
      

En este bloque tenemos 2 cosas importantes, en primer lugar debemos colocar el nombre de la cuenta que queremos minar, y luego tenemos 1 condicional si el nombre de la cuenta es salir hasta aquí llega el código y se sale, pero si agregamos una cuenta así no exista el código crea un nombre en la base de datos si no existe y la ignora si ya existe, la parte mas importante es el bloque else donde si no se escribe un nombre para cuenta el código toma al siguiente nombre y crea un nombre en la base de datos y se ejecuta como si nosotros lo hubiéramos agregado manualmente…

El siguiente Bloque de código no es menos interesante, y trata sobre la conexión y recolección de los datos de la API en primer lugar, es este bloque:


      
    url = twurl.augment(TWITER_URL, {'screen_name': cuenta, 'count': '20'})
  
    print "Recuperando cuenta: " , cuenta
  
    conexion = urllib.urlopen(url)
  
    datos = conexion.read()
  
    cabeceras = conexion.info().dict
  
    print "Restantes" , cabeceras['x-rate-limit-remaining']
  
    js = json.loads(datos)
  
    # print json.dumps(js.indent=4)
  
    cur.execute('UPDATE Personas SET recuperado=1 WHERE nombre = ?', (cuenta, ))
  
    contnuevas = 0
  
    contantiguas = 0
  
    for u in js['users']:
    
        amigo = u['screen_name']
    
        print amigo
    
        cur.execute('SELECT id FROM Personas WHERE nombre = ? LIMIT 1', (amigo, ))
        try:
            
            amigo_id = cur.fetchone()[0]
     
            contantiguas = contantiguas + 1
     
        except:
     
            cur.execute('''INSERT OR IGNORE INTO Personas (nombre, recuperado) VALUES (?,0)''', (amigo, ))
            conn.commit()
     
            if cur.rowcount != 1:
                print 'Error al insertar cuenta:', amigo
                continue
            amigo_id = cur.lastrowid
     
            contnuevas = contnuevas + 1
        cur.execute('''INSERT OR IGNORE INTO Seguimientos (desde_id, hacia_id) VALUES(?,?)''', (id, amigo_id))
    print 'Cuentas nuevas= ', contnuevas,' ya visitadas=', contantiguas
    
    conn.commit()
cur.close()
 
      

 Como dije anteriormente nos conectamos a la URL  y sacamos hasta 20 seguidores de la cuenta, podemos notar screen_name que es el nombre de la cuenta y count, url genera la pagina a la que nos vamos a conectar con screen_name, luego se hace la conexión se sacan las cabeceras como un diccionario, veamoslo así obtenemos los datos de la url se los pasamos a cabeceras como un diccionario solo para revisar cuantas peticiones a la api nos quedan, luego cargamos datos de JSON con load, actualizamos la cuenta en nuestra base de datos, luego iniciamos un bucle for para buscar los datos de nuestros amigos y vamos obteniendo sus nombres, luego tenemos el guardián para contar los seguidores e insertar o ignorar los nombres recuperados…. Luego agregamos la tabla donde tenemos quien sigue a quien para tener llaves foraneas para futuros ejercicios….

De verdad a mi me ha  gustado mucho hasta ahora la Especializacion en Python de Coursera, y me esta gustando Machine Learning con Python, pero espero Dios me de tiempo mas adelante para dedicarme de lleno… Esto de las API es excelente para aprender mas y mas de python por que son codigos muy sencillos y con aplicaciones practicas… hasta la próxima y Dios les Bendiga

Jugando con la API de Twitter [Parte 3.1]

Bueno les explico el por que del 3.1, simple en la entrada anterior escribí basándome en los ejemplos del Libro Mining_the_Social_WEB, Ya tenia planeado usar los ejemplos del libro Python_para_Informáticos que es el libro de versión español para los estudiantes de la Especialización en Python, Explicare mejor el por que me gustan mas los ejemplos de la especialización pero por que no quiero dejar de lado los ejemplos  de Mining_the_Social_WEB, primero por que los ejercicios de la especialización son mas prácticos y ademas son mas sencillos de entender, los hacen como un alumno los haría si comprende la clase, pero los de Mining_the_Social_WEB son mas profundos por que usan al máximo el como usar python, para mi son mas engorrosos por eso les presento los 2, claro con los de Python_para_Informáticos obtendremos mejores resultados y creo deberían ser la base para los códigos finales que vamos a usar….

Ojo que hay un problema no he entrado de lleno en el código del libro Python_para_Informáticos por que cuando ejecutamos si tenemos instalado las librerías de pip me da un error y entonces hay que eliminar el código de python-twitter o pytwitter e instalarlo con pip como super usuario y ahora si funciona el código, no he estudiado el código para hacer la mejora respectiva si se puede, pero no vamos a caer en estos problemas por 100kb de código y yo por ejemplo voy a des-instalar e instalar cada vez q lo necesite. Para que el código que vamos a utilizar funcione vamos a des-instalar e instalar así:

 
pip uninstall twitter

Nos sale algo como esto:

 
Uninstalling twitter:
 /usr/local/bin/twitter 
 /usr/local/bin/twitter-archiver 
 /usr/local/bin/twitter-follow 
 /usr/local/bin/twitter-log 
 /usr/local/bin/twitter-stream-example 
 /usr/local/bin/twitterbot 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/DESCRIPTION.rst 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/METADATA 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/RECORD 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/WHEEL 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/entry_points.txt 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/pydist.json 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/top_level.txt 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/zip-safe 
 /usr/local/lib/python2.7/dist-packages/twitter/__init__.py 
 /usr/local/lib/python2.7/dist-packages/twitter/__init__.pyc 
 /usr/local/lib/python2.7/dist-packages/twitter/ansi.py 
 /usr/local/lib/python2.7/dist-packages/twitter/ansi.pyc 
 /usr/local/lib/python2.7/dist-packages/twitter/api.py 
 /usr/local/lib/python2.7/dist-packages/twitter/api.pyc 
 /usr/local/lib/python2.7/dist-packages/twitter/archiver.py 
 /usr/local/lib/python2.7/dist-packages/twitter/archiver.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/auth.py
 /usr/local/lib/python2.7/dist-packages/twitter/auth.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/cmdline.py
 /usr/local/lib/python2.7/dist-packages/twitter/cmdline.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/follow.py
 /usr/local/lib/python2.7/dist-packages/twitter/follow.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/ircbot.py
 /usr/local/lib/python2.7/dist-packages/twitter/ircbot.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/logger.py
 /usr/local/lib/python2.7/dist-packages/twitter/logger.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/oauth.py
 /usr/local/lib/python2.7/dist-packages/twitter/oauth.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/oauth2.py
 /usr/local/lib/python2.7/dist-packages/twitter/oauth2.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/oauth_dance.py
 /usr/local/lib/python2.7/dist-packages/twitter/oauth_dance.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/stream.py
 /usr/local/lib/python2.7/dist-packages/twitter/stream.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/stream_example.py
 /usr/local/lib/python2.7/dist-packages/twitter/stream_example.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/timezones.py
 /usr/local/lib/python2.7/dist-packages/twitter/timezones.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/twitter_globals.py
 /usr/local/lib/python2.7/dist-packages/twitter/twitter_globals.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/util.py
 /usr/local/lib/python2.7/dist-packages/twitter/util.pyc
Proceed (y/n)? y

Le damos que Si o «y», y ya esta listo, ahora instalamos python-twitter:

pip install python-twitter

 

Ahora vamos a probar el programa con el siguiente código para que veamos lo que podemos hacer con un código mas sencillo 😀 :

import twitter

# Datos de autenticacion
CONSUMER_KEY = 'Datos de A'

CONSUMER_SECRET = 'Datos de B'

OAUTH_TOKEN = 'Datos de C'

OAUTH_SECRET = 'Datos de D'

# Conexion a la API
api = twitter.Api(consumer_key=CONSUMER_KEY,
           consumer_secret=CONSUMER_SECRET,
           access_token_key=OAUTH_TOKEN,
           access_token_secret=OAUTH_SECRET);

# Procedimiento para mostrar los datos de cada amigo seguido en Twitter. 
def GetFriendsInformation(user, api):
   # Obtenemos el listado de de amigos del usuario pasado
   TwitterFriends = api.GetFriends(screen_name=user);
   # Por cada amigo vamos a mostrar la informacion que desemos
   for Friends in TwitterFriends:
      # Nombre mostrados
      print 'Amigo ' + Friends.screen_name;
      # Localizacion
      print '\t Localizacion: ' + Friends.location;
      # Numero de seguidores
      print '\t Numero de seguidores: ' + str(Friends.followers_count);
      # Numero de amigos
      print '\t Numero de amigos: ' + str(Friends.friends_count);
      # Numero de tweets enviados
      print '\t Numero de tweets enviados: ' + str(Friends.statuses_count);

# Llamada al procedimiento para obtener los datos del usuario yorio
# Sustituir el usuario por el vuestro o cualquiera que querais analizar.
GetFriendsInformation('yorio', api);

La salida del programa es:

Amigo GoyaFoods
 Localizacion: 
 Numero de seguidores: 5406
 Numero de amigos: 1954
 Numero de tweets enviados: 6169
Amigo Number2Creative
 Localizacion: New York, NY
 Numero de seguidores: 168
 Numero de amigos: 200
 Numero de tweets enviados: 376
Amigo buzzedhostess
 Localizacion: Hoboken, NJ
 Numero de seguidores: 194
 Numero de amigos: 230
 Numero de tweets enviados: 156
Amigo christinleigh22
 Localizacion: 
 Numero de seguidores: 15
 Numero de amigos: 76
 Numero de tweets enviados: 8

Podemos ver alguna información interesante pero ojo que podemos ir a la API de twitter o a la salida de uno de los primeros códigos que escribimos y podemos obtener datos que antes no se dejaban leer y veríamos datos mas interesantes, por ejemplo el dato de localización lo podríamos usar, mas adelante les diré para que 😀

Este sencillo código te dará información muy interesante de los amigo o a quienes esta siguiendo yorio, podemos probar con vladimirala1 y otros, es muy interesante la información obtenida, mañana voy a agregar mas código y sacaremos mas información ademas vamos a ver algunas rutinas de nuestro programa realmente importante donde agregaremos los datos a una BD y el programa verificara si hemos agregado ya el usuario a estudiar  y si no es así llamar a twitter y agregarlo y si no ingresamos nada podremos estudiar a los amigos de los amigo o a seguidores de seguidores 😀

Saludos Dios les Bendiga, comentar es agradecer

 

Jugando con la API de Twitter [Parte 3]

Jugando con la API de Twitter [Parte 2]

Jugando con la API de Twitter [Parte 1]

Experiencia de La Especialización Python para toda la vida