So I’m sitting there planning out a house party that would feature a Just Dance Tournament, and I wanted to minimize the time it took for people to choose the song. And with all the songs in Just Dance Unlimited, guests were bound to be hit with option paralysis. The quick solution to that would be to make the system choose for them by shuffling the next song.
The problem: Just Dance 2019 has no way to randomize the next song.
The solution: Do it myself with Python.
The requirements:
Python 3.x
Requests
Beautiful Soup 4
Overview of the steps:
Install Beautiful Soup 4 and Requests.
Scrape all the Just Dance Unlimited songs.
Save the list variable to a .csv file so we can launch the program later without scanning for the songs again.
Write the actual randomization algorithm and run the randomizer from the terminal.
Make it look like it’s thinking about what song to randomly land on.
1. Installing Requests and Beautiful Soup 4.
Requests is a package that lets you send HTTP requests using Python.
Beautiful Soup 4 is a package that helps you pull HTML and XML files within Python. Pass in a few keywords and you’ve scraped your content from your target webpage.
We will be installing Requests and Beautiful Soup 4 using the Python Installer Package, or pip. If you don’t have pip installed on your operating system, check these guides out.
From your bash terminal, enter the following command:
$ pip install requests $ pip install beautifulsoup4
To test requests out, start the Python shell by entering “python” and type the following commands:
>> import requests >> response = requests.get('https://google.com') >> print(response) <Response [200]>
A response of 200 means that the call is valid and the HTTP request was successful. At this point the page has been loaded. You can view the information by entering:
>> response.text
Which will result in the shell printing a large block of text.
To test BS4 out, follow this guide on their documentation page.
2. Scrape all the Just Dance Unlimited songs
Before we can scrape a page, we have to find the page itself. I started off with this page only to find that the table they used for the list of songs was of the same type, style, and identification of songs that were not included or removed from Just Dance Unlimited. In other words, there was no way to identify between the songs in Just Dance Unlimited from the songs not in Just Dance Unlimited.
After hours of frustrating filtering and reaching a roadblock I kept searching and found this page which only had the songs in Just Dance Unlimited.
It took a few tries to get the scraping algorithm right. I took a trial and error approach to get to here. I typed the following entries in the Python shell to get the desired result. I used IPython since it plays nice with multi-line entries (for loops, if-then conditionals, etc).
# Import the libraries >> import requests >> from bs4 import BeautifulSoup # Load the page into Python (You'll want to repeat this entire process twice since there's two pages to the song list.) >> url = 'https://justdance.fandom.com/wiki/Category:Songs_in_Just_Dance_Unlimited' >> url2 = 'https://justdance.fandom.com/wiki/Category:Songs_in_Just_Dance_Unlimited?from=Kurio+ko+uddah+le+jana' >> r = requests.get(url) # Save the data >> data = r.text >> soup = BeautifulSoup(data, 'html.parser')
At this point, if you were to enter the following:
>> print(soup)
You would be greeted by a wall of HTML text, which is literally that webpage’s source code. But remember, our goal is to only get the song titles. If you look closely you’ll find a pattern:
And that pattern is that every song title is wrapped with the <a></a> tag! Not only that, but they had an HTML ‘title’ element with their song name attached.
To get all the <a></a> elements, you call the following function:
>> soup.find_all('a')
This function returns a list datatype. To test on a single <a></a> item (because it’s much easier to focus on the smaller units and then scale upward later on), I picked an arbitrary index number.
>> soup.find_all('a')[200] [OUT]: <a class="category-page__member-link" href="/wiki/Done_For_Me" title="Done For Me">Done For Me</a>
(to be honest, I kept on trying different numbers until I got one that returned what I was looking for)
So I used a for loop to go through each <a></a> tag and used a second filter to filter out anything that had Just Dance in the title (because of course, they’re a Just Dance fan site whose Just Dance links are more relevant to the game franchise than Lady Gaga’s 2008 hit). We’ll add the actual Just Dance song back in at the end. Here’s the block of code:
>> songList = [] >> for element in soup.find_all('a'): >> try: >> title = element['title'] >> if "Just Dance" in title: >> continue >> else: >> if title not in songList: >> print("Appending {}".format(title)) >> songList.append(title) >> if title == "Worth It": >> break >> except TypeError: >> continue >> except KeyError: >> continue
3. Save the songs to a file
I used the good ol’ built-in file handler for this one.
>> f = open('just_dance_list.csv', 'w') >> for song in songList: >> f.write(song + '\n') >> f.close()
This tells Python to open the file “just_dance_list.csv” or create it if it doesn’t exist. Then it will iterate through every element in songList and write the song name to the file. The appended ‘\n’ says that it will print a “new line” at the end of the song name, preparing for the next song in the list. Finally, it closes the .csv file to avoid file corruption.
Do note that since there were two pages of songs, I needed to repeat this whole process again. It was only two pages so I chose to do it by hand, but any more and you’re better off automating it. (You can find the complete script at the end of this entry.)
(Don’t forget to add Just Dance by Lady Gaga. We skipped over that. I would say do it by hand but you don’t need my permission to be adventurous)
4. Shuffle the songs
I used Python’s built in random number generator, enumerated each line in the ‘just_dance_list.csv’ file, and returned the corresponding song name.
>> import random >> file = open('just_dance_list.csv', 'r') >> songRead = file.readLines() >> file.close() # Pick an integer number between 0 and the number of songs >> songIndex = random.randint(0, len(songRead) - 1) # Get the song name >> songName = songRead[songIndex] # Print the song name >> print(songName[:-1]) [OUT]: Mamasita
Notice I printed songName[:-1], which means “get me the entire string except for the last character—don’t give me the last character.” In this case, that last character is a “new line” character and it only shows up when you don’t use the print function.
# Using print() >> print(songName) [OUT]: Mamasita # Not using print() >> songName [OUT]: 'Mamasita\n'
I just like to be consistent so I opted for the [:-1] anyway.
5. Make it look more shuffled than it already is
When you pull the lever on a slot machine in Vegas, the machines could simply generate a random outcome almost immediately. In fact, that’s what they really do. All they do is add a sense of anticipation by making you wait a few seconds until all the spinny bits stop spinning.
To get that effect, I repeated the random choosing function and imported a time.sleep() method that runs in between each randomly generated songs. This would occur 100 times.
>> from time import sleep >> for i in range(100): >> songIndex = random.randint(0, len(songRead) - 1) >> songName = songRead[songIndex] >> print('', end="\r") >> print("RANDOMIZED SONG: {}".format(str(songName[:-1])), end="\r") >> sleep(0.01)
You might notice I passed in a second parameter to the print function: end=”\r”. This tells the console to bring the cursor back to the beginning of the line. Without this, the console would flood with 100 extra lines of songs.
The last part is the presentation. When the song is chosen you want to bring the attention to the chosen one. This is what I did to achieve it (though you can get much, much more obnoxious.)
>> print('!' * 128) >> print('\n\n\n\t{}\n\n\n'.format(songName)) >> print('!' * 128)
All there is left is to bump up the font size a few times with ⌘+Plus (Or is it ⌘ + ”+”? Or ⌘ + ⇧ + = ? Or ⌘⇧+? Still need to figure out how to type keyboard shortcuts) and there you have it! There’s the shuffle feature that Ubisoft managed to cheap out on (this would be really embarrassing if I was wrong, so as a sanity check please let me know ASAP if there’s a “randomize next song” feature in Just Dance 2019).
Go forth and bust moves.
For the complete code, click here to check out the GitHub repo.
EDIT: OKAY, A BONUS CHALLENGE. Using the methods above count how many times I’ve written “Just Dance” in this page.