Rankerr
Rankerr is a Hybrid Web/Mobile App that uses a binary insertion algorithm to rank songs on a playlist using the least amount of comparisons necessary.
The Problem
Spotify currently lacks the ability to give a star rating to songs. This makes it difficult to order a playlist based on how much one favors a particular song.
The Solution
Create a tool that allows users to do the minimal comparison necessary between items from a playlist in order to create a new playlist where higher equals better.
Outcome
Rankerr is an app that allows you to quickly create ranked Spotify playlists by asking you which of two songs you prefer. What you end up with is a ranked playlist, where the higher a song is positioned, the more you like it.
It works by feeding off an unordered playlist, album, or your library of saved songs and goes through a list of 1 vs. 1 questions until each song reaches its final position, all of this with the least amount of comparisons necessary.
Features
You can directly start ranking tracks of an album, a playlist made by you, or your library, which creates a new playlist with the "Rankerr" prefix, or you can continue ranking by choosing the playlist you left off at.
Pressing continue instead allows you to choose the input source, aka the feed.
You can also rank single tracks once you have set a source playlist.
When you're finished and there are still songs left on the feed that aren't contained on the playlist you've chosen, a button will appear, asking whether you want to continue with said feed.
Put differently, the "Continue" button exists in case you already have a ranked playlist and want to use it as a basis for ranking songs. It’s basically the same as the first option, with the difference that it won’t create a new playlist on selection. That way, you'll never have to worry to start from the beginning again.
In case you pressed “Can’t decide!” at any earlier point in the chain of decisions, the song will take on the position one number below the song it was compared against.
But try to only press it if you really can't decide! This ensures that the songs you can't decide between will always find themselves near each other.
However, for the most stupid of mistakes, the Undo button got you covered as well.
How It Works
Rankerr uses a sort algorithm called “Binary Insertion sort”. But instead of a machine doing the comparison, you do.
The "Binary" part is simple a variation of normal insertion sort, which is ideal for quickly ranking preferences. It allows us to reduce the amount of comparisons necessary by splitting a set list of items in half until a new item's position has been found.
It starts with a random song of the playlist you feed into it and puts it first on the new, ranked playlist. The next song will be the first that will be compared by asking you which of the two you like more and place it accordingly. The third song will undergo the same decision process - Do you love it more than what is currently in the middle? - and so on.
If my explanation was too confusing, let's make it easier by looking at a longer, already ranked list. Say it's already 100 songs long, and you wanted to add another one; how does Rankerr help you figure out where it belongs?
In a list of 100 items…
Background
My main motivation for starting this project stems from two intertwined problems:
- The inability to rate songs on Spotify
- Wanting to share a long list of my favourite songs, while being able to give a better perspective on my musical taste
This would be easy enough with a rating feature, like the 5 star system Apple Music is offering. While 5 stars isn’t a lot, it can at least give some overview for you and the people you want to share a list with. This is what people have been doing with their iTunes Libraries for the longest time.
But then I realised that we already have a way of organising playlists by rating - the custom sort. I figured that if I were to simply try and put songs I love more above songs I love less, I’d be left with an accurate enough snapshot of my opinion. The only question was how to do it most efficiently.
I began exporting my already rated iTunes smart playlists - each one being dedicated to a number of stars. Next, I imported them into a great tool called Spotlistr, which allowed me to quickly assign the local files to the corresponding Spotify tracks.
I made lists for 1, 2, 3, 4 and 5 stars. Then, I created one last playlist and copied the songs from the others over, starting with the 5 star one and going down from there. Now, all that was left was tagging it with “higher equals better” and done it was - the playlist gave a good general impression of my preferences.
At the same time, the hierarchical nature of playlists quickly became obvious to me - while I do love Van Morrison’s Brown Eyed Girl, it’s not hard for me to say that I love Chuck Berry’s Johnny B. Goode more. In fact, it’s rather easy. And in order to make the playlist represent this opinion, all I had to do was to make them swap positions.
This instantly reminded me of the initial struggle I had with rating songs on iTunes: 5 stars just don’t offer a high enough resolution to make a true “Best of All Time” playlist. But ordering them manually isn’t that efficient either: Where do you even begin? How much time does it take to compare every song to every other one?
Well, I can answer you the second question: Say, we’re dealing with 1000 songs. If you take 5 seconds to make a decision between each, it’s around 1388 hours, or around 87 days of nonstop comparing, with 16 hour shifts. Of course, one will quickly come to the realisation that this process isn’t as efficient as it could be, due to one simple fact:
If you already decided you like song A a bit more than song B, and song C a lot more than song B, it’s unnecessary to compare songs A and C. Instead, C’s superiority over A is an emergent property of the comparisons you already did! This is called transitivity - the secret ingredient that allows us to complete the rating process in around 10 hours.
Now, don't get me wrong - I don’t expect human preferences to be perfectly transitive - after all, depending on which two songs you’re comparing, your opinion might shift in a manner that would seem nonsensical to a computer dealing with hard-coded values in the files it’s looking at. However, this is a struggle we can’t escape with any rating system - a 5 star rating system, which is desired by many Spotify users, poses the same problem.
Gladly, though, it doesn’t matter that much: songs you perceive to be of similar quality will always find themselves in similar regions. The longer the list, the higher the dynamic range of perceived quality, the more accurate. In fact, the resolution the ranking system provides will be better than 5 stars regardless - it's continuous. Depending on how strict your opinion is, it will even be perfectly accurate.
Technical Details
Due to the nature of Ionic Framework using Safari’s Webkit, there’s no easy way of disabling the native “Swipe to go back” functionality implemented by the iOS webview. This makes it more difficult to provide a PWA with a native feel.
One workaround for this issue is to go the route (no pun intended) of history.replace()
instead of history.push.()
, which essentially tells Safari that there’s no history to go back to, thus leaving the swipe back functionality disabled. However, this approach simultaneously breaks the back button functionality in Ionic, as would be expected.
As is the case with using Spotify's API, one has to apply first to be allowed to use its services for commercial purposes. This is the main reason why I went with the web based approach: It serves as a prototype to submit to Spotify, while at the same time making an early version accessible to whoever is interested. If the day comes, I'd plan on rebuilding it in Swift, after honing my skills in it.
This is also the reason why I chose to go with Ionic over React Native: While React Native certainly provides a more native feel and performance, the mere aesthetic of Ionic's components made this choice easy for me, since it is more in line with the SwiftUI library.