What is the Mnemonic Maker app?
Ever use Quizlet? Now imagine those digital flashcards incorporating your favorite song lyrics to help make studying effective and fun. And not just any lyrics, but lyrics whose initials line up perfectly to those of the phrase or list you need to remember. Add these mnemonic devices to a playlist of your choosing and listen to your flashcards come to life!
How we got here
As a former teacher and avid life-long student, I’m always looking for ways to make learning more fun and engaging. When I used to teach fourth graders, my co-teacher and I found that our students were having trouble with their multiplication tables. So, we created multiplication songs for each digit (“This is the way we roll our 3s!”) to have the students sing before they started class. The kids loved it, and, eventually, not one student had trouble with single digit multiplication for the rest of the year. This showed me the magic of strategic, engaging learning, particularly the magic of learning through music.
Over the summer, I was talking with my friend and fellow coder Jack about planets, trying to name every one in order. Jack then pointed out, “What’s that mnemonic device used to remember planets? “My (Mercury) Very (Venus) Eager (Earth) Mother (Mars) something something Noodles (Neptune)?” We laughed and said that we could come up with something better than that. After 5 minutes, we pathetically gave up. One of us (I honestly forget who) then says, “You can definitely write code to generate one for you.” A week later, we started working on our project that would become “Mnemonic Maker”, a website that helps you remember things by matching up your list or phrase’s initials to those of a catchy/memorable song lyric.
Within a few weeks, we created a simple website that returned a matching lyric to an input phrase, but there were two main problems:
1. The “lyric” returned was a string of consecutive words anywhere in the song, often across bar breaks. In other words, if we entered something we wanted to remember, like “Ministry of Transport”, the app might hit the song, “Empire State of Mind” by Jay-Z (great song), and it might hit the lyric: “Concrete Jungles where dreams are made of, there’s nothing you can’t do” (great lyric), but in this case it’ll return the matching phrase as “Made Of, There’s.” That’s not a catchy lyric, and it’s not going to help anyone remember anything.
2. More importantly, It took forever. Nobody wants to sit in front of their computer and wait 5 minutes for a matching phrase to come up.
So, we decided to scrap this project and start fresh (using the lessons we learned and utilizing some useful code from the old project). We then got a pretty cool app, that looked a lot nicer, and was lightening quick. Still, a couple of problems:
1. Same as before, the lyrics are not catchy.
2. The app would return lyrics of just Beatles songs. While I love the Beatles, this is simply not enough data.
So, we scrapped that, and started anew with what would be the final codebase for the project. This is where we got lost in the code and kept adding features. At this point, we were able to to:
-search through many artists’ lyrics very quickly, and filter the search by a particular artist
-add the YouTube videos of the songs (this process deserves its own blog post)
-have users create accounts and login
-save the mnemonic info (user’s input, matching phrase, song info) to a user’s playlist so that they can refer back to it and listen to their mnemonic songs.
-and much more
On top of that, the app looked way nicer.
However, there was still a problem, a bad itch that a couldn’t shake: the returning phrases were still not recognizable nor catchy!
So, I branched off of the project, and using all of its existing code and framework, created a new one. Eventually, I got it. Now the user can search a phrase and the lyric will not be split over bar breaks or be from the middle of a lyric. And it works even faster than before. I have even been using it myself whenever I come across a word or a phrase I don’t know and want to keep track of. It genuinely helps me remember things, and also helps me discover new songs. Am I biased? Of course, but I still think it’s pretty cool.
However, the app is by no means perfect nor is it done. I am just done for now. How will I know when it’s done or that I reached my goals (to some extent)? When I can type in all of the planets in our solar system and get something better than “My Very Eager Mother Just Served Us Noodles.” That phrase is too long for the app at this point. Right now, I usually find success in typing in phrases with a length of 4 words or less.
A few notes about the coding process:
I talked about how the app evolved from a functionality standpoint, however, if you are curious about the programming behind the evolution of the app, stick around. If you don’t care, that’s cool, too. Thanks for reading.
Why was the querying process so slow at first?
We started by making api calls to songs one by one whenever a user typed in a phrase. Not only did it make an api call per song queried, but it also web-scraped the lyrics from genius.com at every turn. You can imagine how the runtime of such an app is not ideal.
Made it faster by…
The power of seeding. When we created the generator based solely on Beatles lyrics, the app was running through every Beatle’s song’s lyrics in our database (without scraping or making api calls, just strict Active Record iterations), until it found a match. This was surprisingly fast and got us pretty excited.
Made it a more comprehensive app by…
Implementing the aspect of OAuth with the options to save bookmarks to a playlist as well as edit playlists and delete them (full CRUD). To incorporate all of these details and have them persist throughout the app, we used Redux, a library that allows you to access and change global state in a clean, structured way.
Made it more dynamic by…
Seeding more artists and their respective song lyrics. To do this we had to code a pretty robust seeding method in the backend, using a combination of making API Calls (to get the artist info and their list of songs) and web-scraping (first by scraping the lyrics from genius, then scraping the YouTube video idea from Youtube). The idea was, if we were to add more artists, and more songs, then the input phrase would find a match more often. However, naturally, with querying more songs comes a slower runtime…and again we still aren’t grabbing “catchy” phrases.
Made it faster, cleaner, and catchier with fewer lines of code by…
Adding a new table, called “Lyric Snippets.” We knew that when we accessed the lyric text from scraping the Genius web-pages, that Ruby allows us to break the text down line by line through the method, “each_line.” So, what I did was raise the fixed cost of seeding so that I could lower the variable cost of the user experience. I iterated through thousands of songs, and seeded each line, double-line (two lines combined together), and fragment (produced by splitting the line about its commas) in a row, along with the initials. That way, whatever a user types in, say “I love coding”, we can easily query all the snippets with those initials-LyricSnippet.where(initials: “ilc”), and queue them up for our user. First result I got in a matter of seconds: “I lost control” from an Ozzy Osborne song. Seems about right.
At the time of deployment, my database holds 542,023 snippets. You may be thinking, “That’s way too many rows and is not optimal for space.” But, when I made the switch to lyric snippets, I no longer had to save the full lyrics in the database, I just triggered an API call/web-scrape upon a match. So, it almost evens out in that sense.
One exciting yet frustrating thing is that I don’t consider this app finished and there are still things that I want to do with it. Stuff like implementing Facebook Auth, executing more elegant styling, filtering by genre, and creating an overall better user experience, is something I would be happy to revisit later. Until then, I will ponder. How do I accomplish my ultimate goal? How do I reach Neptune? Maybe it’s more seed data, maybe it’s a more clever way of querying the lyrics, maybe it’s something I’m totally not seeing. Below is the link to the GitHub repo. Check it out and let me know what you think.