<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Clase Analisis y Presentacion de Datos
Comparacion de artistas en base a sus canciones
Suponemos que podemos evaluar que tan parecido son dos autores en base a que tan comunmente usan cada palabra
Step1:  Algo que no hicimos durante la clase, pero que si hay que hacer, es sacar las palabras que no nos dan informacion. Otra cosa que habria que hacer es sacar todos los simbolos.
Si no sabemos hacer algo, siempre podemos recurrir a Stack Overflow
Step2:  Importo las utilidades de diccionario de la primer parte del TP, de donde vamos a usar la funcion calcular_distancia como metrica. Las metricas siempre se definen en base a lo que vayamos a hacer, existen metricas mas o menos aceptadas para ciertas cosas, pero no evita que podamos definir las nuestras propias (con cierto fundamento claro esta).
Step3:  Pruebo que tanto se parecen algunos artistas al azar. Voy a necesitar markdown para que se vea mas lindo, asi que puedo importar la funcion para mostrarlo directamente desde el output
Step4:  Extra
Hay una forma sencilla de armar canciones nuevas de un artista usando cosas que vimos. Si bien es una solucion "burda", las soluciones mas sofisticadas siguen la misma idea
Step5:  Lo que hice es armar un diccionario con las palabras de las canciones, y a cada una asociarle una lista con todas las palabras que aparecen despues de esa. Al ser una lista con repeticiones, si elijo una palabra al azar, es mas probable que elija una palabra que aparece mas seguido que otras. Entonces, al igual que con el predictivo, puedo armar una cancion de ABBA asi
Step6:  Incluso para ser algo rapido, alguna clase de sentido tiene. Si le queremos dar mas sentido, deberiamos analizar mas que la palabra anterior, por ejemplo las 2 anteriores, y eso deberia mejorar
Step7:  Tambien podemos combinar varias canciones de varios artistas para hacer algo aun mas loco.
<ASSISTANT_TASK:>
Python Code:
import csv
data = {}
with open("songdata.csv") as file:
    for author,_,_,lyric in csv.reader(file):
    
        data[author] = data.get(author,{})
        for word in set(lyric.lower().split()):
            data[author][word] = data[author].get(word,0) + 1 
data["ABBA"]
Explanation: Clase Analisis y Presentacion de Datos
Comparacion de artistas en base a sus canciones
Suponemos que podemos evaluar que tan parecido son dos autores en base a que tan comunmente usan cada palabra
End of explanation
import re
# https://stackoverflow.com/questions/875968/how-to-remove-symbols-from-a-string-with-python
def strip_simbols(string):
   return re.sub(r'[^\w]', '', string)
import csv
data = {}
with open("songdata.csv") as file:
    for author,_,_,lyric in csv.reader(file):
    
        data[author] = data.get(author,{})
        for word in set(lyric.lower().split()):
            word = strip_simbols(word)
            data[author][word] = data[author].get(word,0) + 1 
data["ABBA"]
for author in data:
    print(author)
Explanation: Algo que no hicimos durante la clase, pero que si hay que hacer, es sacar las palabras que no nos dan informacion. Otra cosa que habria que hacer es sacar todos los simbolos.
Si no sabemos hacer algo, siempre podemos recurrir a Stack Overflow
End of explanation
import utilidades_diccionarios
Explanation: Importo las utilidades de diccionario de la primer parte del TP, de donde vamos a usar la funcion calcular_distancia como metrica. Las metricas siempre se definen en base a lo que vayamos a hacer, existen metricas mas o menos aceptadas para ciertas cosas, pero no evita que podamos definir las nuestras propias (con cierto fundamento claro esta).
End of explanation
from IPython.display import display, Markdown, Latex
import random
artists = list(data.keys())
artist_a = random.choice(artists)
artist_b = random.choice(artists)
diference = utilidades_diccionarios.calcular_distancia(data[artist_a],data[artist_b],2)
display(Markdown( f'Diferencia entre *{artist_a}* y _{artist_b}_ es: **{diference}** '))
artist_a = random.choice(artists)
artist_b = random.choice(artists)
diference = utilidades_diccionarios.calcular_distancia(data[artist_a],data[artist_b],2)
display(Markdown( f'Diferencia entre *{artist_a}* y _{artist_b}_ es: **{diference}** '))
artist_a = random.choice(artists)
artist_b = random.choice(artists)
diference = utilidades_diccionarios.calcular_distancia(data[artist_a],data[artist_b],2)
display(Markdown( f'Diferencia entre *{artist_a}* y _{artist_b}_ es: **{diference}** '))
artist_a = random.choice(artists)
artist_b = random.choice(artists)
diference = utilidades_diccionarios.calcular_distancia(data[artist_a],data[artist_b],2)
display(Markdown( f'Diferencia entre *{artist_a}* y _{artist_b}_ es: **{diference}** '))
artist_a = random.choice(artists)
artist_b = random.choice(artists)
diference = utilidades_diccionarios.calcular_distancia(data[artist_a],data[artist_b],2)
display(Markdown( f'Diferencia entre *{artist_a}* y _{artist_b}_ es: **{diference}** '))
Explanation: Pruebo que tanto se parecen algunos artistas al azar. Voy a necesitar markdown para que se vea mas lindo, asi que puedo importar la funcion para mostrarlo directamente desde el output:
End of explanation
import csv
data = {}
authors =  ["ABBA"]
with open("songdata.csv") as file:
    for author,_,_,lyric in csv.reader(file):
    
        if author not in authors:
            continue
    
        prev = ""
        for word in lyric.lower().split():
            new_word = word
            while new_word and not new_word[-1].isalpha():
                new_word = new_word[:-1]
                      
            data[prev] = data.get(prev,[])
            data[prev].append(new_word)
            
            prev = new_word
            
            if not word[-1].isalpha():
                data[prev] = data.get(prev,[])
                data[prev].append(word[-1])
            
                prev = word[-1]
                
        data[prev] = data.get(prev,[])
        data[prev].append("")
Explanation: Extra
Hay una forma sencilla de armar canciones nuevas de un artista usando cosas que vimos. Si bien es una solucion "burda", las soluciones mas sofisticadas siguen la misma idea
End of explanation
cancion = []
prev = ""
for _ in range(100):
    next_word = random.choice(data[prev])
    cancion.append(next_word)
    prev = next_word
    
display(Markdown("_" + " ".join(cancion) + "_") )
Explanation: Lo que hice es armar un diccionario con las palabras de las canciones, y a cada una asociarle una lista con todas las palabras que aparecen despues de esa. Al ser una lista con repeticiones, si elijo una palabra al azar, es mas probable que elija una palabra que aparece mas seguido que otras. Entonces, al igual que con el predictivo, puedo armar una cancion de ABBA asi:
End of explanation
import csv
data = {}
authors =  ["ABBA"]
with open("songdata.csv") as file:
    
    prev = ("","")
    for author,_,_,lyric in csv.reader(file):
    
        if author not in authors:
            continue
    
        for word in lyric.lower().split():
            new_word = word
            
            if not word[0].isalpha():
                data[prev] = data.get(prev,[])
                data[prev].append(word[0])
            
                prev = (prev[-1],word[0])
            
            while new_word and not new_word[0].isalpha():
                new_word = new_word[1:]
            
            while new_word and not new_word[-1].isalpha():
                new_word = new_word[:-1]
                      
            data[prev] = data.get(prev,[])
            data[prev].append(new_word)
            
            prev = (prev[-1],new_word)
            
            if not word[-1].isalpha():
                data[prev] = data.get(prev,[])
                data[prev].append(word[-1])
            
                prev = (prev[-1],word[-1])
                
        data[prev] = data.get(prev,[])
        data[prev].append("")
        prev = (prev[-1],"")
cancion = []
prev = ("","")
for _ in range(100):
    next_word = random.choice(data[prev])
    cancion.append(next_word)
    prev = (prev[-1],next_word)
    
display(Markdown("_" + " ".join(cancion) + "_") )
Explanation: Incluso para ser algo rapido, alguna clase de sentido tiene. Si le queremos dar mas sentido, deberiamos analizar mas que la palabra anterior, por ejemplo las 2 anteriores, y eso deberia mejorar
End of explanation
import csv
data = {}
authors =  ["ABBA","Stevie Wonder","Hank Williams"]
with open("songdata.csv") as file:
    
    prev = ("","")
    for author,_,_,lyric in csv.reader(file):
    
        if author not in authors:
            continue
    
        for word in lyric.lower().split():
            new_word = word
            
            if not word[0].isalpha():
                data[prev] = data.get(prev,[])
                data[prev].append(word[0])
            
                prev = (prev[-1],word[0])
            
            while new_word and not new_word[0].isalpha():
                new_word = new_word[1:]
            
            while new_word and not new_word[-1].isalpha():
                new_word = new_word[:-1]
                      
            data[prev] = data.get(prev,[])
            data[prev].append(new_word)
            
            prev = (prev[-1],new_word)
            
            if not word[-1].isalpha():
                data[prev] = data.get(prev,[])
                data[prev].append(word[-1])
            
                prev = (prev[-1],word[-1])
                
        data[prev] = data.get(prev,[])
        data[prev].append("")
        prev = (prev[-1],"")
cancion = []
prev = ("","")
for _ in range(100):
    next_word = random.choice(data[prev])
    cancion.append(next_word)
    prev = (prev[-1],next_word)
    
display(Markdown("_" + " ".join(cancion) + "_") )
Explanation: Tambien podemos combinar varias canciones de varios artistas para hacer algo aun mas loco.
End of explanation
<END_TASK>