Making transfers and substitutions using fpl!

in #fpl6 years ago






https://github.com/amosbastian/fpl

What is fpl?

It's a Python wrapper for the Fantasy Premier League, which is a fantasy football game - "a game in which participants assemble an imaginary team of real life footballers and score points based on those players' actual statistical performance or their perceived contribution on the field of play. " At the time of writing this post there are more than 6 million teams entered, which includes loads of people on Steem who are participating in Steem's very own league (see here).


It has been a while since the last update, but this is a big one - you can now transfer, substitute and captain players using fpl! I'm really excited about it, as I didn't think it was possible at first... However, after posting about fpl on Reddit (and getting some more cool stars on GitHub) someone messaged me saying he had implemented these features in PowerShell of all things, and gave me a rough outline on how I could implement it. So I set off to investigate!

https://github.com/amosbastian/fpl/pull/32
https://github.com/amosbastian/fpl/pull/33

Researching transfers

The person who helped me out with this mentioned that implementing the transfers would be the easier of the two, and so I started off with this. I logged into the website, opened up Chrome's developer tools and went to the transfer page. While monitoring the network tab and making a transfer I noticed the following:



The transfer payload

Exactly what I was looking for! Let's break it down:

  • confirm: Before making a transfer, the user has to press a button to confirm they actually want to go through with this, so the payload is first sent with this set to false.
  • entry: The user's ID.
  • event: The current gameweek.
  • freehit: When making transfers the user can decide that they want to play their "free hit" chip.
  • transfers: The list containing the actual transfer (who is being transferred out and who is being transferred in).
  • wildcard: Same as freehit, but for the "wildcard" chip.

With this information, creating the plan to implement it was simple. Basically, the user should supply a list of IDs of players they want to transfer out and in, and then the function should format everything correctly and send a POST request. Sounds pretty easy, right?

Implementing the transfer function


The transfer function with some code removed and some comments added

I've included the transfer() function above, with some error checking removed and some additional comments for whoever is reading this post. Basically what it does is take two lists of player IDs and then checks if everything is okay before sending the first POST request (for example, you can't transfer out a player who isn't in your team).

If everything is okay with the first POST request (FPL will provide an error themselves if this isn't the case), then confirmed is simply set to True and the request is sent again. It seems pretty simple, but it was quite a lot of trial and error (thankfully I have a dummy account I can use to test this kind of stuff).



Running a script to transfer Lingard for Brooks

Researching substitutions

This was a lot more difficult to implement, but easier to research, as making a substitution or changing your captain isn't as definitive as actually making a transfer. Basically I used the same method as above; I started making changes while inspecting the network tab. The payload this time was a dictionary with the key "picks", with a list of players as its value. Pretty easy to recreate, or so I thought...

Implementing the substitute function

The biggest pain with substitute function is the algorithm to re-organise the lineup. Each player has an initial position number so when you make a substitution, you give the substitute the position number of the player taken off. If they don't play in the same position, and they're not both substitutes, then the team needs to be shuffled around which is done by sorting by position + (element_type * 100).

So for example if you had Robertson with position number 3, and you want to substitute him with Aguero, who has the position number 14, then you'd do:

Aguero's new position number (3) + his element type (forward: 3) * 100 = 303

which will put him as the first of the forwards (as they'd have had position numbers of 10 and 11 so there numbers would be 310 and 311). I hope that sort of makes sense?

Of course, a normal thing to do when changing your lineup is also selecting a new captain and / or vice captain. This can also be done using the substitute() function, with some of its difficulty being in implementing its default behaviour. For example, if a captain is made the vice captain, then the current vice captain should become the new captain, and vice versa. Anyway, let's look at the function, which should hopefully make it a bit easier to understand!



The substitute function with some code removed and some comments added

It should be pretty straightforward what it does. Most of the work is done in the helper functions which actually set the captain and vice captain, and create the actual lineup.



Helper function for creating the lineup

As you can see it basically does everything that I described above about creating the lineup. Everything works great as far as I can tell, and it also made me realise something. It would be great to simply have a function to captain or vice captain a specific player, and so these functions were also added to the User class.



Substituting Rashford for Mkhitaryan and making Zaha the captain

Roadmap

I will be looking into if it's possible to add the functionality to play any of the user's chips, and see if it's possible to implement stuff like joining / leaving leagues and more. First of all I will be looking into adding some more tests for the substitute and transfer functions (before uploading the next version to PyPI), but it's pretty difficult figuring out how to do this properly. Also adding them to the CLI and allowing users to use the player's name instead of the ID would be nice as well.

Usage & installation

The recommended way to install fpl is via pip.

pip install fpl

To install it directly from GitHub you can do the following:

git clone git://github.com/amosbastian/fpl.git

You can also install a .tar file
or .zip file

$ curl -OL https://github.com/amosbastian/fpl/tarball/master
$ curl -OL https://github.com/amosbastian/fpl/zipball/master # Windows

Once it has been downloaded you can easily install it using pip::

$ cd fpl
$ pip install .

Contributing

  1. Fork the repository on GitHub.
  2. Run the tests with pytest tests/ to confirm they all pass on your system.
    If the tests fail, then try and find out why this is happening. If you aren't
    able to do this yourself, then don't hesitate to either create an issue on
    GitHub, contact me on Discord or send an email to [email protected].
  3. Either create your feature and then write tests for it, or do this the other
    way around.
  4. Run all tests again with with pytest tests/ to confirm that everything
    still passes, including your newly added test(s).
  5. Create a pull request for the main repository's master branch.

For more information on how to contribute to fpl see the contributing guide.

Documentation

Documentation and examples for fpl can be found at http://fpl.readthedocs.io/en/latest/.

Sort:  
  • Congratulations, this is a big one indeed. Great research and implementation.
  • Great use of animated gif, images and code samples to show case the improvements.
  • Awesome commit and code comments.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Chat with us on Discord.

[utopian-moderator]

Thanks Helo, it really opens up a lot of things for the package that I didn't think were possible before, so I'm pretty excited by it. Hopefully I can find some other stuff like this, and keep on gradually improving it!

Thank you for your review, @helo! Keep up the good work!

Hi @amosbastian!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hi @amosbastian!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hey, @amosbastian!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Coin Marketplace

STEEM 0.21
TRX 0.21
JST 0.035
BTC 91999.86
ETH 3131.58
USDT 1.00
SBD 3.08