Tuesday 11 August 2015

representing song lyrics in sw format

An easy one today. It recently occurred to me we can easily enough represent song lyrics in sw format, and then show that using a table. So no more words, here is an example from The Doors:
$ cat the-doors--people-are-strange.sw
lyrics-for |the doors: People are strange> => |line 1: "People Are Strange">
lyrics-for |the doors: People are strange> +=> |line 2: >
lyrics-for |the doors: People are strange> +=> |line 3: People are strange when you're a stranger>
lyrics-for |the doors: People are strange> +=> |line 4: Faces look ugly when you're alone>
lyrics-for |the doors: People are strange> +=> |line 5: Women seem wicked when you're unwanted>
lyrics-for |the doors: People are strange> +=> |line 6: Streets are uneven when you're down>
lyrics-for |the doors: People are strange> +=> |line 7: >
lyrics-for |the doors: People are strange> +=> |line 8: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 9: Faces come out of the rain>
lyrics-for |the doors: People are strange> +=> |line 10: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 11: No one remembers your name>
lyrics-for |the doors: People are strange> +=> |line 12: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 13: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 14: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 15: >
lyrics-for |the doors: People are strange> +=> |line 16: People are strange when you're a stranger>
lyrics-for |the doors: People are strange> +=> |line 17: Faces look ugly when you're alone>
lyrics-for |the doors: People are strange> +=> |line 18: Women seem wicked when you're unwanted>
lyrics-for |the doors: People are strange> +=> |line 19: Streets are uneven when you're down>
lyrics-for |the doors: People are strange> +=> |line 20: >
lyrics-for |the doors: People are strange> +=> |line 21: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 22: Faces come out of the rain>
lyrics-for |the doors: People are strange> +=> |line 23: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 24: No one remembers your name>
lyrics-for |the doors: People are strange> +=> |line 25: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 26: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 27: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 28: >
lyrics-for |the doors: People are strange> +=> |line 29: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 30: Faces come out of the rain>
lyrics-for |the doors: People are strange> +=> |line 31: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 32: No one remembers your name>
lyrics-for |the doors: People are strange> +=> |line 33: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 34: When you're strange>
lyrics-for |the doors: People are strange> +=> |line 35: When you're strange>
where we are using the notation for append learn "+=>" (unfortunately I called it add_learn, which it partly is, and partly isn't, but it is way too late to change it now).

Now we have it in sw we can display it easy enough:
sa: load the-doors--people-are-strange.sw
sa: table[lyrics] lyrics-for |the doors: People are strange>
+-------------------------------------------+
| lyrics                                    |
+-------------------------------------------+
| "People Are Strange"                      |
|                                           |
| People are strange when you're a stranger |
| Faces look ugly when you're alone         |
| Women seem wicked when you're unwanted    |
| Streets are uneven when you're down       |
|                                           |
| When you're strange                       |
| Faces come out of the rain                |
| When you're strange                       |
| No one remembers your name                |
| When you're strange                       |
| When you're strange                       |
| When you're strange                       |
|                                           |
| People are strange when you're a stranger |
| Faces look ugly when you're alone         |
| Women seem wicked when you're unwanted    |
| Streets are uneven when you're down       |
|                                           |
| When you're strange                       |
| Faces come out of the rain                |
| When you're strange                       |
| No one remembers your name                |
| When you're strange                       |
| When you're strange                       |
| When you're strange                       |
|                                           |
| When you're strange                       |
| Faces come out of the rain                |
| When you're strange                       |
| No one remembers your name                |
| When you're strange                       |
| When you're strange                       |
| When you're strange                       |
+-------------------------------------------+
And we are done. All nice and pretty.

Update: say we want to pick a doors song randomly. That is easy enough. And say that we have weights that represent how much we like them. Maybe something like:
list-of-songs |The Doors> => 10|the doors: People are Strange> + 10|the doors: Light My Fire> + 7|the doors: The End> + 6|the doors: Love Me Two Times> + ... + 0.2|the doors: Moonlight Drive>
Then simply enough:
sa: load the-doors.sw
sa: table[lyrics] lyrics-for weighted-pick-elt list-of-songs |The Doors>
And we need some mechanism to filter out songs we have recently heard, and longer term changes in weights for when we get bored of a song.

Maybe we need something along the lines of:
list-of-songs |heard recently> => |the doors: Light My Fire> + |the doors: The End>
list-of-interesting |songs> => complement(list-of-songs |heard recently>,list-of-songs |The Doors>)
Though I don't yet have a complement function, but shouldn't be hard to write one.

Update: wrote a couple of lines of code, so we can now do this example (and it turns out I already had complement() defined in another way, so exclude() seemed the best name).

First the code tweaks (in the functions file):
# exclude(|a> + |c>,|a> + |b> + |c> + |d>) == |b> + |d>
#
def exclude_fn(x,y):
  if x > 0:
    return 0
  return y
       
def exclude(one,two):
  return intersection_fn(exclude_fn,one,two).drop()
Now put it to use:
sa: list-of-songs |The Doors> => 10|the doors: People are Strange> + 10|the doors: Light My Fire> + 7|the doors: The End> + 6|the doors: Love Me Two Times> + 0.2|the doors: Moonlight Drive>
sa: list-of-songs |heard recently> => |the doors: Light My Fire> + |the doors: The End>
sa: list-of-interesting |songs> => exclude(list-of-songs |heard recently>,list-of-songs |The Doors>)
sa: list-of-interesting |songs>
10|the doors: People are Strange> + 6|the doors: Love Me Two Times> + 0.2|the doors: Moonlight Drive>
It works! And this idea of "list-of-something |heard recently>" and then excluding it from a list, seems to me a common pattern humans use. Maybe something as simple as telling jokes. You want to keep track of the ones you have already said. And the reverse, dementia. You forget the stories you have just told to your grandchild. And the child says "Grandma, you already told me that one!".

In this case the child might be doing something like:
you-already-told-me-that-one |*> #=> do-you-know mbr(|_self>,list-of-stories|heard recently>)

The other thing about the exclude function, it reminds me of this Sherlock Holmes quote:
"Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth."

list-of |options> => exclude(list-of |impossible>,list-of-all |possible>)
And then the "no matter how improbable" means the highest coeff in "list-of |options>" is small. But, nonetheless, it is the best option left.

No comments:

Post a Comment