What is this?¶
malaffinity provides a simple way to calculate affinity (Pearson’s correlation * 100) between a “base” user and another user on MyAnimeList.
The term “base user” refers to the user whose scores other users’ scores will be compared to (and affinities to said scores calculated for).
Just assume the “base user” is referring to you, or whoever will be running your script, unless you’re getting into some advanced mumbo-jumbo, in which case you’re on your own.
malaffinity is meant to be used in bulk, where one user (the “base”)’s scores are compared against multiple people, but there’s nothing stopping you from using this as a one-off.
But why should I bother using this? Doesn’t MAL give me an affinity?¶
Let’s consider what you’d have to do if you wanted MAL to give you an affinity value, and a good estimation as to whether it’s “accurate” or not:
- Create a
- Make a
GETrequest to MAL’s login page
- Retrieve the
csrf_tokenfrom one of the
- Make a
POSTrequest to the login page, providing a username, password, a bunch of stupid form data, and the
csrf_tokenyou’ve just obtained
- Confirm you are logged in, by seeing if the
is_logged_incookie is present in the
- Visit a users’ profile
- Look for the affinity value (hint:
.user-compatability-graph .anime .bar-inner[sic])
- Read its
innerHTML, retrieve the affinity value, add a case in to get rid of the double-negative that appears on any negative value for some reason
- Find how many rated anime you share. The value MAL gives you includes unrated anime,
and PTW stuff. It’s not an accurate indicator
/shared.php?u1=you&u2=themand you find yourself trying to navigate through the dark and murky world of bad HTML table parsing
Congrats, you’ve just wasted a few hours of your life, and you’re probably a bit stressed right now. HTML parsing does that to you.
Let’s see how you could handle all this with
malaffinity, assuming your
Xinil and you want to calculate affinity with
from malaffinity import MALAffinity ma = MALAffinity("Xinil") affinity, shared = ma.calculate_affinity("Luna") # Do whatever you like with ``affinity`` and ``shared`` print(affinity) # 37.06659111674594 print(shared) # Note: Is referring to shared, rated anime # 171
ma now holds your scores. You can easily call
on anyone, and you’d get your affinity with them.
If you don’t want your scores to be stored, an option exists for quick, one-off calculations:
import malaffinity affinity, shared = malaffinity.calculate_affinity("Xinil", "Luna") # ...
I’m no expert, but the code(s) above looks a lot neater than the alternative would’ve looked.