Categorías
Python

Introducción a Python SQL Bibliotecas

 

Tabla de Contenidos

  • De la idea al MVP
  • encontrar un tema de interés
  • empezar a desarrollar
  • prueba

  • siguiente iteración
  • Añadir Frasco
  • Implementar en Heroku
  • Conclusión y próximos pasos

nuevos codificadores siempre están buscando nuevos proyectos -, así que debe ser! No sólo está haciendo su propio lado de proyecto la mejor manera de obtener experiencia práctica, pero si usted está mirando para hacer el movimiento de un hobby a una profesión, a continuación, proyectos secundarios son una gran manera de empezar a construir una cartera de trabajo .

De la idea al MVP

En este post, vamos a trabajar a través del proceso de lanzamiento de un (mínimo) MVP, desde la concepción inicial de la idea de un prototipo compartible. Al final, se le han creado su propia versión de Lyricize, una pequeña aplicación que utiliza un artista o banda de letras para generar “nuevas” letras con sonidos similares basadas en probabilidades. En lugar de presentar el típico “aquí está cómo replicar todo este código” tutorial, vamos a pasar por el proceso paso a paso a mostrar lo que es en realidad involucrado en el proceso de pensamiento y la creación en el camino.

Tenga en cuenta que esto no es necesariamente sobre la construcción de la próxima puesta en marcha del asesino; sólo estamos tratando de encontrar un proyecto que puede ser 1) una oportunidad de aprendizaje divertido y 2) se pueda compartir con los demás.

antes de empezar a echar un vistazo a la aplicación de ejemplo para ver lo que va a crear. En esencia, se puede generar nuevas letras en base a las letras de un artista en particular utilizando cadenas de Markov. Por ejemplo, trate de buscar “Bob Dylan” y cambiar el número de líneas a tres. Muy bueno, ¿verdad? Yo sólo ejecuta la misma búsqueda, lo que resultó en:

Allá está su promesa todos y barcos Estoy listo para la garganta Soy un gancho

Tan profundo I. De todos modos, vamos a empezar …

Encontrar un tema de interés

Así, paso 1: Encontrar un tema que usted está interesado en aprender más acerca de. La siguiente aplicación se inspiró en un antiguo trabajo de universidad (la verdad no es la fuente más común de inspiración) que utiliza cadenas de Markov para generar texto “de aspecto real” dado un cuerpo de texto de ejemplo. modelos de Markov surgen en todo tipo de escenarios. (Vamos a bucear en lo que es un modelo de Markov es breve.) Me encontré con la idea de generación de texto basado en probabilidades particularmente interesante; en concreto, me preguntaba qué pasaría si utilizó letras de canciones como texto de ejemplo para generar “nuevas” letras …

a Internet! Una búsqueda rápida en la web muestra algunos sitios generadores basados ​​en la lírica de Markov, pero nada como lo que tengo en mente. Además, el código de tapar lejos en la otra persona esté terminado no es una forma muy efectiva de aprender cómo funcionan realmente los generadores de Markov; Vamos a construir nuestra propia.

Así que … ¿cómo generadores de Markov obras? Básicamente, una cadena de Markov se genera de algún texto basado en la frecuencia de ciertos patrones que ocurren. Como ejemplo, considere la siguiente cadena como nuestro texto de muestra:

bobby

vamos a construir el modelo de Markov más simple posible salir de este texto, que es un modelo de Markov de orden 0 , como una manera de predecir la probabilidad de cualquier particular, el escrito que se produzcan. Esta es una tabla de frecuencias recta de avance:

b: 3/5
o: 1/5
y: 1/5

Sin embargo, este es un modelo de lenguaje bastante malo; además de con qué frecuencia se producen las letras en general, también queremos mirar a la frecuencia con una carta particular se produce da la carta anterior . Ya que estamos en función de una carta anterior, este es un modelo de Markov de orden 1:

given "b":
"b" is next: 1/3
"o" is next: 1/3
"y" is next: 1/3
given "o":
"b" is next: 1
given "y":
[terminates]: 1

A partir de aquí, se puede imaginar modelos de Markov de orden superior; un modelo de orden 2 comenzaría mediante la medición de la frecuencia de cada carta que se produce después de las dos letras de cadena “bo”, etc. Al aumentar el orden, obtenemos un modelo que empieza a buscar más como lenguaje real; por ejemplo, un modelo de Markov para 5 que se había dado un montón de entrada de la muestra, incluyendo la palabra “pitón” sería muy probable que siga la cadena “Pitón” con una “n”, mientras que un modelo de orden menor cantidad posible que haya llegado con algunas palabras creativas.

empezar a desarrollar

¿Cómo podemos ir construyendo una aproximación de un modelo de Markov? En esencia, la estructura que hemos esbozado más arriba con los modelos de orden superior es un diccionario de diccionarios. Se podría imaginar un diccionario modelo con varios fragmentos de palabras (es decir, “Bo”) como llaves. Cada uno de estos fragmentos entonces señalar a un diccionario a su vez, con esos diccionarios interiores que sostiene los próximos letras individuales ( “Y”) como claves con sus respectivas frecuencias como valores. inicio de

Let haciendo un método generateModel () que toma en un texto de muestra y un modelo de Markov, a continuación, devuelve este diccionario de diccionarios:

def generateModel(text, order):
model = {}
for i in range(0, len(text) - order):
fragment = text[i:i+order]
next_letter = text[i+order]
if fragment not in model:
model[fragment] = {}
if next_letter not in model[fragment]:
model[fragment][next_letter] = 1
else:
model[fragment][next_letter] += 1
return model

Nos bucle a través de todo el texto disponible, subiendo hasta el último disponible completa fragmento + siguiente letra para que no se corra el final de la cadena, añadiendo nuestros diccionarios fragmento al modelo con cada fragmento de la celebración de un diccionario de frecuencias totales next_letter.

Copiar esta función en un terminal de Python y probarlo:

>>> generateModel("bobby", 1)
{'b': {'y': 1, 'b': 1, 'o': 1}, 'o': {'b': 1}}

que va a hacer! Tenemos los recuentos de frecuencias en lugar de probabilidades relativas, pero podemos trabajar con eso; no hay razón por la que necesitamos para normalizar cada diccionario para agregar a las probabilidades de 100%.

Ahora vamos a utilizar este modelo en un método getNextCharacter () que, dado un modelo y un fragmento, decidir sobre una próxima letra apropiada dada probabilidades del modelo:

from random import choice
def getNextCharacter(model, fragment):
letters = []
for letter in model[fragment].keys():
for times in range(0, model[fragment][letter]):
letters.append(letter)
return choice(letters)

no es la configuración más eficiente, pero es fácil de construir y funciona por ahora. Simplemente, construimos una lista de letras, dada su total de frecuencias de ocurrencia después de que el fragmento, y elegimos al azar de esa lista.

Todo lo que queda es el uso de estos dos métodos en un tercer método que realmente generar texto de alguna longitud especificada. Para ello, tendremos que hacer un seguimiento del fragmento de texto actual que estamos construyendo mientras que la adición de nuevos personajes: Maquillaje de

def generateText(text, order, length):
model = generateModel(text, order)

currentFragment = text[0:order]
output = ""
for i in range(0, length-order):
newCharacter = getNextCharacter(model, currentFragment)
output += newCharacter
currentFragment = currentFragment[1:] + newCharacter
print output

Let esto en un script ejecutable completo que toma una orden de Markov y salida de longitud de texto como argumentos:

from random import choice
import sys

def generateModel(text, order):
model = {}
for i in range(0, len(text) - order):
fragment = text[i:i+order]
next_letter = text[i+order]
if fragment not in model:
model[fragment] = {}
if next_letter not in model[fragment]:
model[fragment][next_letter] = 1
else:
model[fragment][next_letter] += 1
return model

def getNextCharacter(model, fragment):
letters = []
for letter in model[fragment].keys():
for times in range(0, model[fragment][letter]):
letters.append(letter)
return choice(letters)

def generateText(text, order, length):
model = generateModel(text, order)
currentFragment = text[0:order]
output = ""
for i in range(0, length-order):
newCharacter = getNextCharacter(model, currentFragment)
output += newCharacter
currentFragment = currentFragment[1:] + newCharacter
print output

text = "some sample text"
if __name__ == "__main__":
generateText(text, int(sys.argv[1]), int(sys.argv[2]))

Por ahora, vamos a generar texto de la muestra a través del método muy científico de lanzar una cadena directamente en el código basado en algunas Alanis Morissette letras copiados y pegados.

prueba

Guardar el guión y darle un giro:

$ python markov.py 2 100
I wounts
You ho's humortel whime
mateend I wass
How by Lover
$ python markov.py 4 100
stress you to cosmic tears
All they've cracked you (honestly) at the filler in to like raise
$ python markov.py 6 100
tress you place the wheel from me
Please be philosophical
Please be tapped into my house

Bueno, eso era simplemente precioso. Los dos últimos ensayos son decentemente representante de sus letras (aunque la primera muestra de orden 2 se parece más a Björk). Estos resultados son alentadores suficiente para un boceto código rápido, así que vamos a darle vuelta a esto en un proyecto real.

siguiente iteración

primer obstáculo: ¿cómo vamos a automatizar conseguir un montón de letras? Una opción sería la de contenido raspadura selectivamente desde un sitio de letras, pero que suena como un gran esfuerzo para obtener resultados probablemente de baja calidad, además de una potencial zona gris legal dada la shadiness de la mayoría de los agregadores de letras y el draconianism de la industria de la música. En su lugar, vamos a ver si hay algunas APIs abiertos. De dirigirse a buscar a través de programmableweb.com, en realidad nos encontramos 14 letras diferentes APIs enumerados. Estos listados no son siempre la información más actualizada, sin embargo, así que vamos a la búsqueda a través de la más reciente en la lista.

LYRICSnMUSIC ofrece una API gratuita, REST utilizando JSON para volver hasta 150 caracteres de letras de canciones. Esto suena perfecto para nuestro caso de uso, especialmente dada la repetición de la mayoría de las canciones; no hay necesidad de recoger todas las letras cuando solo una muestra va a hacer. Ir a tomar una nueva clave para que pueda tener acceso a su API. try de

Let su API a cabo antes de decidirse por esta fuente para el bien. Sobre la base de su documentación, podemos hacer una muestra de este modo: resulta

http://api.lyricsnmusic.com/songs?api_key=[YOUR_API_KEY_HERE]&artist=coldplay

El JSON escupe de nuevo en un navegador son un poco difícil de leer; a través de ellos en un formateador para tomar una mejor visión. Parece que estamos llegando con éxito volver una lista de diccionarios basados ​​en canciones de Coldplay:

[
{
"title":"Don't Panic",
"url":"http://www.lyricsnmusic.com/coldplay/don-t-panic-lyrics/4294612",
"snippet":"Bones sinking like stones \r\nAll that we've fought for \r\nHomes, places we've grown \r\nAll of us are done for \r\n\r\nWe live in a beautiful world \r\nYeah we ...",
"context":null,
"viewable":true,
"instrumental":false,
"artist":{
"name":"Coldplay",
"url":"http://www.lyricsnmusic.com/coldplay"
}
},
{
"title":"Shiver",
"url":"http://www.lyricsnmusic.com/coldplay/shiver-lyrics/4294613",
"snippet":"So I look in your direction\r\nBut you pay me no attention, do you\r\nI know you don't listen to me\r\n'Cause you say you see straight through me, don't you...",
"context":null,
"viewable":true,
"instrumental":false,
"artist":{
"name":"Coldplay",
"url":"http://www.lyricsnmusic.com/coldplay"
}
},
...
]

No hay manera de limitar la respuesta, pero sólo está interesado en cada “snippet” proporcionado, que se ve muy bien para este proyecto.

Nuestros experimentos preliminares con generadores de Markov fueron educativa, pero nuestro modelo actual no es el más adecuado para la tarea de generar letras. Por un lado, probablemente deberíamos usar palabras individuales como nuestras fichas en lugar de tomar las cosas carácter por carácter; Es divertido intentar propio idioma maqueta, pero para la generación de falsas letras, que querrá seguir con propiedades Inglés. Esto suena más complicado, sin embargo, y hemos recorrido un largo camino para entender cómo funcionan las cadenas de Markov, que era el objetivo inicial con que el ejercicio. En este punto, se llega a un cruce de caminos: reinventar la rueda metafórica en aras de un mayor aprendizaje (que podría ser una buena práctica de codificación), o ver lo que otros más ya han creado.

Elegí la manera perezosa de ida y vuelta se dirigió a buscar las innerwebs. Un alma caritativa en GitHub ya se ha puesto en marcha una cadena de Markov basados ​​en una sola palabra básica e incluso lo ha subido a PyPI. Tomando un paseo rápido a través del código, parece que este modelo sólo es de orden 0. Esto lo suficientemente rápido, probablemente habría sido construir por nuestra cuenta, mientras que un modelo de orden superior podría ser significativamente más trabajo. Por ahora, vamos a ir con la rueda de pre-envasados ​​de otra persona; al menos un modelo de orden 0 no va a terminar sonando como Björk si estamos usando palabras completas.

Como queremos compartir fácilmente nuestra creación con amigos y familiares, tiene sentido para convertirlo en una aplicación web. Ahora, elegir un framework de desarrollo web. En lo personal, estoy con mucho el más familiarizado con Django, pero que parece un exceso aquí; después de todo, ni siquiera necesita una base de datos de los nuestros. Vamos a probar el frasco.

Añadir Frasco

por la rutina habitual, el fuego de un entorno virtual – si no lo ha hecho! Si esto no es un proceso familiar, eche un vistazo a algunos de nuestros mensajes anteriores para aprender a ponerse en marcha.

$ mkdir lyricize
$ cd lyricize
$ virtualenv --no-site-packages venv
$ source venv/bin/activate

También como de costumbre, instalar los requisitos necesarios y los echan en un archivo requirements.txt:

$ pip install PyMarkovChain flask requests
$ pip freeze > requirements.txt

Hemos añadido en la biblioteca de solicitudes, así por lo que podemos hacer peticiones web a la API de letras.

Ahora, para hacer la aplicación. En aras de la simplicidad, vamos a dividirlo en dos páginas: la página principal presentará una forma básica al usuario para elegir un nombre de artista y una serie de líneas de letras para generar, mientras que un segundo “letras” página presentarán el resultados. Vamos a empezar con una aplicación de barebones frasco llamado app.py que utiliza una plantilla index.html :

from flask import Flask, render_template

app = Flask(__name__)
app.debug = True

@app.route('/', methods=['GET'])
def index():
return render_template('index.html')

if __name__ == '__main__':
app.run()

Todo esta aplicación va a hacer hasta ahora es cargar el contenido de una plantilla index.html. Vamos a hacer que una forma básica:


Artist or band name:
Number of lines:




Guardar este index.html en una carpeta separada llamada plantillas frasco de manera que pueda encontrarlo. Aquí estamos utilizando plantillas Jinja2 del frasco para crear una lista desplegable de “selección” basado en un bucle que abarca los números del 1 al 10. Antes de añadir cualquier otra cosa, el fuego de esta página para asegurarse de que estamos configurados correctamente:

$ python app.py
* Running on http://127.0.0.1:5000/

Usted ahora debería ser capaz de visitar http://127.0.0.1:5000/ en un navegador y ver la forma preciosa.

Ahora vamos a decidir lo que queremos mostrar en la página de resultados, por lo que sabemos lo que vamos a necesitar para pasar a ella:


{% for line in result %}
{{ line }}
{% endfor %}

{{ artist }}




Aquí tenemos un bucle a través de un resultar matriz, línea por línea, mostrando cada línea por separado . Debajo de eso, mostramos el artista seleccionado y volver enlace a la página principal. Guardar esto como lyrics.html en el directorio templates /.

También tenemos que actualizar la acción forma de index.html a punto a esta página de resultados:

ahora a escribir una ruta para la página letras resultante:

@app.route('/lyrics', methods=['POST'])
def lyrics():
artist = request.form['artist']
lines = int(request.form['lines'])

if not artist:
return redirect(url_for('index'))

return render_template('lyrics.html', result=['hello', 'world'], artist=artist)

Esta página lleva una solicitud POST de la forma, el análisis cabo el artista proporcionado y el número de líneas – que no están generando ningún letras, sin embargo, sólo dar la plantilla de una lista de relleno de resultados. También necesitaremos añadir la funcionalidad necesaria Frasco – url_for y redirección – que hemos confiado en:

from flask import Flask, render_template, url_for, redirect

probarlo para asegurarse de que nada se ha roto todavía:

$ python app.py

Grande, ahora para la carne real del proyecto. Dentro de letras (), vamos a obtener una copia de la respuesta de LYRICSnMUSIC basado en nuestro pasado-en el parámetro artista:

# Get a response of sample lyrics from the provided artist
uri = "http://api.lyricsnmusic.com/songs"
params = {
'api_key': API_KEY,
'artist': artist,
}
response = requests.get(uri, params=params)
lyric_list = response.json()

El uso de solicitudes, buscamos a una URL específica que incluye un diccionario de parámetros: el nombre del artista proporcionado, y nuestra clave de API. Esta clave de API privada debe no aparecerá en el código; Después de todo, tendrá que compartir el código con los demás. En su lugar, vamos a hacer un archivo separado para mantener este valor como una variable:

$ echo "API_KEY=[youractualapikeygoeshere]" > .env

Hemos creado un archivo especial de “medio ambiente” que el frasco ahora puede leer en el caso de que sólo tiene que añadir lo siguiente a la parte superior de nuestra aplicación:

import os
API_KEY = os.environ.get('API_KEY')

y, por último, vamos a añadir en la funcionalidad de la cadena de Markov. Ahora que estamos utilizando el paquete de otra persona, esto termina siendo bastante trivial. En primer lugar, añadir la importación en la parte superior:

from pymarkovchain import MarkovChain

Y luego, después de que hemos recibido una respuesta letras de la API, simplemente creamos una Cadena de Márkov, la carga de los datos letras , y generar una lista de frases:

mc = MarkovChain()
mc.generateDatabase(lyrics)

result = []
for line in range(0, lines):
result.append(mc.generateString())

En total, entonces, app.py ahora debe ser algo como esto:

from flask import Flask, url_for, redirect, request, render_template
import requests
from pymarkovchain import MarkovChain
import os

API_KEY = os.environ.get('API_KEY')

app = Flask(__name__)
app.debug = True

@app.route('/', methods=['GET'])
def index():
return render_template('index.html')

@app.route('/lyrics', methods=['POST'])
def lyrics():
artist = request.form['artist']
lines = int(request.form['lines'])

if not artist:
return redirect(url_for('index'))

# Get a response of sample lyrics from the artist
uri = "http://api.lyricsnmusic.com/songs"
params = {
'api_key': API_KEY,
'artist': artist,
}
response = requests.get(uri, params=params)
lyric_list = response.json()

# Parse results into a long string of lyrics
lyrics = ''
for lyric_dict in lyric_list:
lyrics += lyric_dict['snippet'].replace('...', '') + ' '

# Generate a Markov model
mc = MarkovChain()
mc.generateDatabase(lyrics)

# Add lines of lyrics
result = []
for line in range(0, lines):
result.append(mc.generateString())

return render_template('lyrics.html', result=result, artist=artist)

if __name__ == '__main__':
app.run()

Pruébalo! Todo debe estar trabajando a nivel local. Ahora, para compartir con el mundo …

Implementar para el anfitrión de Heroku

Let en Heroku, ya que (para estos requisitos mínimos) podemos hacerlo de forma gratuita. Para ello, tendremos que hacer algunos ajustes menores al código. En primer lugar, añadir un Procfile que le dirá Heroku cómo servir a la aplicación:

$ echo "web: python app.py" > Procfile

A continuación, desde Heroku especifica un puerto aleatorio en el que ejecutar la aplicación, tendrá que pasar un número de puerto en la parte superior:

PORT = int(os.environ.get('PORT', 5000))

app = Flask(__name__)
app.config.from_object(__name__)

y cuando se ejecuta la aplicación, asegúrese de pasar este puerto en

if __name__ == '__main__':
app.run(host='0.0.0.0', port=PORT)

también tuvimos que especificar la cantidad de ‘0.0.0.0’ porque Frasco por defecto se ejecuta de forma privada en el equipo local, mientras que queremos que la aplicación se ejecute en Heroku en un IP a disposición del público.

Por último, app.debug remove = true de su código para que los usuarios no llegan a ver sus errores StackTrace completo si algo va mal.

inicializar un repositorio git (si no lo ha hecho), cree una nueva aplicación Heroku, y empujar su código a él!

$ git init
$ git add .
$ git commit -m "First commit"
$ heroku create
$ git push heroku master

Véase la documentación Heroku para un resumen más detallado de este proceso de implementación. Asegúrese de añadir la variable de API_KEY en Heroku:

$ heroku config:set API_KEY=[youractualapikeygoeshere]

Y estamos listos! Tiempo para compartir su creación con el mundo – o mantener la piratería en ello 🙂

Conclusión y próximos pasos

Si te gustó este contenido, que podría estar interesado en nuestros cursos actuales para el desarrollo web de aprendizaje o nuestro nuevo pedal de arranque que cubre más avanzada técnicas. O – sólo jugar un poco con la aplicación aquí.

posibles próximos pasos:

  • Este código HTML parece que fue escrito en los años 90; el uso de rutina de carga o simplemente un poco de CSS básicos para crear
  • añadir algunos comentarios al código antes de que se le olvida lo que hace! (Esto se deja como ejercicio para el lector: o)
  • Abstract el código en la ruta letras para ser métodos individuales (es decir, un método para devolver respuestas de la API de letras y otro método independiente para generar el modelo de Markov); esto hará que el código sea más fácil de mantener y comprobable a medida que crece en tamaño y complejidad
  • Crear un generador de Markov que es capaz de utilizar órdenes superiores
  • Uso matraz de WTF para mejorar las formas y validación de formularios
  • Hablando de eso: Maquillaje lo más seguro! En este momento, alguien podría potencialmente enviar solicitudes POST no razonables, inyectar su propio código en la página o DoS al sitio con muchos pedidos repetidos rápidamente; añadir un poco de validación de entrada sólida y tasa básica limitar
  • Añadir un mejor manejo de errores; ¿y si una llamada API tarda demasiado tiempo o falla por alguna razón?
  • banda los resultados en un motor de texto a voz, aprender a variar los patrones de tono utilizando otro modelo de Markov, y se puso a un ritmo; pronto va a estar en la cima de las listas!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *