footballmvp


Namefootballmvp JSON
Version 0.1.1 PyPI version JSON
download
home_pageNone
SummaryAnalytical tool to determine top performing football players (MVP) across leagues and tournaments.
upload_time2025-07-27 05:41:25
maintainerNone
docs_urlNone
authorNone
requires_python>=3.12
licenseNone
keywords football soccer mvp analytics sports
VCS
bugtrack_url
requirements appnope asttokens attrs beautifulsoup4 bs4 certifi charset-normalizer comm contourpy cycler debugpy decorator executing fonttools h11 idna ipykernel ipython jedi jupyter_client jupyter_core kiwisolver matplotlib matplotlib-inline nest-asyncio numpy outcome packaging pandas parso pexpect pillow platformdirs prompt_toolkit psutil ptyprocess pure_eval py4j Pygments pyparsing PySocks pyspark python-dateutil pytz pyzmq requests selenium setuptools six sniffio sortedcontainers soupsieve stack-data tornado traitlets trio trio-websocket typing_extensions tzdata urllib3 wcwidth websocket-client wsproto
Travis-CI No Travis.
coveralls test coverage No coveralls.
            FootballMVP
An analytics program to find the top-performing players (MVPs) in football leagues and tournaments.

What is Soccer MVP Analyzer?
This project calculates the Most Valuable Player (MVP) for professional football leagues and tournaments using player performance statistics.

Think of it as a custom analytics engine that scrapes, cleans, processes, and visualizes soccer player data to answer:

"Who’s really been the MVP this season?"

Getting Started
1. Clone the Project
Choose your workflow:

Option A: Clone (For engineers)
git clone https://github.com/YOUR_USERNAME/FootballMVPAPI.git


Option B: Fork (For contributors)
Fork the repo on GitHub, then clone your fork:
git clone https://github.com/YOUR_USERNAME/FootballMVPAPI.git


Option C: Install via pip (For developers)
pip install FootballMVP
pip install -r requirements.txt
python mvp_comp_dir/mvp_run.py


2. Setup Your Environment
Python Version: 3.12 (Required)

Install dependencies:
pip install -r requirements.txt
Using pyenv (recommended):
pyenv install 3.12.4
pyenv virtualenv 3.12.4 soccer-mvp-env
pyenv activate soccer-mvp-env
pip install -r requirements.txt
Troubleshooting:
If you see ModuleNotFoundError: No module named 'distutils', run:
pip install setuptools


3. Install Java (Needed for PySpark)
Install Java 11:
brew install openjdk@11
Verify Java version:
java --version
Link Java with Homebrew:


sudo ln -sfn /opt/homebrew/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk
Add to your shell config (.zshrc or .bashrc):

---

Pyenv setup
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"

Initialize pyenv and pyenv-virtualenv
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

Java setup for PySpark (force Java 11)
export JAVA_HOME="/opt/homebrew/opt/openjdk@11"
export PATH="$JAVA_HOME/bin:$PATH"
Reload your shell:


source ~/.zshrc


---

### 3. Input Parameters (Function Call)

```python
def compute_mvp(
    competition_name: str,             # Required
    competition_year: str,             # Required
    scalar: int = 4,                   # Optional
    open_close_league: str = "",       # Optional
    overide: bool = True,              # Optional
    title: str = "",                   # Optional
    percentile_threshold: float = .98, # Optional
    manual_competition_id: str = ""    # Optional
) -> str:
```

---


### Add Competition to Watchlist

* If already in list:

```python
print(all_comps.add_competition_to_my_watchlist(competition_name="mls", gather_all_competition_ids=all_comp_info))
```

* If NOT in list (custom URL):

```python
print(all_comps.add_competition_to_my_watchlist(
    competition_name="", 
    gather_all_competition_ids=all_comp_info, 
    defined_url="https://www.fotmob.com/leagues/55/matches/serie"
))
```

### Run with optional arguements:

#### Only Required Params:

```python
print(workflow_compute_mvp(competition_name="mls", competition_year="2023"))
print(workflow_compute_mvp(competition_name="serie", competition_year="2024-2025"))
```

#### Custom Scalar

```python
print(mvp.compute_mvp(competition_name="fifa-intercontinental-cup", competition_year="2024", scalar=14))
```

#### Two Leagues Per Year

```python
print(workflow_compute_mvp(competition_name="liga-mx", competition_year="2024-2025", open_close_league="Apertura"))
print(workflow_compute_mvp(competition_name="liga-mx", competition_year="2024-2025", open_close_league="Clausura"))
```

#### Memoization Without Override

```python
print(workflow_compute_mvp(competition_name="canadian-championship", competition_year="2025", overide=False))
```

#### Custom Table Title

```python
print(workflow_compute_mvp(competition_name="concacaf-champions-cup", competition_year="2025", title="Top Performing Players for North American Football Clubs"))
```

#### Custom Percentile Threshold

```python
mvp = MVP()
print(mvp.compute_mvp(competition_name="serie", competition_year="2024-2025", percentile_threshold=.97, title="Top 3% MVPs for Serie-A in 2024-2025"))
```

#### Use Manual Competition ID

```python
print(all_comps.add_competition_to_my_watchlist(competition_name="", gather_all_competition_ids=all_comp_info, defined_url="https://www.fotmob.com/leagues/47/matches/premier-league"))
print(workflow_compute_mvp(competition_name="premier-league", competition_year="2016-2017", manual_competition_id="47"))

print(all_comps.add_competition_to_my_watchlist(competition_name="", gather_all_competition_ids=all_comp_info, defined_url="https://www.fotmob.com/leagues/9986/matches/premier-league"))
print(workflow_compute_mvp(competition_name="premier-league", competition_year="2019", manual_competition_id="9986"))
```

### Sample Code:
    - Add Competitions:

        - Internationianl - Countries
            - print(all_comps.add_competition_to_my_watchlist(competition_name="concacaf-gold-cup", gather_all_competition_ids=all_comp_info, defined_url="https://www.fotmob.com/leagues/298/matches/concacaf-gold-cup"))
            - print(all_comps.add_competition_to_my_watchlist(competition_name="euro", gather_all_competition_ids=all_comp_info))
            - print(all_comps.add_competition_to_my_watchlist(competition_name="concacaf-nations-league", gather_all_competition_ids=all_comp_info))
            - print(all_comps.add_competition_to_my_watchlist(competition_name="uefa-nations-league-a", gather_all_competition_ids=all_comp_info))
            - print(all_comps.add_competition_to_my_watchlist(competition_name="uefa-nations-league-b", gather_all_competition_ids=all_comp_info))
            - print(all_comps.add_competition_to_my_watchlist(competition_name="uefa-nations-league-c", gather_all_competition_ids=all_comp_info))
            - print(all_comps.add_competition_to_my_watchlist(competition_name="uefa-nations-league-d", gather_all_competition_ids=all_comp_info))
            - print(all_comps.add_competition_to_my_watchlist(competition_name="copa-america", gather_all_competition_ids=all_comp_info))
            - print(all_comps.add_competition_to_my_watchlist(competition_name="summer-olympics", gather_all_competition_ids=all_comp_info))
            - print(all_comps.add_competition_to_my_watchlist(competition_name="world-cup", gather_all_competition_ids=all_comp_info, defined_url="https://www.fotmob.com/leagues/77/matches/world-cup"))


        - International - Clubs
            - print(all_comps.add_competition_to_my_watchlist(competition_name="europa-league", gather_all_competition_ids=all_comp_info, defined_url="https://www.fotmob.com/leagues/78/matches/fifa-club-world-cup"))
            - print(all_comps.add_competition_to_my_watchlist(competition_name="afc-champions-league-elite", gather_all_competition_ids=all_comp_info))
            - print(all_comps.add_competition_to_my_watchlist(competition_name="champions-league", gather_all_competition_ids=all_comp_info))
            - print(all_comps.add_competition_to_my_watchlist(competition_name="concacaf-champions-cup", gather_all_competition_ids=all_comp_info))
            - print(all_comps.add_competition_to_my_watchlist(competition_name="concacaf-gold-cup", gather_all_competition_ids=all_comp_info))

        - Countries
            - Austria 
                - print(all_comps.add_competition_to_my_watchlist(competition_name="eredivisie", gather_all_competition_ids=all_comp_info, defined_url="https://www.fotmob.com/leagues/38/matches/bundesliga"))
            - Canada
                - print(all_comps.add_competition_to_my_watchlist(competition_name="canadian-championship", gather_all_competition_ids=all_comp_info))
                - print(all_comps.add_competition_to_my_watchlist(competition_name="premier-league", gather_all_competition_ids=all_comp_info))
            - England
                - print(all_comps.add_competition_to_my_watchlist(competition_name="", gather_all_competition_ids=all_comp_info, defined_url="https://www.fotmob.com/leagues/47/matches/premier-league"))
                - print(all_comps.add_competition_to_my_watchlist(competition_name="", gather_all_competition_ids=all_comp_info, defined_url="https://www.fotmob.com/leagues/9986/matches/premier-league"))
                - print(all_comps.add_competition_to_my_watchlist(competition_name="fa-cup", gather_all_competition_ids=all_comp_info))
            - France 
                - print(all_comps.add_competition_to_my_watchlist(competition_name="ligue-1", gather_all_competition_ids=all_comp_info))
                - print(all_comps.add_competition_to_my_watchlist(competition_name="coupe-de-france", gather_all_competition_ids=all_comp_info))
            - Germany
                - print(all_comps.add_competition_to_my_watchlist(competition_name="bundesliga", gather_all_competition_ids=all_comp_info, defined_url="https://www.fotmob.com/leagues/54/matches/bundesliga"))
                - print(all_comps.add_competition_to_my_watchlist(competition_name="dfb-pokal", gather_all_competition_ids=all_comp_info))
            - Italy 
                - print(all_comps.add_competition_to_my_watchlist(competition_name="serie", gather_all_competition_ids=all_comp_info, defined_url="https://www.fotmob.com/leagues/55/matches/serie"))
                - print(all_comps.add_competition_to_my_watchlist(competition_name="coppa-italia", gather_all_competition_ids=all_comp_info))
            - Mexico
                - print(all_comps.add_competition_to_my_watchlist(competition_name="liga-mx", gather_all_competition_ids=all_comp_info, defined_url="https://www.fotmob.com/leagues/230/matches/liga-mx"))
            - Netherlands
                - print(all_comps.add_competition_to_my_watchlist(competition_name="eredivisie", gather_all_competition_ids=all_comp_info, defined_url="https://www.fotmob.com/leagues/57/matches"))
            - Saudi Arabia
                - print(all_comps.add_competition_to_my_watchlist(competition_name="saudi-pro-league", gather_all_competition_ids=all_comp_info))
            - Scotland
                - print(all_comps.add_competition_to_my_watchlist(competition_name="premiership", gather_all_competition_ids=all_comp_info, defined_url="https://www.fotmob.com/leagues/64/matches"))
                - print(all_comps.add_competition_to_my_watchlist(competition_name="fifa-intercontinental-cup", gather_all_competition_ids=all_comp_info))
            - Spain
                - print(all_comps.add_competition_to_my_watchlist(competition_name="laliga", gather_all_competition_ids=all_comp_info))
                - print(all_comps.add_competition_to_my_watchlist(competition_name="copa-del-rey", gather_all_competition_ids=all_comp_info))
            - USA
                - print(all_comps.add_competition_to_my_watchlist(competition_name="mls", gather_all_competition_ids=all_comp_info))
                - print(all_comps.add_competition_to_my_watchlist(competition_name="open-cup", gather_all_competition_ids=all_comp_info))


    - Run MVP Program:
        - International - Countries
            - print(workflow_compute_mvp(competition_name="concacaf-gold-cup", competition_year="2025", scalar=14))
            - print(workflow_compute_mvp(competition_name="euro", competition_year="2024", scalar=14))
            - print(workflow_compute_mvp(competition_name="concacaf-nations-league", competition_year="2024-2025", scalar=14))
            - print(workflow_compute_mvp(competition_name="uefa-nations-league-a", competition_year="2024-2025", scalar=14))
            - print(workflow_compute_mvp(competition_name="uefa-nations-league-b", competition_year="2024-2025", scalar=14))
            - print(workflow_compute_mvp(competition_name="uefa-nations-league-c", competition_year="2024-2025", scalar=14))
            - print(workflow_compute_mvp(competition_name="uefa-nations-league-d",competition_year= "2024-2025", scalar=14))
            - print(workflow_compute_mvp(competition_name="copa-america", competition_year="2024", scalar=14))
            - print(workflow_compute_mvp(competition_name="summer-olympics", competition_year="2024", scalar=14))
            - print(workflow_compute_mvp(competition_name="world-cup", competition_year="2022", manual_competition_id="77", scalar=14))

        - International - Clubs
            - print(workflow_compute_mvp(competition_name="fifa-club-world-cup", competition_year="2025", scalar=14))
            - print(workflow_compute_mvp(competition_name="europa-league", competition_year="2024-2025", scalar=14))
            - print(workflow_compute_mvp(competition_name="afc-champions-league-elite", competition_year="2024-2025", scalar=14))
            - print(workflow_compute_mvp(competition_name="champions-league", competition_year="2024-2025", scalar=14))
            - print(workflow_compute_mvp(competition_name="concacaf-champions-cup", competition_year="2025", scalar=14))
            - print(workflow_compute_mvp(competition_name="concacaf-gold-cup", competition_year="2025", scalar=14))
        - Countries:
            - Austria
                - print(workflow_compute_mvp(competition_name="eredivisie", competition_year="2024-2025")) 
            - Canada
                - print(workflow_compute_mvp(competition_name="canadian-championship", competition_year="2025", scalar=14))
                - print(workflow_compute_mvp(competition_name="premier-league", competition_year="2025", manual_competition_id="9986"))
            - England
                - print(workflow_compute_mvp(competition_name="premier-league", competition_year="2024-2025", manual_competition_id="47"))
                - print(workflow_compute_mvp(competition_name="fa-cup", competition_year="2024-2025", scalar=14))
            - France
                - print(workflow_compute_mvp(competition_name="ligue-1", competition_year="2024-2025", manual_competition_id="53"))
                - print(workflow_compute_mvp(competition_name="coupe-de-france", competition_year="2024-2025", scalar=14))
            - Germany
                - print(workflow_compute_mvp(competition_name="bundesliga", competition_year="2024-2025", manual_competition_id="54"))
                - print(workflow_compute_mvp(competition_name="dfb-pokal", competition_year="2024-2025", scalar=14))
            - Italy
                - print(mvp.compute_mvp(competition_name="serie", competition_year="2024-2025", manual_competition_id="55")) 
                - print(workflow_compute_mvp(competition_name="coppa-italia", competition_year="2024-2025", scalar=14))
            - Mexico
                - print(workflow_compute_mvp(competition_name="liga-mx", competition_year="2023-2024", open_close_league="Apertura")) 
                - print(workflow_compute_mvp(competition_name="liga-mx", competition_year="2023-2024", open_close_league="Clausura")) 
            - Netherlands
                - print(workflow_compute_mvp(competition_name="eredivisie", competition_year="2024-2025", manual_competition_id="57"))  
            - Saudi Arabia
                - print(workflow_compute_mvp(competition_name="saudi-pro-league", competition_year="2024-2025"))        
            - Scotland
                - print(workflow_compute_mvp(competition_name="premiership", competition_year="2024-2025"))             
            - Spain
                - print(workflow_compute_mvp(competition_name="laliga", competition_year="2024-2025"))   
                - print(workflow_compute_mvp(competition_name="copa-del-rey", competition_year="2024-2025", scalar=14))         
            - USA
                - print(workflow_compute_mvp(competition_name="open-cup", competition_year="2025", scalar=14))
                - print(workflow_compute_mvp(competition_name="mls", competition_year="2025"))        
            
        
    - Step-by-Step
        - List all available competitions (Note: if a competition is not available, include a defined_url arguement)
            - all_comps = AllCompetitions()
            - all_comp_info = all_comps.gather_all_competition_ids("https://www.fotmob.com/") # run
            - print(all_comp_info)

        - Chooses the competition 
            - comps = Competition()
            - print(comps.choose_competition(competition_name="mls", competition_year="2023"))

        - Test this out later to extract player info from new html setup 
            - match = Match()
            - print(match.extract_single_match_players_stats("https://www.fotmob.com/matches/toronto-fc-vs-fc-cincinnati/3vaemjyi#4085040"))
            - print(match.choose_match(competition_name="mls", competition_year="2023"))

        - Extract player stats and compute both the total of games played and average SPI score for only games with SPI scores included. 
            - player = Player()
            - print(player.choose_player_stats(competition_name="mls", competition_year="2023"))
            - print(player.competition_analysis(competition_name="mls", competition_year="2023"))

        - Runs all the steps above
            - mvp = MVP()
            - print(mvp.compute_mvp(competition_name="mls", competition_year="2023", scalar=4))





## How a Player Receives an SPI Score:

Only players who receive an SPI score are considered to have officially played in a match. 
While the exact time required for a score isn't fully confirmed, starting players typically 
need to play just a few minutes to earn an SPI for that match. On the other hand, substitutes 
must play for approximately 10 minutes to qualify for a score.

Substitute players who play less than the required time or those who are injured shortly after 
entering the game will not receive an SPI score. Initially, I considered assigning a default 
starting score (likely around 6.0 or 7.0, which is what I think a player starts off anyways) to any competitor who participated in the match but didn’t earn 
a score. However, this approach raised concerns: for instance, a player who scores a goal and 
one who concedes an own-goal would both receive the same starting score, which seems inappropriate.

To maintain consistency, this MVP program will only consider a match as "played" if a player has been assigned an SPI rating. 

The FotMob player rating is calculated based on more than 100 individual stats per player per match

---

All Competition names and ids (i.e. all_comp_info):

{'38': 'bundesliga', '40': 'first-division-a', '42': 'champions-league', '43': 'confederation-cup', '44': 'copa-america', '45': 'copa-libertadores', '46': 'superligaen', '48': 'championship', '50': 'euro', '51': 'veikkausliiga', '57': 'eredivisie', '58': 'eredivisie', '64': 'premiership', '65': 'summer-olympics-women', '66': 'summer-olympics', '68': 'allsvenskan', '69': 'super-league', '73': 'europa-league', '85': '1-division', '86': 'serie-b', '108': 'league-one', '109': 'league-two', '112': 'liga-profesional', '113': 'a-league', '114': 'friendlies', '116': 'cymru-premier', '117': 'national-league', '119': '2-liga', '120': 'super-league', '121': 'primera-division', '122': '1-liga', '123': 'championship', '124': 'league-one', '125': 'league-two', '127': 'ligat-haal', '128': 'leumit-league', '129': 'premiership', '130': 'mls', '131': 'liga-1', '132': 'fa-cup', '135': 'super-league-1', '136': '1-division', '137': 'scottish-cup', '140': 'laliga2', '141': 'coppa-italia', '142': 'efl-trophy', '143': 'suomen-cup', '144': 'primera-division', '145': 'greece-cup', '147': 'serie-c', '150': 'coupe-de-la-ligue', '151': 'turkish-cup', '161': 'primera-division', '163': 'challenge-league', '169': 'ettan', '171': 'svenska-cupen', '176': '1-liga', '179': 'challenge-cup', '180': 'league-cup', '181': 'premiership-playoff', '182': 'super-liga', '187': 'league-cup', '189': 'liga-i', '190': 'cupa-româniei', '193': 'russian-cup', '196': 'ekstraklasa', '199': 'division-profesional', '204': 'postnord-ligaen', '205': 'norsk-tipping-ligaen', '207': 'trophée-des-champions', '209': 'dfb-pokal', '215': 'besta-deildin', '217': 'icelandic-cup', '218': 'first-division', '224': 'j-league-cup', '225': 'premier-league', '230': 'liga-mx', '231': 'national-division', '239': '2-division', '240': '3-division', '241': 'danmarksserien', '246': 'serie-a', '251': 'ykkosliiga', '256': 'kvindeligaen', '263': 'premier-league', '264': 'first-division-b', '267': 'premier-league', '270': 'first-professional-league', '273': 'primera-division', '274': 'categoría-primera-a', '287': 'euro-u19', '288': 'euro-u21', '290': 'asian-cup', '292': "women's-euro", '293': "women's-friendlies", '297': 'concacaf-champions-cup', '298': 'concacaf-gold-cup', '299': 'copa-sudamericana', '300': 'east-asian-championship', '301': 'european-championship-u-17', '305': 'toulon-tournament', '329': 'gulf-cup', '331': 'toppserien', '332': '1-division-kvinner', '335': 'primera-division', '336': 'liga-nacional', '337': 'liga-nacional', '338': '1-division', '339': 'primera-division', '342': 'finland-cup', '441': 'premier-league', '489': 'club-friendlies', '512': 'regionalliga', '519': 'premier-league', '524': 'stars-league', '525': 'afc-champions-league-elite', '526': 'caf-champions-league', '529': 'premier-league', '533': 'professional-football-league', '537': 'premier-soccer-league', '544': 'ligue-i', '8815': 'super-league-2', '8870': 'championship', '8944': 'national-north-&-south', '8947': 'premier-division', '8965': 'primera-b-nacional', '8968': 'primera-federación', '8969': 'ykkonen', '8971': 'serie-c', '8973': '2-liga', '8974': 'j-league-2', '8976': 'liga-de-expansión-mx', '8980': 'brazil-state-championship', '9015': 'liga-primera', '9039': 'lpf', '9080': 'k-league-1', '9081': 'bundesliga', '9100': '2-division', '9112': 'liga-3', '9113': 'liga-ii', '9116': 'k-league-2', '9122': 'segunda-division', '9123': 'second-league', '9125': 'primera-b', '9126': 'primera-b', '9134': 'nwsl', '9137': 'china-league-one', '9138': 'segunda-federación', '9141': 'germany-5', '9143': 'singapore-cup', '9210': 'france-4', '9213': 'primera-b-metropolitana-&-torneo-federal-a', '9253': 'fa-trophy', '9265': 'asean-championship', '9294': "women's-championship", '9296': 'usl-league-one', '9305': 'copa-argentina', '9306': 'cecafa-cup', '9345': 'copa-mx', '9375': "women's-champions-league", '9382': 'toppserien-qualification', '9390': 'west-asian-championship', '9391': 'copa-mx-clausura', '9408': 'international-champions-cup', '9422': 'k-league', '9428': 'african-nations-championship', '9429': 'copa-do-nordeste', '9441': 'open-cup', '9468': 'caf-confed-cup', '9469': 'afc-champions-league-two', '9470': 'afc-challenge-league', '9474': 'mtn8', '9478': 'indian-super-league', '9494': 'usl-league-two', '9495': 'a-league-women', '9500': 'we-league-women', '9514': 'the-atlantic-cup', '9537': 'k-league-3', '9545': 'highland-/-lowland', '9579': 'algarve-cup-qualification', '9656': 'concacaf-championship-u20', '9682': 'concacaf-central-american-cup', '9690': 'southeast-asian-games', '9717': "women's-league-cup", '9741': 'uefa-youth-league', '9754': 'obos-ligaen', '9806': 'uefa-nations-league-a', '9807': 'uefa-nations-league-b', '9808': 'uefa-nations-league-c', '9809': 'uefa-nations-league-d', '9821': 'concacaf-nations-league', '9833': 'asian-games', '9837': 'canadian-championship', '9841': 'afc-u20-asian-cup', '9876': 'saff-championship', '9906': 'liga-mx-femenil', '9907': 'liga-f', '9921': 'shebelieves-cup-qualification', '9986': 'premier-league', '10007': 'copa-de-la-liga-profesional', '10022': 'regionalliga', '10043': 'leagues-cup', '10046': 'copa-ecuador', '10056': 'liga-2', '10075': 'torneo-de-verano', '10076': 'league-cup', '10082': 'fa-cup-women', '10084': 'nisa', '10145': 'footballs-staying-home-cup-(esports)', '10167': 'nwsl-challenge-cup', '10176': 'premier-league-2-div-2', '10178': 'serie-a-femminile', '10188': 'k-league-3', '10207': 'nisa-legends-cup', '10216': 'conference-league', '10242': 'fifa-arab-cup', '10244': 'paulista-a1', '10269': 'womens-asian-cup', '10270': 'league-cup', '10272': 'carioca', '10273': 'mineiro', '10274': 'gaúcho', '10290': 'baiano', '10291': 'goiano', '10304': 'finalissima', '10309': 'durand-cup', '10310': 'stars-league-relegation-playoff', '10325': 'preseason', '10366': 'super-cup', '10368': 'copa-america-femenina', '10437': 'euro-u-21', '10449': 'nacional-feminino', '10457': "uefa-women's-nations-league-a", '10458': 'uefa-nations-league-b-women', '10459': 'uefa-nations-league-c-women', '10474': 'arab-club-champions-cup', '10498': 'summer-olympics-concacaf-qualification', '10508': 'african-football-league', '10511': 'afc-summer-olympics-women', '10584': 'south-africa-league', '10603': 'concacaf-gold-cup-women', '10607': 'euro', '10609': 'asian-cup--playoff', '10610': 'concafaf-gold-cup', '10611': 'champions-league', '10612': "women's-champions-league", '10613': 'europa-league', '10615': 'conference-league', '10616': 'euro-u19', '10617': 'euro-u17', '10618': 'copa-libertadores', '10619': 'caf-champions-league', '10621': 'concacaf-championship-u20', '10622': 'afc-champions-league-elite', '10623': 'copa-sudamericana', '10640': "women's-euro-league-a", '10641': "women's-euro-league-b", '10642': "women's-euro-league-c", '10649': 'nwsl-x-liga-mx', '10651': 'copa-de-la-reina', '10654': 'usl-jägermeister-cup', '10699': 'usl-super-league-women', '10703': 'fifa-intercontinental-cup', '10705': 'national-league-cup', '10708': 'knockout-cup', '10717': 'uefa-nations-league-a', '10718': 'uefa-nations-league-b', '10719': 'uefa-nations-league-c', '10791': 'swpl-1', '10840': 'baller-league', '10844': 'baller-league', '10872': 'northern-super-league'}

---

Resource: 
- (Fotmob Homepage) - */https://www.fotmob.com/*

- (Install Pyspark) - */https://medium.com/@jpurrutia95/install-and-set-up-pyspark-in-5-minutes-m1-mac-eb415fe623f3/*

---

### Potential Contributions:
- Add a CI/CD pipeline (e.g. Github Actions - pytest, flake8, isort, black, docker build)
- Cloud data storage functionality
- Unit Tests

### Possibilites to optimize the MVP algorithm
- Add more weighted features:
    - players
        - avg spi for all (or specific) competitions
        - avg spi from past N years/months/weeks/games 
    - teams
    - leagues or tournaments
    - countries
    - continents 
    - match type 
        - e.g. 
            - "finalTournament":"Final","bronzeFinal":"Bronze-final","semifinal":"Semi-final","quarterfinal":"Quarter-final","roundof16":"Round of 16","h2h":"Head-to-Head","bracket":"Bracket"

---

Made by Drue Tomas Staples



            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "footballmvp",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": null,
    "keywords": "football, soccer, mvp, analytics, sports",
    "author": null,
    "author_email": "Drue Staples <druestaples@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/99/39/4b2a991e9a4abb4695286812dd9bc58ddd95ba9bb3eed0fa7f05d7b322de/footballmvp-0.1.1.tar.gz",
    "platform": null,
    "description": "FootballMVP\nAn analytics program to find the top-performing players (MVPs) in football leagues and tournaments.\n\nWhat is Soccer MVP Analyzer?\nThis project calculates the Most Valuable Player (MVP) for professional football leagues and tournaments using player performance statistics.\n\nThink of it as a custom analytics engine that scrapes, cleans, processes, and visualizes soccer player data to answer:\n\n\"Who\u2019s really been the MVP this season?\"\n\nGetting Started\n1. Clone the Project\nChoose your workflow:\n\nOption A: Clone (For engineers)\ngit clone https://github.com/YOUR_USERNAME/FootballMVPAPI.git\n\n\nOption B: Fork (For contributors)\nFork the repo on GitHub, then clone your fork:\ngit clone https://github.com/YOUR_USERNAME/FootballMVPAPI.git\n\n\nOption C: Install via pip (For developers)\npip install FootballMVP\npip install -r requirements.txt\npython mvp_comp_dir/mvp_run.py\n\n\n2. Setup Your Environment\nPython Version: 3.12 (Required)\n\nInstall dependencies:\npip install -r requirements.txt\nUsing pyenv (recommended):\npyenv install 3.12.4\npyenv virtualenv 3.12.4 soccer-mvp-env\npyenv activate soccer-mvp-env\npip install -r requirements.txt\nTroubleshooting:\nIf you see ModuleNotFoundError: No module named 'distutils', run:\npip install setuptools\n\n\n3. Install Java (Needed for PySpark)\nInstall Java 11:\nbrew install openjdk@11\nVerify Java version:\njava --version\nLink Java with Homebrew:\n\n\nsudo ln -sfn /opt/homebrew/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk\nAdd to your shell config (.zshrc or .bashrc):\n\n---\n\nPyenv setup\nexport PYENV_ROOT=\"$HOME/.pyenv\"\nexport PATH=\"$PYENV_ROOT/bin:$PATH\"\n\nInitialize pyenv and pyenv-virtualenv\neval \"$(pyenv init --path)\"\neval \"$(pyenv init -)\"\neval \"$(pyenv virtualenv-init -)\"\n\nJava setup for PySpark (force Java 11)\nexport JAVA_HOME=\"/opt/homebrew/opt/openjdk@11\"\nexport PATH=\"$JAVA_HOME/bin:$PATH\"\nReload your shell:\n\n\nsource ~/.zshrc\n\n\n---\n\n### 3. Input Parameters (Function Call)\n\n```python\ndef compute_mvp(\n    competition_name: str,             # Required\n    competition_year: str,             # Required\n    scalar: int = 4,                   # Optional\n    open_close_league: str = \"\",       # Optional\n    overide: bool = True,              # Optional\n    title: str = \"\",                   # Optional\n    percentile_threshold: float = .98, # Optional\n    manual_competition_id: str = \"\"    # Optional\n) -> str:\n```\n\n---\n\n\n### Add Competition to Watchlist\n\n* If already in list:\n\n```python\nprint(all_comps.add_competition_to_my_watchlist(competition_name=\"mls\", gather_all_competition_ids=all_comp_info))\n```\n\n* If NOT in list (custom URL):\n\n```python\nprint(all_comps.add_competition_to_my_watchlist(\n    competition_name=\"\", \n    gather_all_competition_ids=all_comp_info, \n    defined_url=\"https://www.fotmob.com/leagues/55/matches/serie\"\n))\n```\n\n### Run with optional arguements:\n\n#### Only Required Params:\n\n```python\nprint(workflow_compute_mvp(competition_name=\"mls\", competition_year=\"2023\"))\nprint(workflow_compute_mvp(competition_name=\"serie\", competition_year=\"2024-2025\"))\n```\n\n#### Custom Scalar\n\n```python\nprint(mvp.compute_mvp(competition_name=\"fifa-intercontinental-cup\", competition_year=\"2024\", scalar=14))\n```\n\n#### Two Leagues Per Year\n\n```python\nprint(workflow_compute_mvp(competition_name=\"liga-mx\", competition_year=\"2024-2025\", open_close_league=\"Apertura\"))\nprint(workflow_compute_mvp(competition_name=\"liga-mx\", competition_year=\"2024-2025\", open_close_league=\"Clausura\"))\n```\n\n#### Memoization Without Override\n\n```python\nprint(workflow_compute_mvp(competition_name=\"canadian-championship\", competition_year=\"2025\", overide=False))\n```\n\n#### Custom Table Title\n\n```python\nprint(workflow_compute_mvp(competition_name=\"concacaf-champions-cup\", competition_year=\"2025\", title=\"Top Performing Players for North American Football Clubs\"))\n```\n\n#### Custom Percentile Threshold\n\n```python\nmvp = MVP()\nprint(mvp.compute_mvp(competition_name=\"serie\", competition_year=\"2024-2025\", percentile_threshold=.97, title=\"Top 3% MVPs for Serie-A in 2024-2025\"))\n```\n\n#### Use Manual Competition ID\n\n```python\nprint(all_comps.add_competition_to_my_watchlist(competition_name=\"\", gather_all_competition_ids=all_comp_info, defined_url=\"https://www.fotmob.com/leagues/47/matches/premier-league\"))\nprint(workflow_compute_mvp(competition_name=\"premier-league\", competition_year=\"2016-2017\", manual_competition_id=\"47\"))\n\nprint(all_comps.add_competition_to_my_watchlist(competition_name=\"\", gather_all_competition_ids=all_comp_info, defined_url=\"https://www.fotmob.com/leagues/9986/matches/premier-league\"))\nprint(workflow_compute_mvp(competition_name=\"premier-league\", competition_year=\"2019\", manual_competition_id=\"9986\"))\n```\n\n### Sample Code:\n    - Add Competitions:\n\n        - Internationianl - Countries\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"concacaf-gold-cup\", gather_all_competition_ids=all_comp_info, defined_url=\"https://www.fotmob.com/leagues/298/matches/concacaf-gold-cup\"))\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"euro\", gather_all_competition_ids=all_comp_info))\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"concacaf-nations-league\", gather_all_competition_ids=all_comp_info))\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"uefa-nations-league-a\", gather_all_competition_ids=all_comp_info))\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"uefa-nations-league-b\", gather_all_competition_ids=all_comp_info))\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"uefa-nations-league-c\", gather_all_competition_ids=all_comp_info))\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"uefa-nations-league-d\", gather_all_competition_ids=all_comp_info))\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"copa-america\", gather_all_competition_ids=all_comp_info))\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"summer-olympics\", gather_all_competition_ids=all_comp_info))\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"world-cup\", gather_all_competition_ids=all_comp_info, defined_url=\"https://www.fotmob.com/leagues/77/matches/world-cup\"))\n\n\n        - International - Clubs\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"europa-league\", gather_all_competition_ids=all_comp_info, defined_url=\"https://www.fotmob.com/leagues/78/matches/fifa-club-world-cup\"))\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"afc-champions-league-elite\", gather_all_competition_ids=all_comp_info))\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"champions-league\", gather_all_competition_ids=all_comp_info))\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"concacaf-champions-cup\", gather_all_competition_ids=all_comp_info))\n            - print(all_comps.add_competition_to_my_watchlist(competition_name=\"concacaf-gold-cup\", gather_all_competition_ids=all_comp_info))\n\n        - Countries\n            - Austria \n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"eredivisie\", gather_all_competition_ids=all_comp_info, defined_url=\"https://www.fotmob.com/leagues/38/matches/bundesliga\"))\n            - Canada\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"canadian-championship\", gather_all_competition_ids=all_comp_info))\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"premier-league\", gather_all_competition_ids=all_comp_info))\n            - England\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"\", gather_all_competition_ids=all_comp_info, defined_url=\"https://www.fotmob.com/leagues/47/matches/premier-league\"))\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"\", gather_all_competition_ids=all_comp_info, defined_url=\"https://www.fotmob.com/leagues/9986/matches/premier-league\"))\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"fa-cup\", gather_all_competition_ids=all_comp_info))\n            - France \n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"ligue-1\", gather_all_competition_ids=all_comp_info))\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"coupe-de-france\", gather_all_competition_ids=all_comp_info))\n            - Germany\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"bundesliga\", gather_all_competition_ids=all_comp_info, defined_url=\"https://www.fotmob.com/leagues/54/matches/bundesliga\"))\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"dfb-pokal\", gather_all_competition_ids=all_comp_info))\n            - Italy \n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"serie\", gather_all_competition_ids=all_comp_info, defined_url=\"https://www.fotmob.com/leagues/55/matches/serie\"))\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"coppa-italia\", gather_all_competition_ids=all_comp_info))\n            - Mexico\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"liga-mx\", gather_all_competition_ids=all_comp_info, defined_url=\"https://www.fotmob.com/leagues/230/matches/liga-mx\"))\n            - Netherlands\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"eredivisie\", gather_all_competition_ids=all_comp_info, defined_url=\"https://www.fotmob.com/leagues/57/matches\"))\n            - Saudi Arabia\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"saudi-pro-league\", gather_all_competition_ids=all_comp_info))\n            - Scotland\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"premiership\", gather_all_competition_ids=all_comp_info, defined_url=\"https://www.fotmob.com/leagues/64/matches\"))\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"fifa-intercontinental-cup\", gather_all_competition_ids=all_comp_info))\n            - Spain\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"laliga\", gather_all_competition_ids=all_comp_info))\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"copa-del-rey\", gather_all_competition_ids=all_comp_info))\n            - USA\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"mls\", gather_all_competition_ids=all_comp_info))\n                - print(all_comps.add_competition_to_my_watchlist(competition_name=\"open-cup\", gather_all_competition_ids=all_comp_info))\n\n\n    - Run MVP Program:\n        - International - Countries\n            - print(workflow_compute_mvp(competition_name=\"concacaf-gold-cup\", competition_year=\"2025\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"euro\", competition_year=\"2024\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"concacaf-nations-league\", competition_year=\"2024-2025\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"uefa-nations-league-a\", competition_year=\"2024-2025\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"uefa-nations-league-b\", competition_year=\"2024-2025\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"uefa-nations-league-c\", competition_year=\"2024-2025\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"uefa-nations-league-d\",competition_year= \"2024-2025\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"copa-america\", competition_year=\"2024\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"summer-olympics\", competition_year=\"2024\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"world-cup\", competition_year=\"2022\", manual_competition_id=\"77\", scalar=14))\n\n        - International - Clubs\n            - print(workflow_compute_mvp(competition_name=\"fifa-club-world-cup\", competition_year=\"2025\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"europa-league\", competition_year=\"2024-2025\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"afc-champions-league-elite\", competition_year=\"2024-2025\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"champions-league\", competition_year=\"2024-2025\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"concacaf-champions-cup\", competition_year=\"2025\", scalar=14))\n            - print(workflow_compute_mvp(competition_name=\"concacaf-gold-cup\", competition_year=\"2025\", scalar=14))\n        - Countries:\n            - Austria\n                - print(workflow_compute_mvp(competition_name=\"eredivisie\", competition_year=\"2024-2025\")) \n            - Canada\n                - print(workflow_compute_mvp(competition_name=\"canadian-championship\", competition_year=\"2025\", scalar=14))\n                - print(workflow_compute_mvp(competition_name=\"premier-league\", competition_year=\"2025\", manual_competition_id=\"9986\"))\n            - England\n                - print(workflow_compute_mvp(competition_name=\"premier-league\", competition_year=\"2024-2025\", manual_competition_id=\"47\"))\n                - print(workflow_compute_mvp(competition_name=\"fa-cup\", competition_year=\"2024-2025\", scalar=14))\n            - France\n                - print(workflow_compute_mvp(competition_name=\"ligue-1\", competition_year=\"2024-2025\", manual_competition_id=\"53\"))\n                - print(workflow_compute_mvp(competition_name=\"coupe-de-france\", competition_year=\"2024-2025\", scalar=14))\n            - Germany\n                - print(workflow_compute_mvp(competition_name=\"bundesliga\", competition_year=\"2024-2025\", manual_competition_id=\"54\"))\n                - print(workflow_compute_mvp(competition_name=\"dfb-pokal\", competition_year=\"2024-2025\", scalar=14))\n            - Italy\n                - print(mvp.compute_mvp(competition_name=\"serie\", competition_year=\"2024-2025\", manual_competition_id=\"55\")) \n                - print(workflow_compute_mvp(competition_name=\"coppa-italia\", competition_year=\"2024-2025\", scalar=14))\n            - Mexico\n                - print(workflow_compute_mvp(competition_name=\"liga-mx\", competition_year=\"2023-2024\", open_close_league=\"Apertura\")) \n                - print(workflow_compute_mvp(competition_name=\"liga-mx\", competition_year=\"2023-2024\", open_close_league=\"Clausura\")) \n            - Netherlands\n                - print(workflow_compute_mvp(competition_name=\"eredivisie\", competition_year=\"2024-2025\", manual_competition_id=\"57\"))  \n            - Saudi Arabia\n                - print(workflow_compute_mvp(competition_name=\"saudi-pro-league\", competition_year=\"2024-2025\"))        \n            - Scotland\n                - print(workflow_compute_mvp(competition_name=\"premiership\", competition_year=\"2024-2025\"))             \n            - Spain\n                - print(workflow_compute_mvp(competition_name=\"laliga\", competition_year=\"2024-2025\"))   \n                - print(workflow_compute_mvp(competition_name=\"copa-del-rey\", competition_year=\"2024-2025\", scalar=14))         \n            - USA\n                - print(workflow_compute_mvp(competition_name=\"open-cup\", competition_year=\"2025\", scalar=14))\n                - print(workflow_compute_mvp(competition_name=\"mls\", competition_year=\"2025\"))        \n            \n        \n    - Step-by-Step\n        - List all available competitions (Note: if a competition is not available, include a defined_url arguement)\n            - all_comps = AllCompetitions()\n            - all_comp_info = all_comps.gather_all_competition_ids(\"https://www.fotmob.com/\") # run\n            - print(all_comp_info)\n\n        - Chooses the competition \n            - comps = Competition()\n            - print(comps.choose_competition(competition_name=\"mls\", competition_year=\"2023\"))\n\n        - Test this out later to extract player info from new html setup \n            - match = Match()\n            - print(match.extract_single_match_players_stats(\"https://www.fotmob.com/matches/toronto-fc-vs-fc-cincinnati/3vaemjyi#4085040\"))\n            - print(match.choose_match(competition_name=\"mls\", competition_year=\"2023\"))\n\n        - Extract player stats and compute both the total of games played and average SPI score for only games with SPI scores included. \n            - player = Player()\n            - print(player.choose_player_stats(competition_name=\"mls\", competition_year=\"2023\"))\n            - print(player.competition_analysis(competition_name=\"mls\", competition_year=\"2023\"))\n\n        - Runs all the steps above\n            - mvp = MVP()\n            - print(mvp.compute_mvp(competition_name=\"mls\", competition_year=\"2023\", scalar=4))\n\n\n\n\n\n## How a Player Receives an SPI Score:\n\nOnly players who receive an SPI score are considered to have officially played in a match. \nWhile the exact time required for a score isn't fully confirmed, starting players typically \nneed to play just a few minutes to earn an SPI for that match. On the other hand, substitutes \nmust play for approximately 10 minutes to qualify for a score.\n\nSubstitute players who play less than the required time or those who are injured shortly after \nentering the game will not receive an SPI score. Initially, I considered assigning a default \nstarting score (likely around 6.0 or 7.0, which is what I think a player starts off anyways) to any competitor who participated in the match but didn\u2019t earn \na score. However, this approach raised concerns: for instance, a player who scores a goal and \none who concedes an own-goal would both receive the same starting score, which seems inappropriate.\n\nTo maintain consistency, this MVP program will only consider a match as \"played\" if a player has been assigned an SPI rating. \n\nThe FotMob player rating is calculated based on more than 100 individual stats per player per match\n\n---\n\nAll Competition names and ids (i.e. all_comp_info):\n\n{'38': 'bundesliga', '40': 'first-division-a', '42': 'champions-league', '43': 'confederation-cup', '44': 'copa-america', '45': 'copa-libertadores', '46': 'superligaen', '48': 'championship', '50': 'euro', '51': 'veikkausliiga', '57': 'eredivisie', '58': 'eredivisie', '64': 'premiership', '65': 'summer-olympics-women', '66': 'summer-olympics', '68': 'allsvenskan', '69': 'super-league', '73': 'europa-league', '85': '1-division', '86': 'serie-b', '108': 'league-one', '109': 'league-two', '112': 'liga-profesional', '113': 'a-league', '114': 'friendlies', '116': 'cymru-premier', '117': 'national-league', '119': '2-liga', '120': 'super-league', '121': 'primera-division', '122': '1-liga', '123': 'championship', '124': 'league-one', '125': 'league-two', '127': 'ligat-haal', '128': 'leumit-league', '129': 'premiership', '130': 'mls', '131': 'liga-1', '132': 'fa-cup', '135': 'super-league-1', '136': '1-division', '137': 'scottish-cup', '140': 'laliga2', '141': 'coppa-italia', '142': 'efl-trophy', '143': 'suomen-cup', '144': 'primera-division', '145': 'greece-cup', '147': 'serie-c', '150': 'coupe-de-la-ligue', '151': 'turkish-cup', '161': 'primera-division', '163': 'challenge-league', '169': 'ettan', '171': 'svenska-cupen', '176': '1-liga', '179': 'challenge-cup', '180': 'league-cup', '181': 'premiership-playoff', '182': 'super-liga', '187': 'league-cup', '189': 'liga-i', '190': 'cupa-rom\u00e2niei', '193': 'russian-cup', '196': 'ekstraklasa', '199': 'division-profesional', '204': 'postnord-ligaen', '205': 'norsk-tipping-ligaen', '207': 'troph\u00e9e-des-champions', '209': 'dfb-pokal', '215': 'besta-deildin', '217': 'icelandic-cup', '218': 'first-division', '224': 'j-league-cup', '225': 'premier-league', '230': 'liga-mx', '231': 'national-division', '239': '2-division', '240': '3-division', '241': 'danmarksserien', '246': 'serie-a', '251': 'ykkosliiga', '256': 'kvindeligaen', '263': 'premier-league', '264': 'first-division-b', '267': 'premier-league', '270': 'first-professional-league', '273': 'primera-division', '274': 'categor\u00eda-primera-a', '287': 'euro-u19', '288': 'euro-u21', '290': 'asian-cup', '292': \"women's-euro\", '293': \"women's-friendlies\", '297': 'concacaf-champions-cup', '298': 'concacaf-gold-cup', '299': 'copa-sudamericana', '300': 'east-asian-championship', '301': 'european-championship-u-17', '305': 'toulon-tournament', '329': 'gulf-cup', '331': 'toppserien', '332': '1-division-kvinner', '335': 'primera-division', '336': 'liga-nacional', '337': 'liga-nacional', '338': '1-division', '339': 'primera-division', '342': 'finland-cup', '441': 'premier-league', '489': 'club-friendlies', '512': 'regionalliga', '519': 'premier-league', '524': 'stars-league', '525': 'afc-champions-league-elite', '526': 'caf-champions-league', '529': 'premier-league', '533': 'professional-football-league', '537': 'premier-soccer-league', '544': 'ligue-i', '8815': 'super-league-2', '8870': 'championship', '8944': 'national-north-&-south', '8947': 'premier-division', '8965': 'primera-b-nacional', '8968': 'primera-federaci\u00f3n', '8969': 'ykkonen', '8971': 'serie-c', '8973': '2-liga', '8974': 'j-league-2', '8976': 'liga-de-expansi\u00f3n-mx', '8980': 'brazil-state-championship', '9015': 'liga-primera', '9039': 'lpf', '9080': 'k-league-1', '9081': 'bundesliga', '9100': '2-division', '9112': 'liga-3', '9113': 'liga-ii', '9116': 'k-league-2', '9122': 'segunda-division', '9123': 'second-league', '9125': 'primera-b', '9126': 'primera-b', '9134': 'nwsl', '9137': 'china-league-one', '9138': 'segunda-federaci\u00f3n', '9141': 'germany-5', '9143': 'singapore-cup', '9210': 'france-4', '9213': 'primera-b-metropolitana-&-torneo-federal-a', '9253': 'fa-trophy', '9265': 'asean-championship', '9294': \"women's-championship\", '9296': 'usl-league-one', '9305': 'copa-argentina', '9306': 'cecafa-cup', '9345': 'copa-mx', '9375': \"women's-champions-league\", '9382': 'toppserien-qualification', '9390': 'west-asian-championship', '9391': 'copa-mx-clausura', '9408': 'international-champions-cup', '9422': 'k-league', '9428': 'african-nations-championship', '9429': 'copa-do-nordeste', '9441': 'open-cup', '9468': 'caf-confed-cup', '9469': 'afc-champions-league-two', '9470': 'afc-challenge-league', '9474': 'mtn8', '9478': 'indian-super-league', '9494': 'usl-league-two', '9495': 'a-league-women', '9500': 'we-league-women', '9514': 'the-atlantic-cup', '9537': 'k-league-3', '9545': 'highland-/-lowland', '9579': 'algarve-cup-qualification', '9656': 'concacaf-championship-u20', '9682': 'concacaf-central-american-cup', '9690': 'southeast-asian-games', '9717': \"women's-league-cup\", '9741': 'uefa-youth-league', '9754': 'obos-ligaen', '9806': 'uefa-nations-league-a', '9807': 'uefa-nations-league-b', '9808': 'uefa-nations-league-c', '9809': 'uefa-nations-league-d', '9821': 'concacaf-nations-league', '9833': 'asian-games', '9837': 'canadian-championship', '9841': 'afc-u20-asian-cup', '9876': 'saff-championship', '9906': 'liga-mx-femenil', '9907': 'liga-f', '9921': 'shebelieves-cup-qualification', '9986': 'premier-league', '10007': 'copa-de-la-liga-profesional', '10022': 'regionalliga', '10043': 'leagues-cup', '10046': 'copa-ecuador', '10056': 'liga-2', '10075': 'torneo-de-verano', '10076': 'league-cup', '10082': 'fa-cup-women', '10084': 'nisa', '10145': 'footballs-staying-home-cup-(esports)', '10167': 'nwsl-challenge-cup', '10176': 'premier-league-2-div-2', '10178': 'serie-a-femminile', '10188': 'k-league-3', '10207': 'nisa-legends-cup', '10216': 'conference-league', '10242': 'fifa-arab-cup', '10244': 'paulista-a1', '10269': 'womens-asian-cup', '10270': 'league-cup', '10272': 'carioca', '10273': 'mineiro', '10274': 'ga\u00facho', '10290': 'baiano', '10291': 'goiano', '10304': 'finalissima', '10309': 'durand-cup', '10310': 'stars-league-relegation-playoff', '10325': 'preseason', '10366': 'super-cup', '10368': 'copa-america-femenina', '10437': 'euro-u-21', '10449': 'nacional-feminino', '10457': \"uefa-women's-nations-league-a\", '10458': 'uefa-nations-league-b-women', '10459': 'uefa-nations-league-c-women', '10474': 'arab-club-champions-cup', '10498': 'summer-olympics-concacaf-qualification', '10508': 'african-football-league', '10511': 'afc-summer-olympics-women', '10584': 'south-africa-league', '10603': 'concacaf-gold-cup-women', '10607': 'euro', '10609': 'asian-cup--playoff', '10610': 'concafaf-gold-cup', '10611': 'champions-league', '10612': \"women's-champions-league\", '10613': 'europa-league', '10615': 'conference-league', '10616': 'euro-u19', '10617': 'euro-u17', '10618': 'copa-libertadores', '10619': 'caf-champions-league', '10621': 'concacaf-championship-u20', '10622': 'afc-champions-league-elite', '10623': 'copa-sudamericana', '10640': \"women's-euro-league-a\", '10641': \"women's-euro-league-b\", '10642': \"women's-euro-league-c\", '10649': 'nwsl-x-liga-mx', '10651': 'copa-de-la-reina', '10654': 'usl-j\u00e4germeister-cup', '10699': 'usl-super-league-women', '10703': 'fifa-intercontinental-cup', '10705': 'national-league-cup', '10708': 'knockout-cup', '10717': 'uefa-nations-league-a', '10718': 'uefa-nations-league-b', '10719': 'uefa-nations-league-c', '10791': 'swpl-1', '10840': 'baller-league', '10844': 'baller-league', '10872': 'northern-super-league'}\n\n---\n\nResource: \n- (Fotmob Homepage) - */https://www.fotmob.com/*\n\n- (Install Pyspark) - */https://medium.com/@jpurrutia95/install-and-set-up-pyspark-in-5-minutes-m1-mac-eb415fe623f3/*\n\n---\n\n### Potential Contributions:\n- Add a CI/CD pipeline (e.g. Github Actions - pytest, flake8, isort, black, docker build)\n- Cloud data storage functionality\n- Unit Tests\n\n### Possibilites to optimize the MVP algorithm\n- Add more weighted features:\n    - players\n        - avg spi for all (or specific) competitions\n        - avg spi from past N years/months/weeks/games \n    - teams\n    - leagues or tournaments\n    - countries\n    - continents \n    - match type \n        - e.g. \n            - \"finalTournament\":\"Final\",\"bronzeFinal\":\"Bronze-final\",\"semifinal\":\"Semi-final\",\"quarterfinal\":\"Quarter-final\",\"roundof16\":\"Round of 16\",\"h2h\":\"Head-to-Head\",\"bracket\":\"Bracket\"\n\n---\n\nMade by Drue Tomas Staples\n\n\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Analytical tool to determine top performing football players (MVP) across leagues and tournaments.",
    "version": "0.1.1",
    "project_urls": {
        "Homepage": "https://github.com/DrueStaples08/FootballMVP",
        "Tracker": "https://github.com/DrueStaples08/FootballMVP/issues"
    },
    "split_keywords": [
        "football",
        " soccer",
        " mvp",
        " analytics",
        " sports"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f2f12dd61636b7c133c7c160e483b2b5011a05a52bda06258dc3eccf9525a82d",
                "md5": "e6d40255b21fad3711a3595b30c28fe3",
                "sha256": "226408df001d47244a8a1841191ce50029d04b3d111314aeeb69c1b40bfd9d6f"
            },
            "downloads": -1,
            "filename": "footballmvp-0.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e6d40255b21fad3711a3595b30c28fe3",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.12",
            "size": 20161,
            "upload_time": "2025-07-27T05:41:24",
            "upload_time_iso_8601": "2025-07-27T05:41:24.181934Z",
            "url": "https://files.pythonhosted.org/packages/f2/f1/2dd61636b7c133c7c160e483b2b5011a05a52bda06258dc3eccf9525a82d/footballmvp-0.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "99394b2a991e9a4abb4695286812dd9bc58ddd95ba9bb3eed0fa7f05d7b322de",
                "md5": "32fd6798d62f368311e4ab56d7a940db",
                "sha256": "0fa80156af6eb858192f1e0e339f63a2c4a82bb4dbc5302bae348ecb1e42a352"
            },
            "downloads": -1,
            "filename": "footballmvp-0.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "32fd6798d62f368311e4ab56d7a940db",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 26726,
            "upload_time": "2025-07-27T05:41:25",
            "upload_time_iso_8601": "2025-07-27T05:41:25.170333Z",
            "url": "https://files.pythonhosted.org/packages/99/39/4b2a991e9a4abb4695286812dd9bc58ddd95ba9bb3eed0fa7f05d7b322de/footballmvp-0.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-27 05:41:25",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "DrueStaples08",
    "github_project": "FootballMVP",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "appnope",
            "specs": [
                [
                    "==",
                    "0.1.4"
                ]
            ]
        },
        {
            "name": "asttokens",
            "specs": [
                [
                    "==",
                    "2.4.1"
                ]
            ]
        },
        {
            "name": "attrs",
            "specs": [
                [
                    "==",
                    "25.3.0"
                ]
            ]
        },
        {
            "name": "beautifulsoup4",
            "specs": [
                [
                    "==",
                    "4.12.3"
                ]
            ]
        },
        {
            "name": "bs4",
            "specs": [
                [
                    "==",
                    "0.0.2"
                ]
            ]
        },
        {
            "name": "certifi",
            "specs": [
                [
                    "==",
                    "2024.8.30"
                ]
            ]
        },
        {
            "name": "charset-normalizer",
            "specs": [
                [
                    "==",
                    "3.4.0"
                ]
            ]
        },
        {
            "name": "comm",
            "specs": [
                [
                    "==",
                    "0.2.2"
                ]
            ]
        },
        {
            "name": "contourpy",
            "specs": [
                [
                    "==",
                    "1.3.0"
                ]
            ]
        },
        {
            "name": "cycler",
            "specs": [
                [
                    "==",
                    "0.12.1"
                ]
            ]
        },
        {
            "name": "debugpy",
            "specs": [
                [
                    "==",
                    "1.8.7"
                ]
            ]
        },
        {
            "name": "decorator",
            "specs": [
                [
                    "==",
                    "5.1.1"
                ]
            ]
        },
        {
            "name": "executing",
            "specs": [
                [
                    "==",
                    "2.1.0"
                ]
            ]
        },
        {
            "name": "fonttools",
            "specs": [
                [
                    "==",
                    "4.54.1"
                ]
            ]
        },
        {
            "name": "h11",
            "specs": [
                [
                    "==",
                    "0.16.0"
                ]
            ]
        },
        {
            "name": "idna",
            "specs": [
                [
                    "==",
                    "3.10"
                ]
            ]
        },
        {
            "name": "ipykernel",
            "specs": [
                [
                    "==",
                    "6.29.5"
                ]
            ]
        },
        {
            "name": "ipython",
            "specs": [
                [
                    "==",
                    "8.29.0"
                ]
            ]
        },
        {
            "name": "jedi",
            "specs": [
                [
                    "==",
                    "0.19.1"
                ]
            ]
        },
        {
            "name": "jupyter_client",
            "specs": [
                [
                    "==",
                    "8.6.3"
                ]
            ]
        },
        {
            "name": "jupyter_core",
            "specs": [
                [
                    "==",
                    "5.7.2"
                ]
            ]
        },
        {
            "name": "kiwisolver",
            "specs": [
                [
                    "==",
                    "1.4.7"
                ]
            ]
        },
        {
            "name": "matplotlib",
            "specs": [
                [
                    "==",
                    "3.9.2"
                ]
            ]
        },
        {
            "name": "matplotlib-inline",
            "specs": [
                [
                    "==",
                    "0.1.7"
                ]
            ]
        },
        {
            "name": "nest-asyncio",
            "specs": [
                [
                    "==",
                    "1.6.0"
                ]
            ]
        },
        {
            "name": "numpy",
            "specs": [
                [
                    "==",
                    "2.1.2"
                ]
            ]
        },
        {
            "name": "outcome",
            "specs": [
                [
                    "==",
                    "1.3.0.post0"
                ]
            ]
        },
        {
            "name": "packaging",
            "specs": [
                [
                    "==",
                    "24.1"
                ]
            ]
        },
        {
            "name": "pandas",
            "specs": [
                [
                    "==",
                    "2.2.3"
                ]
            ]
        },
        {
            "name": "parso",
            "specs": [
                [
                    "==",
                    "0.8.4"
                ]
            ]
        },
        {
            "name": "pexpect",
            "specs": [
                [
                    "==",
                    "4.9.0"
                ]
            ]
        },
        {
            "name": "pillow",
            "specs": [
                [
                    "==",
                    "11.0.0"
                ]
            ]
        },
        {
            "name": "platformdirs",
            "specs": [
                [
                    "==",
                    "4.3.6"
                ]
            ]
        },
        {
            "name": "prompt_toolkit",
            "specs": [
                [
                    "==",
                    "3.0.48"
                ]
            ]
        },
        {
            "name": "psutil",
            "specs": [
                [
                    "==",
                    "6.1.0"
                ]
            ]
        },
        {
            "name": "ptyprocess",
            "specs": [
                [
                    "==",
                    "0.7.0"
                ]
            ]
        },
        {
            "name": "pure_eval",
            "specs": [
                [
                    "==",
                    "0.2.3"
                ]
            ]
        },
        {
            "name": "py4j",
            "specs": [
                [
                    "==",
                    "0.10.9.7"
                ]
            ]
        },
        {
            "name": "Pygments",
            "specs": [
                [
                    "==",
                    "2.18.0"
                ]
            ]
        },
        {
            "name": "pyparsing",
            "specs": [
                [
                    "==",
                    "3.2.0"
                ]
            ]
        },
        {
            "name": "PySocks",
            "specs": [
                [
                    "==",
                    "1.7.1"
                ]
            ]
        },
        {
            "name": "pyspark",
            "specs": [
                [
                    "==",
                    "3.5.3"
                ]
            ]
        },
        {
            "name": "python-dateutil",
            "specs": [
                [
                    "==",
                    "2.9.0.post0"
                ]
            ]
        },
        {
            "name": "pytz",
            "specs": [
                [
                    "==",
                    "2024.2"
                ]
            ]
        },
        {
            "name": "pyzmq",
            "specs": [
                [
                    "==",
                    "26.2.0"
                ]
            ]
        },
        {
            "name": "requests",
            "specs": [
                [
                    "==",
                    "2.32.3"
                ]
            ]
        },
        {
            "name": "selenium",
            "specs": [
                [
                    "==",
                    "4.32.0"
                ]
            ]
        },
        {
            "name": "setuptools",
            "specs": [
                [
                    "==",
                    "80.9.0"
                ]
            ]
        },
        {
            "name": "six",
            "specs": [
                [
                    "==",
                    "1.16.0"
                ]
            ]
        },
        {
            "name": "sniffio",
            "specs": [
                [
                    "==",
                    "1.3.1"
                ]
            ]
        },
        {
            "name": "sortedcontainers",
            "specs": [
                [
                    "==",
                    "2.4.0"
                ]
            ]
        },
        {
            "name": "soupsieve",
            "specs": [
                [
                    "==",
                    "2.6"
                ]
            ]
        },
        {
            "name": "stack-data",
            "specs": [
                [
                    "==",
                    "0.6.3"
                ]
            ]
        },
        {
            "name": "tornado",
            "specs": [
                [
                    "==",
                    "6.4.1"
                ]
            ]
        },
        {
            "name": "traitlets",
            "specs": [
                [
                    "==",
                    "5.14.3"
                ]
            ]
        },
        {
            "name": "trio",
            "specs": [
                [
                    "==",
                    "0.30.0"
                ]
            ]
        },
        {
            "name": "trio-websocket",
            "specs": [
                [
                    "==",
                    "0.12.2"
                ]
            ]
        },
        {
            "name": "typing_extensions",
            "specs": [
                [
                    "==",
                    "4.12.2"
                ]
            ]
        },
        {
            "name": "tzdata",
            "specs": [
                [
                    "==",
                    "2024.2"
                ]
            ]
        },
        {
            "name": "urllib3",
            "specs": [
                [
                    "==",
                    "2.2.3"
                ]
            ]
        },
        {
            "name": "wcwidth",
            "specs": [
                [
                    "==",
                    "0.2.13"
                ]
            ]
        },
        {
            "name": "websocket-client",
            "specs": [
                [
                    "==",
                    "1.8.0"
                ]
            ]
        },
        {
            "name": "wsproto",
            "specs": [
                [
                    "==",
                    "1.2.0"
                ]
            ]
        }
    ],
    "lcname": "footballmvp"
}
        
Elapsed time: 1.85826s