Latest commit

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Kickbase Bundesliga data project

Work in progress. This repository preserves the project's source, curated reference data, notebooks, archived material, and generated output snapshots. Commit refreshed output files alongside the change that produced them so the data history remains reproducible.

This project supports a repeatable Bundesliga-to-Kickbase decision workflow: collect fixtures, odds, team, squad, player, and predicted-lineup data; derive comparable signals and expected-points scores; then build and save constrained Kickbase squads. Its live sources include SofaScore, FotMob, Transfermarkt, KBStats, RotoWire, LigaInsider, Kicker, and manually transcribed Kickbase lineups.

Project layout

  • notebooks/01_fixtures_and_teams: match-ID collectors and the shared Bundesliga team-reference builder.
  • notebooks/02_odds: SofaScore and FotMob matchday odds collectors.
  • notebooks/03_team_data: recent form, team statistics, Transfermarkt squads, and KBStats player collectors.
  • notebooks/04_derived_analysis: combined Bundesliga snapshots, high-rated-player analysis, KBStats average-points percentile filtering, and KBStats last-five-match-slot analysis.
  • notebooks/05_predicted_lineups: live predicted and confirmed lineup collectors from RotoWire, LigaInsider, and Kicker, plus compatible source-specific outputs.
  • notebooks/06_score_creation: score builders that combine source signals into expected-points files for the optimizers.
  • notebooks/07_squad_optimisation: optimizer notebooks for Bundesliga Arena, KickbaseKIS Arena, All Limits Arena, and Kickbase.insider Arena, plus manually_create_lineup.ipynb for manual entry.
  • notebooks/tests: diagnostic notebooks that are not production pipeline steps.
  • data/reference/kickbase: curated Kickbase scoring and event-frequency rules.
  • outputs/sofascore: SofaScore match IDs, odds, team reference, form, team statistics, high-rated-player results, and approximate Kickbase-point averages.
  • outputs/fotmob: FotMob match IDs and odds.
  • outputs/transfermarkt: squad exports and diagnostic HTML.
  • outputs/rotowire: timestamped Bundesliga predicted-lineup snapshots.
  • outputs/ligainsider: timestamped Bundesliga predicted-lineup snapshots, including formation slots and candidate alternatives where supplied.
  • outputs/kicker: timestamped Bundesliga predicted-lineup snapshots. Each record preserves Kicker’s raw lineup text, formation, coach, bench, unavailable players, and explanation alongside the common home/away schema.
  • outputs/kickbase: timestamped predicted-lineup snapshots transcribed from user-submitted Kickbase screenshots; player names remain source display names and are not resolved to canonical identities.
  • outputs/kbstats: KBStats player snapshots.
  • outputs/derived: multi-source normalized outputs.
  • outputs/optimized_squad: timestamped optimizer exports.
  • outputs/selected_lineups: canonical per-arena selected-lineup JSON snapshots. A newer confirmed selection replaces only that arena's file.
  • archive: superseded notebooks, historical data, and any unique recovered Jupyter checkpoints.
  • project_paths.py: the authoritative filesystem interface used by notebooks.
  • selected_lineups.py: shared selected-lineup persistence and replacement prompts.
  • manual_lineup_helpers.py: shared non-solver player-pool, rule, and validation logic used by the manual lineup notebook.

Generated JSON, CSV, and debug HTML must be written through project_paths.py; do not write generated files beside a notebook or into the project root.

Timestamped output retention

Timestamped output exporters invoke the shared cleanup in project_paths.py. The cleanup uses the final timestamp in a filename as the output creation time and retains the 10 newest files in each applicable family. Files without a supported creation timestamp in their filename are never removed.

Most families are distinguished by output directory, filename pattern with timestamps removed, and file extension. Meaningful labels such as matchday, percentile, and datatype remain separate. Two high-volume CSV directories use a single limit across their methods: outputs/expected_points retains its 10 newest expected-points CSVs, and outputs/optimized_squad retains its 10 newest optimizer CSVs. Run timestamped-output notebooks through their final retention cell to apply the same cleanup after notebook exports.

Setup

From PowerShell in the project root:

.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
jupyter lab

Run the automated checks with:

python -m pytest

The existing .venv stays at the root because moving a virtual environment can invalidate absolute paths stored inside it. The browser-backed scraping notebooks expect a compatible Chrome installation; their current configuration targets Chrome 150. If Kicker presents a browser-verification page, complete it manually in the Chrome window when prompted; the notebook does not attempt to bypass it.

Version-control conventions

All portable project assets are versioned, including data/, archive/, and outputs/. The local .venv, Python caches, and automatic Jupyter checkpoints are intentionally excluded because they are machine-specific or reproducible.

Do not commit credentials, API tokens, browser profiles, cookies, screenshots, or other sensitive local material. Keep each code change and its related output refresh in a small, descriptive commit. A selected-lineup file represents the current canonical choice for one arena; replacing it is intentional rather than creating a timestamped history.

Recommended pipeline

  1. Run notebooks/01_fixtures_and_teams/01_sofascore_match_ids.ipynb and/or 02_fotmob_match_ids.ipynb for the desired matchday.
  2. Run 03_build_bundesliga_team_reference.ipynb after selecting its MATCHDAY.
  3. Run the appropriate notebooks in notebooks/02_odds.
  4. Run any needed collectors in notebooks/03_team_data. Recent form and team statistics require outputs/sofascore/reference/bundesliga_teams.json.
  5. Run the derived notebooks. The high-rated-player notebook automatically uses the newest valid timestamped file in outputs/sofascore/team_form.
  6. Run the required collectors in notebooks/05_predicted_lineups: RotoWire, LigaInsider, Kicker, and/or the source-specific manual Kickbase workflow. Their snapshots share the match/home/away/player envelope while retaining source-specific details. Default lineup-blend weights are LigaInsider 4, Kickbase 3, Kicker 2, and RotoWire 1; only sources covering a team contribute to that team's blend.
  7. Create the required expected-points score file in notebooks/06_score_creation.
  8. Run an optimizer in notebooks/07_squad_optimisation, or run manually_create_lineup.ipynb to enter a formation, players, and captain interactively. A confirmed selection is stored in outputs/selected_lineups.

The Transfermarkt, KBStats, and FotMob collectors can run independently of the SofaScore team-reference pipeline when their own inputs are available.

Inputs and outputs

NotebookReadsWrites
SofaScore match IDsLive SofaScore APIoutputs/sofascore/match_ids
FotMob match IDsLive FotMob pages/APIoutputs/fotmob/match_ids
Team-reference builderSofaScore match IDsoutputs/sofascore/reference
SofaScore oddsSofaScore match IDsoutputs/sofascore/odds
FotMob oddsFotMob match IDsoutputs/fotmob/odds
Recent formTeam referenceoutputs/sofascore/team_form
Team statisticsTeam referenceoutputs/sofascore/team_stats
Transfermarkt squadsLive Transfermarkt pagesoutputs/transfermarkt/squads
RotoWire predicted lineupsLive RotoWire Bundesliga lineups pageoutputs/rotowire/predicted_lineups
LigaInsider predicted lineupsLive LigaInsider team pagesoutputs/ligainsider/predicted_lineups
Kicker predicted lineupsLive Kicker matchday and fixture pagesoutputs/kicker/predicted_lineups
Kickbase screenshot lineupsUser-submitted screenshots and fixture referenceoutputs/kickbase/predicted_lineups
KBStats playersLive KBStats APIoutputs/kbstats/players
Bundesliga snapshotTeam reference and live source dataoutputs/derived/bundesliga_snapshots
High-rated playersLatest team-form snapshotoutputs/sofascore/high_rated_players
SofaScore Kickbase-point averagesLatest team-form snapshot and live SofaScore match payloadsoutputs/sofascore/player_kickbase_point_averages
KBStats high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_high_average_players
KBStats last-five high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_last_5_high_average_players
Squad optimizersLatest expected-points CSV and matchday matchesTimestamped optimizer CSV and optional selected-lineup JSON
Manual lineupLatest expected-points CSV, matchday matches, arena, formation, and player choicesOptional canonical JSON in outputs/selected_lineups

Missing required inputs raise errors that include the exact expected path. Start Jupyter from the project root for the simplest path discovery; VS Code notebook execution is also supported.

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Kickbase Bundesliga data project

Work in progress. This repository preserves the project's source, curated reference data, notebooks, archived material, and generated output snapshots. Commit refreshed output files alongside the change that produced them so the data history remains reproducible.

This project supports a repeatable Bundesliga-to-Kickbase decision workflow: collect fixtures, odds, team, squad, player, and predicted-lineup data; derive comparable signals and expected-points scores; then build and save constrained Kickbase squads. Its live sources include SofaScore, FotMob, Transfermarkt, KBStats, RotoWire, LigaInsider, Kicker, and manually transcribed Kickbase lineups.

Project layout

  • notebooks/01_fixtures_and_teams: match-ID collectors and the shared Bundesliga team-reference builder.
  • notebooks/02_odds: SofaScore and FotMob matchday odds collectors.
  • notebooks/03_team_data: recent form, team statistics, Transfermarkt squads, and KBStats player collectors.
  • notebooks/04_derived_analysis: combined Bundesliga snapshots, high-rated-player analysis, KBStats average-points percentile filtering, and KBStats last-five-match-slot analysis.
  • notebooks/05_predicted_lineups: live predicted and confirmed lineup collectors from RotoWire, LigaInsider, and Kicker, plus compatible source-specific outputs.
  • notebooks/06_score_creation: score builders that combine source signals into expected-points files for the optimizers.
  • notebooks/07_squad_optimisation: optimizer notebooks for Bundesliga Arena, KickbaseKIS Arena, All Limits Arena, and Kickbase.insider Arena, plus manually_create_lineup.ipynb for manual entry.
  • notebooks/tests: diagnostic notebooks that are not production pipeline steps.
  • data/reference/kickbase: curated Kickbase scoring and event-frequency rules.
  • outputs/sofascore: SofaScore match IDs, odds, team reference, form, team statistics, high-rated-player results, and approximate Kickbase-point averages.
  • outputs/fotmob: FotMob match IDs and odds.
  • outputs/transfermarkt: squad exports and diagnostic HTML.
  • outputs/rotowire: timestamped Bundesliga predicted-lineup snapshots.
  • outputs/ligainsider: timestamped Bundesliga predicted-lineup snapshots, including formation slots and candidate alternatives where supplied.
  • outputs/kicker: timestamped Bundesliga predicted-lineup snapshots. Each record preserves Kicker’s raw lineup text, formation, coach, bench, unavailable players, and explanation alongside the common home/away schema.
  • outputs/kickbase: timestamped predicted-lineup snapshots transcribed from user-submitted Kickbase screenshots; player names remain source display names and are not resolved to canonical identities.
  • outputs/kbstats: KBStats player snapshots.
  • outputs/derived: multi-source normalized outputs.
  • outputs/optimized_squad: timestamped optimizer exports.
  • outputs/selected_lineups: canonical per-arena selected-lineup JSON snapshots. A newer confirmed selection replaces only that arena's file.
  • archive: superseded notebooks, historical data, and any unique recovered Jupyter checkpoints.
  • project_paths.py: the authoritative filesystem interface used by notebooks.
  • selected_lineups.py: shared selected-lineup persistence and replacement prompts.
  • manual_lineup_helpers.py: shared non-solver player-pool, rule, and validation logic used by the manual lineup notebook.

Generated JSON, CSV, and debug HTML must be written through project_paths.py; do not write generated files beside a notebook or into the project root.

Timestamped output retention

Timestamped output exporters invoke the shared cleanup in project_paths.py. The cleanup uses the final timestamp in a filename as the output creation time and retains the 10 newest files in each applicable family. Files without a supported creation timestamp in their filename are never removed.

Most families are distinguished by output directory, filename pattern with timestamps removed, and file extension. Meaningful labels such as matchday, percentile, and datatype remain separate. Two high-volume CSV directories use a single limit across their methods: outputs/expected_points retains its 10 newest expected-points CSVs, and outputs/optimized_squad retains its 10 newest optimizer CSVs. Run timestamped-output notebooks through their final retention cell to apply the same cleanup after notebook exports.

Setup

From PowerShell in the project root:

.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
jupyter lab

Run the automated checks with:

python -m pytest

The existing .venv stays at the root because moving a virtual environment can invalidate absolute paths stored inside it. The browser-backed scraping notebooks expect a compatible Chrome installation; their current configuration targets Chrome 150. If Kicker presents a browser-verification page, complete it manually in the Chrome window when prompted; the notebook does not attempt to bypass it.

Version-control conventions

All portable project assets are versioned, including data/, archive/, and outputs/. The local .venv, Python caches, and automatic Jupyter checkpoints are intentionally excluded because they are machine-specific or reproducible.

Do not commit credentials, API tokens, browser profiles, cookies, screenshots, or other sensitive local material. Keep each code change and its related output refresh in a small, descriptive commit. A selected-lineup file represents the current canonical choice for one arena; replacing it is intentional rather than creating a timestamped history.

Recommended pipeline

  1. Run notebooks/01_fixtures_and_teams/01_sofascore_match_ids.ipynb and/or 02_fotmob_match_ids.ipynb for the desired matchday.
  2. Run 03_build_bundesliga_team_reference.ipynb after selecting its MATCHDAY.
  3. Run the appropriate notebooks in notebooks/02_odds.
  4. Run any needed collectors in notebooks/03_team_data. Recent form and team statistics require outputs/sofascore/reference/bundesliga_teams.json.
  5. Run the derived notebooks. The high-rated-player notebook automatically uses the newest valid timestamped file in outputs/sofascore/team_form.
  6. Run the required collectors in notebooks/05_predicted_lineups: RotoWire, LigaInsider, Kicker, and/or the source-specific manual Kickbase workflow. Their snapshots share the match/home/away/player envelope while retaining source-specific details. Default lineup-blend weights are LigaInsider 4, Kickbase 3, Kicker 2, and RotoWire 1; only sources covering a team contribute to that team's blend.
  7. Create the required expected-points score file in notebooks/06_score_creation.
  8. Run an optimizer in notebooks/07_squad_optimisation, or run manually_create_lineup.ipynb to enter a formation, players, and captain interactively. A confirmed selection is stored in outputs/selected_lineups.

The Transfermarkt, KBStats, and FotMob collectors can run independently of the SofaScore team-reference pipeline when their own inputs are available.

Inputs and outputs

NotebookReadsWrites
SofaScore match IDsLive SofaScore APIoutputs/sofascore/match_ids
FotMob match IDsLive FotMob pages/APIoutputs/fotmob/match_ids
Team-reference builderSofaScore match IDsoutputs/sofascore/reference
SofaScore oddsSofaScore match IDsoutputs/sofascore/odds
FotMob oddsFotMob match IDsoutputs/fotmob/odds
Recent formTeam referenceoutputs/sofascore/team_form
Team statisticsTeam referenceoutputs/sofascore/team_stats
Transfermarkt squadsLive Transfermarkt pagesoutputs/transfermarkt/squads
RotoWire predicted lineupsLive RotoWire Bundesliga lineups pageoutputs/rotowire/predicted_lineups
LigaInsider predicted lineupsLive LigaInsider team pagesoutputs/ligainsider/predicted_lineups
Kicker predicted lineupsLive Kicker matchday and fixture pagesoutputs/kicker/predicted_lineups
Kickbase screenshot lineupsUser-submitted screenshots and fixture referenceoutputs/kickbase/predicted_lineups
KBStats playersLive KBStats APIoutputs/kbstats/players
Bundesliga snapshotTeam reference and live source dataoutputs/derived/bundesliga_snapshots
High-rated playersLatest team-form snapshotoutputs/sofascore/high_rated_players
SofaScore Kickbase-point averagesLatest team-form snapshot and live SofaScore match payloadsoutputs/sofascore/player_kickbase_point_averages
KBStats high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_high_average_players
KBStats last-five high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_last_5_high_average_players
Squad optimizersLatest expected-points CSV and matchday matchesTimestamped optimizer CSV and optional selected-lineup JSON
Manual lineupLatest expected-points CSV, matchday matches, arena, formation, and player choicesOptional canonical JSON in outputs/selected_lineups

Missing required inputs raise errors that include the exact expected path. Start Jupyter from the project root for the simplest path discovery; VS Code notebook execution is also supported.

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Kickbase Bundesliga data project

Work in progress. This repository preserves the project's source, curated reference data, notebooks, archived material, and generated output snapshots. Commit refreshed output files alongside the change that produced them so the data history remains reproducible.

This project supports a repeatable Bundesliga-to-Kickbase decision workflow: collect fixtures, odds, team, squad, player, and predicted-lineup data; derive comparable signals and expected-points scores; then build and save constrained Kickbase squads. Its live sources include SofaScore, FotMob, Transfermarkt, KBStats, RotoWire, LigaInsider, Kicker, and manually transcribed Kickbase lineups.

Project layout

  • notebooks/01_fixtures_and_teams: match-ID collectors and the shared Bundesliga team-reference builder.
  • notebooks/02_odds: SofaScore and FotMob matchday odds collectors.
  • notebooks/03_team_data: recent form, team statistics, Transfermarkt squads, and KBStats player collectors.
  • notebooks/04_derived_analysis: combined Bundesliga snapshots, high-rated-player analysis, KBStats average-points percentile filtering, and KBStats last-five-match-slot analysis.
  • notebooks/05_predicted_lineups: live predicted and confirmed lineup collectors from RotoWire, LigaInsider, and Kicker, plus compatible source-specific outputs.
  • notebooks/06_score_creation: score builders that combine source signals into expected-points files for the optimizers.
  • notebooks/07_squad_optimisation: optimizer notebooks for Bundesliga Arena, KickbaseKIS Arena, All Limits Arena, and Kickbase.insider Arena, plus manually_create_lineup.ipynb for manual entry.
  • notebooks/tests: diagnostic notebooks that are not production pipeline steps.
  • data/reference/kickbase: curated Kickbase scoring and event-frequency rules.
  • outputs/sofascore: SofaScore match IDs, odds, team reference, form, team statistics, high-rated-player results, and approximate Kickbase-point averages.
  • outputs/fotmob: FotMob match IDs and odds.
  • outputs/transfermarkt: squad exports and diagnostic HTML.
  • outputs/rotowire: timestamped Bundesliga predicted-lineup snapshots.
  • outputs/ligainsider: timestamped Bundesliga predicted-lineup snapshots, including formation slots and candidate alternatives where supplied.
  • outputs/kicker: timestamped Bundesliga predicted-lineup snapshots. Each record preserves Kicker’s raw lineup text, formation, coach, bench, unavailable players, and explanation alongside the common home/away schema.
  • outputs/kickbase: timestamped predicted-lineup snapshots transcribed from user-submitted Kickbase screenshots; player names remain source display names and are not resolved to canonical identities.
  • outputs/kbstats: KBStats player snapshots.
  • outputs/derived: multi-source normalized outputs.
  • outputs/optimized_squad: timestamped optimizer exports.
  • outputs/selected_lineups: canonical per-arena selected-lineup JSON snapshots. A newer confirmed selection replaces only that arena's file.
  • archive: superseded notebooks, historical data, and any unique recovered Jupyter checkpoints.
  • project_paths.py: the authoritative filesystem interface used by notebooks.
  • selected_lineups.py: shared selected-lineup persistence and replacement prompts.
  • manual_lineup_helpers.py: shared non-solver player-pool, rule, and validation logic used by the manual lineup notebook.

Generated JSON, CSV, and debug HTML must be written through project_paths.py; do not write generated files beside a notebook or into the project root.

Timestamped output retention

Timestamped output exporters invoke the shared cleanup in project_paths.py. The cleanup uses the final timestamp in a filename as the output creation time and retains the 10 newest files in each applicable family. Files without a supported creation timestamp in their filename are never removed.

Most families are distinguished by output directory, filename pattern with timestamps removed, and file extension. Meaningful labels such as matchday, percentile, and datatype remain separate. Two high-volume CSV directories use a single limit across their methods: outputs/expected_points retains its 10 newest expected-points CSVs, and outputs/optimized_squad retains its 10 newest optimizer CSVs. Run timestamped-output notebooks through their final retention cell to apply the same cleanup after notebook exports.

Setup

From PowerShell in the project root:

.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
jupyter lab

Run the automated checks with:

python -m pytest

The existing .venv stays at the root because moving a virtual environment can invalidate absolute paths stored inside it. The browser-backed scraping notebooks expect a compatible Chrome installation; their current configuration targets Chrome 150. If Kicker presents a browser-verification page, complete it manually in the Chrome window when prompted; the notebook does not attempt to bypass it.

Version-control conventions

All portable project assets are versioned, including data/, archive/, and outputs/. The local .venv, Python caches, and automatic Jupyter checkpoints are intentionally excluded because they are machine-specific or reproducible.

Do not commit credentials, API tokens, browser profiles, cookies, screenshots, or other sensitive local material. Keep each code change and its related output refresh in a small, descriptive commit. A selected-lineup file represents the current canonical choice for one arena; replacing it is intentional rather than creating a timestamped history.

Recommended pipeline

  1. Run notebooks/01_fixtures_and_teams/01_sofascore_match_ids.ipynb and/or 02_fotmob_match_ids.ipynb for the desired matchday.
  2. Run 03_build_bundesliga_team_reference.ipynb after selecting its MATCHDAY.
  3. Run the appropriate notebooks in notebooks/02_odds.
  4. Run any needed collectors in notebooks/03_team_data. Recent form and team statistics require outputs/sofascore/reference/bundesliga_teams.json.
  5. Run the derived notebooks. The high-rated-player notebook automatically uses the newest valid timestamped file in outputs/sofascore/team_form.
  6. Run the required collectors in notebooks/05_predicted_lineups: RotoWire, LigaInsider, Kicker, and/or the source-specific manual Kickbase workflow. Their snapshots share the match/home/away/player envelope while retaining source-specific details. Default lineup-blend weights are LigaInsider 4, Kickbase 3, Kicker 2, and RotoWire 1; only sources covering a team contribute to that team's blend.
  7. Create the required expected-points score file in notebooks/06_score_creation.
  8. Run an optimizer in notebooks/07_squad_optimisation, or run manually_create_lineup.ipynb to enter a formation, players, and captain interactively. A confirmed selection is stored in outputs/selected_lineups.

The Transfermarkt, KBStats, and FotMob collectors can run independently of the SofaScore team-reference pipeline when their own inputs are available.

Inputs and outputs

NotebookReadsWrites
SofaScore match IDsLive SofaScore APIoutputs/sofascore/match_ids
FotMob match IDsLive FotMob pages/APIoutputs/fotmob/match_ids
Team-reference builderSofaScore match IDsoutputs/sofascore/reference
SofaScore oddsSofaScore match IDsoutputs/sofascore/odds
FotMob oddsFotMob match IDsoutputs/fotmob/odds
Recent formTeam referenceoutputs/sofascore/team_form
Team statisticsTeam referenceoutputs/sofascore/team_stats
Transfermarkt squadsLive Transfermarkt pagesoutputs/transfermarkt/squads
RotoWire predicted lineupsLive RotoWire Bundesliga lineups pageoutputs/rotowire/predicted_lineups
LigaInsider predicted lineupsLive LigaInsider team pagesoutputs/ligainsider/predicted_lineups
Kicker predicted lineupsLive Kicker matchday and fixture pagesoutputs/kicker/predicted_lineups
Kickbase screenshot lineupsUser-submitted screenshots and fixture referenceoutputs/kickbase/predicted_lineups
KBStats playersLive KBStats APIoutputs/kbstats/players
Bundesliga snapshotTeam reference and live source dataoutputs/derived/bundesliga_snapshots
High-rated playersLatest team-form snapshotoutputs/sofascore/high_rated_players
SofaScore Kickbase-point averagesLatest team-form snapshot and live SofaScore match payloadsoutputs/sofascore/player_kickbase_point_averages
KBStats high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_high_average_players
KBStats last-five high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_last_5_high_average_players
Squad optimizersLatest expected-points CSV and matchday matchesTimestamped optimizer CSV and optional selected-lineup JSON
Manual lineupLatest expected-points CSV, matchday matches, arena, formation, and player choicesOptional canonical JSON in outputs/selected_lineups

Missing required inputs raise errors that include the exact expected path. Start Jupyter from the project root for the simplest path discovery; VS Code notebook execution is also supported.

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Kickbase Bundesliga data project

Work in progress. This repository preserves the project's source, curated reference data, notebooks, archived material, and generated output snapshots. Commit refreshed output files alongside the change that produced them so the data history remains reproducible.

This project supports a repeatable Bundesliga-to-Kickbase decision workflow: collect fixtures, odds, team, squad, player, and predicted-lineup data; derive comparable signals and expected-points scores; then build and save constrained Kickbase squads. Its live sources include SofaScore, FotMob, Transfermarkt, KBStats, RotoWire, LigaInsider, Kicker, and manually transcribed Kickbase lineups.

Project layout

  • notebooks/01_fixtures_and_teams: match-ID collectors and the shared Bundesliga team-reference builder.
  • notebooks/02_odds: SofaScore and FotMob matchday odds collectors.
  • notebooks/03_team_data: recent form, team statistics, Transfermarkt squads, and KBStats player collectors.
  • notebooks/04_derived_analysis: combined Bundesliga snapshots, high-rated-player analysis, KBStats average-points percentile filtering, and KBStats last-five-match-slot analysis.
  • notebooks/05_predicted_lineups: live predicted and confirmed lineup collectors from RotoWire, LigaInsider, and Kicker, plus compatible source-specific outputs.
  • notebooks/06_score_creation: score builders that combine source signals into expected-points files for the optimizers.
  • notebooks/07_squad_optimisation: optimizer notebooks for Bundesliga Arena, KickbaseKIS Arena, All Limits Arena, and Kickbase.insider Arena, plus manually_create_lineup.ipynb for manual entry.
  • notebooks/tests: diagnostic notebooks that are not production pipeline steps.
  • data/reference/kickbase: curated Kickbase scoring and event-frequency rules.
  • outputs/sofascore: SofaScore match IDs, odds, team reference, form, team statistics, high-rated-player results, and approximate Kickbase-point averages.
  • outputs/fotmob: FotMob match IDs and odds.
  • outputs/transfermarkt: squad exports and diagnostic HTML.
  • outputs/rotowire: timestamped Bundesliga predicted-lineup snapshots.
  • outputs/ligainsider: timestamped Bundesliga predicted-lineup snapshots, including formation slots and candidate alternatives where supplied.
  • outputs/kicker: timestamped Bundesliga predicted-lineup snapshots. Each record preserves Kicker’s raw lineup text, formation, coach, bench, unavailable players, and explanation alongside the common home/away schema.
  • outputs/kickbase: timestamped predicted-lineup snapshots transcribed from user-submitted Kickbase screenshots; player names remain source display names and are not resolved to canonical identities.
  • outputs/kbstats: KBStats player snapshots.
  • outputs/derived: multi-source normalized outputs.
  • outputs/optimized_squad: timestamped optimizer exports.
  • outputs/selected_lineups: canonical per-arena selected-lineup JSON snapshots. A newer confirmed selection replaces only that arena's file.
  • archive: superseded notebooks, historical data, and any unique recovered Jupyter checkpoints.
  • project_paths.py: the authoritative filesystem interface used by notebooks.
  • selected_lineups.py: shared selected-lineup persistence and replacement prompts.
  • manual_lineup_helpers.py: shared non-solver player-pool, rule, and validation logic used by the manual lineup notebook.

Generated JSON, CSV, and debug HTML must be written through project_paths.py; do not write generated files beside a notebook or into the project root.

Timestamped output retention

Timestamped output exporters invoke the shared cleanup in project_paths.py. The cleanup uses the final timestamp in a filename as the output creation time and retains the 10 newest files in each applicable family. Files without a supported creation timestamp in their filename are never removed.

Most families are distinguished by output directory, filename pattern with timestamps removed, and file extension. Meaningful labels such as matchday, percentile, and datatype remain separate. Two high-volume CSV directories use a single limit across their methods: outputs/expected_points retains its 10 newest expected-points CSVs, and outputs/optimized_squad retains its 10 newest optimizer CSVs. Run timestamped-output notebooks through their final retention cell to apply the same cleanup after notebook exports.

Setup

From PowerShell in the project root:

.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
jupyter lab

Run the automated checks with:

python -m pytest

The existing .venv stays at the root because moving a virtual environment can invalidate absolute paths stored inside it. The browser-backed scraping notebooks expect a compatible Chrome installation; their current configuration targets Chrome 150. If Kicker presents a browser-verification page, complete it manually in the Chrome window when prompted; the notebook does not attempt to bypass it.

Version-control conventions

All portable project assets are versioned, including data/, archive/, and outputs/. The local .venv, Python caches, and automatic Jupyter checkpoints are intentionally excluded because they are machine-specific or reproducible.

Do not commit credentials, API tokens, browser profiles, cookies, screenshots, or other sensitive local material. Keep each code change and its related output refresh in a small, descriptive commit. A selected-lineup file represents the current canonical choice for one arena; replacing it is intentional rather than creating a timestamped history.

Recommended pipeline

  1. Run notebooks/01_fixtures_and_teams/01_sofascore_match_ids.ipynb and/or 02_fotmob_match_ids.ipynb for the desired matchday.
  2. Run 03_build_bundesliga_team_reference.ipynb after selecting its MATCHDAY.
  3. Run the appropriate notebooks in notebooks/02_odds.
  4. Run any needed collectors in notebooks/03_team_data. Recent form and team statistics require outputs/sofascore/reference/bundesliga_teams.json.
  5. Run the derived notebooks. The high-rated-player notebook automatically uses the newest valid timestamped file in outputs/sofascore/team_form.
  6. Run the required collectors in notebooks/05_predicted_lineups: RotoWire, LigaInsider, Kicker, and/or the source-specific manual Kickbase workflow. Their snapshots share the match/home/away/player envelope while retaining source-specific details. Default lineup-blend weights are LigaInsider 4, Kickbase 3, Kicker 2, and RotoWire 1; only sources covering a team contribute to that team's blend.
  7. Create the required expected-points score file in notebooks/06_score_creation.
  8. Run an optimizer in notebooks/07_squad_optimisation, or run manually_create_lineup.ipynb to enter a formation, players, and captain interactively. A confirmed selection is stored in outputs/selected_lineups.

The Transfermarkt, KBStats, and FotMob collectors can run independently of the SofaScore team-reference pipeline when their own inputs are available.

Inputs and outputs

NotebookReadsWrites
SofaScore match IDsLive SofaScore APIoutputs/sofascore/match_ids
FotMob match IDsLive FotMob pages/APIoutputs/fotmob/match_ids
Team-reference builderSofaScore match IDsoutputs/sofascore/reference
SofaScore oddsSofaScore match IDsoutputs/sofascore/odds
FotMob oddsFotMob match IDsoutputs/fotmob/odds
Recent formTeam referenceoutputs/sofascore/team_form
Team statisticsTeam referenceoutputs/sofascore/team_stats
Transfermarkt squadsLive Transfermarkt pagesoutputs/transfermarkt/squads
RotoWire predicted lineupsLive RotoWire Bundesliga lineups pageoutputs/rotowire/predicted_lineups
LigaInsider predicted lineupsLive LigaInsider team pagesoutputs/ligainsider/predicted_lineups
Kicker predicted lineupsLive Kicker matchday and fixture pagesoutputs/kicker/predicted_lineups
Kickbase screenshot lineupsUser-submitted screenshots and fixture referenceoutputs/kickbase/predicted_lineups
KBStats playersLive KBStats APIoutputs/kbstats/players
Bundesliga snapshotTeam reference and live source dataoutputs/derived/bundesliga_snapshots
High-rated playersLatest team-form snapshotoutputs/sofascore/high_rated_players
SofaScore Kickbase-point averagesLatest team-form snapshot and live SofaScore match payloadsoutputs/sofascore/player_kickbase_point_averages
KBStats high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_high_average_players
KBStats last-five high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_last_5_high_average_players
Squad optimizersLatest expected-points CSV and matchday matchesTimestamped optimizer CSV and optional selected-lineup JSON
Manual lineupLatest expected-points CSV, matchday matches, arena, formation, and player choicesOptional canonical JSON in outputs/selected_lineups

Missing required inputs raise errors that include the exact expected path. Start Jupyter from the project root for the simplest path discovery; VS Code notebook execution is also supported.

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Kickbase Bundesliga data project

Work in progress. This repository preserves the project's source, curated reference data, notebooks, archived material, and generated output snapshots. Commit refreshed output files alongside the change that produced them so the data history remains reproducible.

This project supports a repeatable Bundesliga-to-Kickbase decision workflow: collect fixtures, odds, team, squad, player, and predicted-lineup data; derive comparable signals and expected-points scores; then build and save constrained Kickbase squads. Its live sources include SofaScore, FotMob, Transfermarkt, KBStats, RotoWire, LigaInsider, Kicker, and manually transcribed Kickbase lineups.

Project layout

  • notebooks/01_fixtures_and_teams: match-ID collectors and the shared Bundesliga team-reference builder.
  • notebooks/02_odds: SofaScore and FotMob matchday odds collectors.
  • notebooks/03_team_data: recent form, team statistics, Transfermarkt squads, and KBStats player collectors.
  • notebooks/04_derived_analysis: combined Bundesliga snapshots, high-rated-player analysis, KBStats average-points percentile filtering, and KBStats last-five-match-slot analysis.
  • notebooks/05_predicted_lineups: live predicted and confirmed lineup collectors from RotoWire, LigaInsider, and Kicker, plus compatible source-specific outputs.
  • notebooks/06_score_creation: score builders that combine source signals into expected-points files for the optimizers.
  • notebooks/07_squad_optimisation: optimizer notebooks for Bundesliga Arena, KickbaseKIS Arena, All Limits Arena, and Kickbase.insider Arena, plus manually_create_lineup.ipynb for manual entry.
  • notebooks/tests: diagnostic notebooks that are not production pipeline steps.
  • data/reference/kickbase: curated Kickbase scoring and event-frequency rules.
  • outputs/sofascore: SofaScore match IDs, odds, team reference, form, team statistics, high-rated-player results, and approximate Kickbase-point averages.
  • outputs/fotmob: FotMob match IDs and odds.
  • outputs/transfermarkt: squad exports and diagnostic HTML.
  • outputs/rotowire: timestamped Bundesliga predicted-lineup snapshots.
  • outputs/ligainsider: timestamped Bundesliga predicted-lineup snapshots, including formation slots and candidate alternatives where supplied.
  • outputs/kicker: timestamped Bundesliga predicted-lineup snapshots. Each record preserves Kicker’s raw lineup text, formation, coach, bench, unavailable players, and explanation alongside the common home/away schema.
  • outputs/kickbase: timestamped predicted-lineup snapshots transcribed from user-submitted Kickbase screenshots; player names remain source display names and are not resolved to canonical identities.
  • outputs/kbstats: KBStats player snapshots.
  • outputs/derived: multi-source normalized outputs.
  • outputs/optimized_squad: timestamped optimizer exports.
  • outputs/selected_lineups: canonical per-arena selected-lineup JSON snapshots. A newer confirmed selection replaces only that arena's file.
  • archive: superseded notebooks, historical data, and any unique recovered Jupyter checkpoints.
  • project_paths.py: the authoritative filesystem interface used by notebooks.
  • selected_lineups.py: shared selected-lineup persistence and replacement prompts.
  • manual_lineup_helpers.py: shared non-solver player-pool, rule, and validation logic used by the manual lineup notebook.

Generated JSON, CSV, and debug HTML must be written through project_paths.py; do not write generated files beside a notebook or into the project root.

Timestamped output retention

Timestamped output exporters invoke the shared cleanup in project_paths.py. The cleanup uses the final timestamp in a filename as the output creation time and retains the 10 newest files in each applicable family. Files without a supported creation timestamp in their filename are never removed.

Most families are distinguished by output directory, filename pattern with timestamps removed, and file extension. Meaningful labels such as matchday, percentile, and datatype remain separate. Two high-volume CSV directories use a single limit across their methods: outputs/expected_points retains its 10 newest expected-points CSVs, and outputs/optimized_squad retains its 10 newest optimizer CSVs. Run timestamped-output notebooks through their final retention cell to apply the same cleanup after notebook exports.

Setup

From PowerShell in the project root:

.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
jupyter lab

Run the automated checks with:

python -m pytest

The existing .venv stays at the root because moving a virtual environment can invalidate absolute paths stored inside it. The browser-backed scraping notebooks expect a compatible Chrome installation; their current configuration targets Chrome 150. If Kicker presents a browser-verification page, complete it manually in the Chrome window when prompted; the notebook does not attempt to bypass it.

Version-control conventions

All portable project assets are versioned, including data/, archive/, and outputs/. The local .venv, Python caches, and automatic Jupyter checkpoints are intentionally excluded because they are machine-specific or reproducible.

Do not commit credentials, API tokens, browser profiles, cookies, screenshots, or other sensitive local material. Keep each code change and its related output refresh in a small, descriptive commit. A selected-lineup file represents the current canonical choice for one arena; replacing it is intentional rather than creating a timestamped history.

Recommended pipeline

  1. Run notebooks/01_fixtures_and_teams/01_sofascore_match_ids.ipynb and/or 02_fotmob_match_ids.ipynb for the desired matchday.
  2. Run 03_build_bundesliga_team_reference.ipynb after selecting its MATCHDAY.
  3. Run the appropriate notebooks in notebooks/02_odds.
  4. Run any needed collectors in notebooks/03_team_data. Recent form and team statistics require outputs/sofascore/reference/bundesliga_teams.json.
  5. Run the derived notebooks. The high-rated-player notebook automatically uses the newest valid timestamped file in outputs/sofascore/team_form.
  6. Run the required collectors in notebooks/05_predicted_lineups: RotoWire, LigaInsider, Kicker, and/or the source-specific manual Kickbase workflow. Their snapshots share the match/home/away/player envelope while retaining source-specific details. Default lineup-blend weights are LigaInsider 4, Kickbase 3, Kicker 2, and RotoWire 1; only sources covering a team contribute to that team's blend.
  7. Create the required expected-points score file in notebooks/06_score_creation.
  8. Run an optimizer in notebooks/07_squad_optimisation, or run manually_create_lineup.ipynb to enter a formation, players, and captain interactively. A confirmed selection is stored in outputs/selected_lineups.

The Transfermarkt, KBStats, and FotMob collectors can run independently of the SofaScore team-reference pipeline when their own inputs are available.

Inputs and outputs

NotebookReadsWrites
SofaScore match IDsLive SofaScore APIoutputs/sofascore/match_ids
FotMob match IDsLive FotMob pages/APIoutputs/fotmob/match_ids
Team-reference builderSofaScore match IDsoutputs/sofascore/reference
SofaScore oddsSofaScore match IDsoutputs/sofascore/odds
FotMob oddsFotMob match IDsoutputs/fotmob/odds
Recent formTeam referenceoutputs/sofascore/team_form
Team statisticsTeam referenceoutputs/sofascore/team_stats
Transfermarkt squadsLive Transfermarkt pagesoutputs/transfermarkt/squads
RotoWire predicted lineupsLive RotoWire Bundesliga lineups pageoutputs/rotowire/predicted_lineups
LigaInsider predicted lineupsLive LigaInsider team pagesoutputs/ligainsider/predicted_lineups
Kicker predicted lineupsLive Kicker matchday and fixture pagesoutputs/kicker/predicted_lineups
Kickbase screenshot lineupsUser-submitted screenshots and fixture referenceoutputs/kickbase/predicted_lineups
KBStats playersLive KBStats APIoutputs/kbstats/players
Bundesliga snapshotTeam reference and live source dataoutputs/derived/bundesliga_snapshots
High-rated playersLatest team-form snapshotoutputs/sofascore/high_rated_players
SofaScore Kickbase-point averagesLatest team-form snapshot and live SofaScore match payloadsoutputs/sofascore/player_kickbase_point_averages
KBStats high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_high_average_players
KBStats last-five high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_last_5_high_average_players
Squad optimizersLatest expected-points CSV and matchday matchesTimestamped optimizer CSV and optional selected-lineup JSON
Manual lineupLatest expected-points CSV, matchday matches, arena, formation, and player choicesOptional canonical JSON in outputs/selected_lineups

Missing required inputs raise errors that include the exact expected path. Start Jupyter from the project root for the simplest path discovery; VS Code notebook execution is also supported.

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Kickbase Bundesliga data project

Work in progress. This repository preserves the project's source, curated reference data, notebooks, archived material, and generated output snapshots. Commit refreshed output files alongside the change that produced them so the data history remains reproducible.

This project supports a repeatable Bundesliga-to-Kickbase decision workflow: collect fixtures, odds, team, squad, player, and predicted-lineup data; derive comparable signals and expected-points scores; then build and save constrained Kickbase squads. Its live sources include SofaScore, FotMob, Transfermarkt, KBStats, RotoWire, LigaInsider, Kicker, and manually transcribed Kickbase lineups.

Project layout

  • notebooks/01_fixtures_and_teams: match-ID collectors and the shared Bundesliga team-reference builder.
  • notebooks/02_odds: SofaScore and FotMob matchday odds collectors.
  • notebooks/03_team_data: recent form, team statistics, Transfermarkt squads, and KBStats player collectors.
  • notebooks/04_derived_analysis: combined Bundesliga snapshots, high-rated-player analysis, KBStats average-points percentile filtering, and KBStats last-five-match-slot analysis.
  • notebooks/05_predicted_lineups: live predicted and confirmed lineup collectors from RotoWire, LigaInsider, and Kicker, plus compatible source-specific outputs.
  • notebooks/06_score_creation: score builders that combine source signals into expected-points files for the optimizers.
  • notebooks/07_squad_optimisation: optimizer notebooks for Bundesliga Arena, KickbaseKIS Arena, All Limits Arena, and Kickbase.insider Arena, plus manually_create_lineup.ipynb for manual entry.
  • notebooks/tests: diagnostic notebooks that are not production pipeline steps.
  • data/reference/kickbase: curated Kickbase scoring and event-frequency rules.
  • outputs/sofascore: SofaScore match IDs, odds, team reference, form, team statistics, high-rated-player results, and approximate Kickbase-point averages.
  • outputs/fotmob: FotMob match IDs and odds.
  • outputs/transfermarkt: squad exports and diagnostic HTML.
  • outputs/rotowire: timestamped Bundesliga predicted-lineup snapshots.
  • outputs/ligainsider: timestamped Bundesliga predicted-lineup snapshots, including formation slots and candidate alternatives where supplied.
  • outputs/kicker: timestamped Bundesliga predicted-lineup snapshots. Each record preserves Kicker’s raw lineup text, formation, coach, bench, unavailable players, and explanation alongside the common home/away schema.
  • outputs/kickbase: timestamped predicted-lineup snapshots transcribed from user-submitted Kickbase screenshots; player names remain source display names and are not resolved to canonical identities.
  • outputs/kbstats: KBStats player snapshots.
  • outputs/derived: multi-source normalized outputs.
  • outputs/optimized_squad: timestamped optimizer exports.
  • outputs/selected_lineups: canonical per-arena selected-lineup JSON snapshots. A newer confirmed selection replaces only that arena's file.
  • archive: superseded notebooks, historical data, and any unique recovered Jupyter checkpoints.
  • project_paths.py: the authoritative filesystem interface used by notebooks.
  • selected_lineups.py: shared selected-lineup persistence and replacement prompts.
  • manual_lineup_helpers.py: shared non-solver player-pool, rule, and validation logic used by the manual lineup notebook.

Generated JSON, CSV, and debug HTML must be written through project_paths.py; do not write generated files beside a notebook or into the project root.

Timestamped output retention

Timestamped output exporters invoke the shared cleanup in project_paths.py. The cleanup uses the final timestamp in a filename as the output creation time and retains the 10 newest files in each applicable family. Files without a supported creation timestamp in their filename are never removed.

Most families are distinguished by output directory, filename pattern with timestamps removed, and file extension. Meaningful labels such as matchday, percentile, and datatype remain separate. Two high-volume CSV directories use a single limit across their methods: outputs/expected_points retains its 10 newest expected-points CSVs, and outputs/optimized_squad retains its 10 newest optimizer CSVs. Run timestamped-output notebooks through their final retention cell to apply the same cleanup after notebook exports.

Setup

From PowerShell in the project root:

.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
jupyter lab

Run the automated checks with:

python -m pytest

The existing .venv stays at the root because moving a virtual environment can invalidate absolute paths stored inside it. The browser-backed scraping notebooks expect a compatible Chrome installation; their current configuration targets Chrome 150. If Kicker presents a browser-verification page, complete it manually in the Chrome window when prompted; the notebook does not attempt to bypass it.

Version-control conventions

All portable project assets are versioned, including data/, archive/, and outputs/. The local .venv, Python caches, and automatic Jupyter checkpoints are intentionally excluded because they are machine-specific or reproducible.

Do not commit credentials, API tokens, browser profiles, cookies, screenshots, or other sensitive local material. Keep each code change and its related output refresh in a small, descriptive commit. A selected-lineup file represents the current canonical choice for one arena; replacing it is intentional rather than creating a timestamped history.

Recommended pipeline

  1. Run notebooks/01_fixtures_and_teams/01_sofascore_match_ids.ipynb and/or 02_fotmob_match_ids.ipynb for the desired matchday.
  2. Run 03_build_bundesliga_team_reference.ipynb after selecting its MATCHDAY.
  3. Run the appropriate notebooks in notebooks/02_odds.
  4. Run any needed collectors in notebooks/03_team_data. Recent form and team statistics require outputs/sofascore/reference/bundesliga_teams.json.
  5. Run the derived notebooks. The high-rated-player notebook automatically uses the newest valid timestamped file in outputs/sofascore/team_form.
  6. Run the required collectors in notebooks/05_predicted_lineups: RotoWire, LigaInsider, Kicker, and/or the source-specific manual Kickbase workflow. Their snapshots share the match/home/away/player envelope while retaining source-specific details. Default lineup-blend weights are LigaInsider 4, Kickbase 3, Kicker 2, and RotoWire 1; only sources covering a team contribute to that team's blend.
  7. Create the required expected-points score file in notebooks/06_score_creation.
  8. Run an optimizer in notebooks/07_squad_optimisation, or run manually_create_lineup.ipynb to enter a formation, players, and captain interactively. A confirmed selection is stored in outputs/selected_lineups.

The Transfermarkt, KBStats, and FotMob collectors can run independently of the SofaScore team-reference pipeline when their own inputs are available.

Inputs and outputs

NotebookReadsWrites
SofaScore match IDsLive SofaScore APIoutputs/sofascore/match_ids
FotMob match IDsLive FotMob pages/APIoutputs/fotmob/match_ids
Team-reference builderSofaScore match IDsoutputs/sofascore/reference
SofaScore oddsSofaScore match IDsoutputs/sofascore/odds
FotMob oddsFotMob match IDsoutputs/fotmob/odds
Recent formTeam referenceoutputs/sofascore/team_form
Team statisticsTeam referenceoutputs/sofascore/team_stats
Transfermarkt squadsLive Transfermarkt pagesoutputs/transfermarkt/squads
RotoWire predicted lineupsLive RotoWire Bundesliga lineups pageoutputs/rotowire/predicted_lineups
LigaInsider predicted lineupsLive LigaInsider team pagesoutputs/ligainsider/predicted_lineups
Kicker predicted lineupsLive Kicker matchday and fixture pagesoutputs/kicker/predicted_lineups
Kickbase screenshot lineupsUser-submitted screenshots and fixture referenceoutputs/kickbase/predicted_lineups
KBStats playersLive KBStats APIoutputs/kbstats/players
Bundesliga snapshotTeam reference and live source dataoutputs/derived/bundesliga_snapshots
High-rated playersLatest team-form snapshotoutputs/sofascore/high_rated_players
SofaScore Kickbase-point averagesLatest team-form snapshot and live SofaScore match payloadsoutputs/sofascore/player_kickbase_point_averages
KBStats high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_high_average_players
KBStats last-five high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_last_5_high_average_players
Squad optimizersLatest expected-points CSV and matchday matchesTimestamped optimizer CSV and optional selected-lineup JSON
Manual lineupLatest expected-points CSV, matchday matches, arena, formation, and player choicesOptional canonical JSON in outputs/selected_lineups

Missing required inputs raise errors that include the exact expected path. Start Jupyter from the project root for the simplest path discovery; VS Code notebook execution is also supported.

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Kickbase Bundesliga data project

Work in progress. This repository preserves the project's source, curated reference data, notebooks, archived material, and generated output snapshots. Commit refreshed output files alongside the change that produced them so the data history remains reproducible.

This project supports a repeatable Bundesliga-to-Kickbase decision workflow: collect fixtures, odds, team, squad, player, and predicted-lineup data; derive comparable signals and expected-points scores; then build and save constrained Kickbase squads. Its live sources include SofaScore, FotMob, Transfermarkt, KBStats, RotoWire, LigaInsider, Kicker, and manually transcribed Kickbase lineups.

Project layout

  • notebooks/01_fixtures_and_teams: match-ID collectors and the shared Bundesliga team-reference builder.
  • notebooks/02_odds: SofaScore and FotMob matchday odds collectors.
  • notebooks/03_team_data: recent form, team statistics, Transfermarkt squads, and KBStats player collectors.
  • notebooks/04_derived_analysis: combined Bundesliga snapshots, high-rated-player analysis, KBStats average-points percentile filtering, and KBStats last-five-match-slot analysis.
  • notebooks/05_predicted_lineups: live predicted and confirmed lineup collectors from RotoWire, LigaInsider, and Kicker, plus compatible source-specific outputs.
  • notebooks/06_score_creation: score builders that combine source signals into expected-points files for the optimizers.
  • notebooks/07_squad_optimisation: optimizer notebooks for Bundesliga Arena, KickbaseKIS Arena, All Limits Arena, and Kickbase.insider Arena, plus manually_create_lineup.ipynb for manual entry.
  • notebooks/tests: diagnostic notebooks that are not production pipeline steps.
  • data/reference/kickbase: curated Kickbase scoring and event-frequency rules.
  • outputs/sofascore: SofaScore match IDs, odds, team reference, form, team statistics, high-rated-player results, and approximate Kickbase-point averages.
  • outputs/fotmob: FotMob match IDs and odds.
  • outputs/transfermarkt: squad exports and diagnostic HTML.
  • outputs/rotowire: timestamped Bundesliga predicted-lineup snapshots.
  • outputs/ligainsider: timestamped Bundesliga predicted-lineup snapshots, including formation slots and candidate alternatives where supplied.
  • outputs/kicker: timestamped Bundesliga predicted-lineup snapshots. Each record preserves Kicker’s raw lineup text, formation, coach, bench, unavailable players, and explanation alongside the common home/away schema.
  • outputs/kickbase: timestamped predicted-lineup snapshots transcribed from user-submitted Kickbase screenshots; player names remain source display names and are not resolved to canonical identities.
  • outputs/kbstats: KBStats player snapshots.
  • outputs/derived: multi-source normalized outputs.
  • outputs/optimized_squad: timestamped optimizer exports.
  • outputs/selected_lineups: canonical per-arena selected-lineup JSON snapshots. A newer confirmed selection replaces only that arena's file.
  • archive: superseded notebooks, historical data, and any unique recovered Jupyter checkpoints.
  • project_paths.py: the authoritative filesystem interface used by notebooks.
  • selected_lineups.py: shared selected-lineup persistence and replacement prompts.
  • manual_lineup_helpers.py: shared non-solver player-pool, rule, and validation logic used by the manual lineup notebook.

Generated JSON, CSV, and debug HTML must be written through project_paths.py; do not write generated files beside a notebook or into the project root.

Timestamped output retention

Timestamped output exporters invoke the shared cleanup in project_paths.py. The cleanup uses the final timestamp in a filename as the output creation time and retains the 10 newest files in each applicable family. Files without a supported creation timestamp in their filename are never removed.

Most families are distinguished by output directory, filename pattern with timestamps removed, and file extension. Meaningful labels such as matchday, percentile, and datatype remain separate. Two high-volume CSV directories use a single limit across their methods: outputs/expected_points retains its 10 newest expected-points CSVs, and outputs/optimized_squad retains its 10 newest optimizer CSVs. Run timestamped-output notebooks through their final retention cell to apply the same cleanup after notebook exports.

Setup

From PowerShell in the project root:

.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
jupyter lab

Run the automated checks with:

python -m pytest

The existing .venv stays at the root because moving a virtual environment can invalidate absolute paths stored inside it. The browser-backed scraping notebooks expect a compatible Chrome installation; their current configuration targets Chrome 150. If Kicker presents a browser-verification page, complete it manually in the Chrome window when prompted; the notebook does not attempt to bypass it.

Version-control conventions

All portable project assets are versioned, including data/, archive/, and outputs/. The local .venv, Python caches, and automatic Jupyter checkpoints are intentionally excluded because they are machine-specific or reproducible.

Do not commit credentials, API tokens, browser profiles, cookies, screenshots, or other sensitive local material. Keep each code change and its related output refresh in a small, descriptive commit. A selected-lineup file represents the current canonical choice for one arena; replacing it is intentional rather than creating a timestamped history.

Recommended pipeline

  1. Run notebooks/01_fixtures_and_teams/01_sofascore_match_ids.ipynb and/or 02_fotmob_match_ids.ipynb for the desired matchday.
  2. Run 03_build_bundesliga_team_reference.ipynb after selecting its MATCHDAY.
  3. Run the appropriate notebooks in notebooks/02_odds.
  4. Run any needed collectors in notebooks/03_team_data. Recent form and team statistics require outputs/sofascore/reference/bundesliga_teams.json.
  5. Run the derived notebooks. The high-rated-player notebook automatically uses the newest valid timestamped file in outputs/sofascore/team_form.
  6. Run the required collectors in notebooks/05_predicted_lineups: RotoWire, LigaInsider, Kicker, and/or the source-specific manual Kickbase workflow. Their snapshots share the match/home/away/player envelope while retaining source-specific details. Default lineup-blend weights are LigaInsider 4, Kickbase 3, Kicker 2, and RotoWire 1; only sources covering a team contribute to that team's blend.
  7. Create the required expected-points score file in notebooks/06_score_creation.
  8. Run an optimizer in notebooks/07_squad_optimisation, or run manually_create_lineup.ipynb to enter a formation, players, and captain interactively. A confirmed selection is stored in outputs/selected_lineups.

The Transfermarkt, KBStats, and FotMob collectors can run independently of the SofaScore team-reference pipeline when their own inputs are available.

Inputs and outputs

NotebookReadsWrites
SofaScore match IDsLive SofaScore APIoutputs/sofascore/match_ids
FotMob match IDsLive FotMob pages/APIoutputs/fotmob/match_ids
Team-reference builderSofaScore match IDsoutputs/sofascore/reference
SofaScore oddsSofaScore match IDsoutputs/sofascore/odds
FotMob oddsFotMob match IDsoutputs/fotmob/odds
Recent formTeam referenceoutputs/sofascore/team_form
Team statisticsTeam referenceoutputs/sofascore/team_stats
Transfermarkt squadsLive Transfermarkt pagesoutputs/transfermarkt/squads
RotoWire predicted lineupsLive RotoWire Bundesliga lineups pageoutputs/rotowire/predicted_lineups
LigaInsider predicted lineupsLive LigaInsider team pagesoutputs/ligainsider/predicted_lineups
Kicker predicted lineupsLive Kicker matchday and fixture pagesoutputs/kicker/predicted_lineups
Kickbase screenshot lineupsUser-submitted screenshots and fixture referenceoutputs/kickbase/predicted_lineups
KBStats playersLive KBStats APIoutputs/kbstats/players
Bundesliga snapshotTeam reference and live source dataoutputs/derived/bundesliga_snapshots
High-rated playersLatest team-form snapshotoutputs/sofascore/high_rated_players
SofaScore Kickbase-point averagesLatest team-form snapshot and live SofaScore match payloadsoutputs/sofascore/player_kickbase_point_averages
KBStats high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_high_average_players
KBStats last-five high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_last_5_high_average_players
Squad optimizersLatest expected-points CSV and matchday matchesTimestamped optimizer CSV and optional selected-lineup JSON
Manual lineupLatest expected-points CSV, matchday matches, arena, formation, and player choicesOptional canonical JSON in outputs/selected_lineups

Missing required inputs raise errors that include the exact expected path. Start Jupyter from the project root for the simplest path discovery; VS Code notebook execution is also supported.

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Kickbase Bundesliga data project

Work in progress. This repository preserves the project's source, curated reference data, notebooks, archived material, and generated output snapshots. Commit refreshed output files alongside the change that produced them so the data history remains reproducible.

This project supports a repeatable Bundesliga-to-Kickbase decision workflow: collect fixtures, odds, team, squad, player, and predicted-lineup data; derive comparable signals and expected-points scores; then build and save constrained Kickbase squads. Its live sources include SofaScore, FotMob, Transfermarkt, KBStats, RotoWire, LigaInsider, Kicker, and manually transcribed Kickbase lineups.

Project layout

  • notebooks/01_fixtures_and_teams: match-ID collectors and the shared Bundesliga team-reference builder.
  • notebooks/02_odds: SofaScore and FotMob matchday odds collectors.
  • notebooks/03_team_data: recent form, team statistics, Transfermarkt squads, and KBStats player collectors.
  • notebooks/04_derived_analysis: combined Bundesliga snapshots, high-rated-player analysis, KBStats average-points percentile filtering, and KBStats last-five-match-slot analysis.
  • notebooks/05_predicted_lineups: live predicted and confirmed lineup collectors from RotoWire, LigaInsider, and Kicker, plus compatible source-specific outputs.
  • notebooks/06_score_creation: score builders that combine source signals into expected-points files for the optimizers.
  • notebooks/07_squad_optimisation: optimizer notebooks for Bundesliga Arena, KickbaseKIS Arena, All Limits Arena, and Kickbase.insider Arena, plus manually_create_lineup.ipynb for manual entry.
  • notebooks/tests: diagnostic notebooks that are not production pipeline steps.
  • data/reference/kickbase: curated Kickbase scoring and event-frequency rules.
  • outputs/sofascore: SofaScore match IDs, odds, team reference, form, team statistics, high-rated-player results, and approximate Kickbase-point averages.
  • outputs/fotmob: FotMob match IDs and odds.
  • outputs/transfermarkt: squad exports and diagnostic HTML.
  • outputs/rotowire: timestamped Bundesliga predicted-lineup snapshots.
  • outputs/ligainsider: timestamped Bundesliga predicted-lineup snapshots, including formation slots and candidate alternatives where supplied.
  • outputs/kicker: timestamped Bundesliga predicted-lineup snapshots. Each record preserves Kicker’s raw lineup text, formation, coach, bench, unavailable players, and explanation alongside the common home/away schema.
  • outputs/kickbase: timestamped predicted-lineup snapshots transcribed from user-submitted Kickbase screenshots; player names remain source display names and are not resolved to canonical identities.
  • outputs/kbstats: KBStats player snapshots.
  • outputs/derived: multi-source normalized outputs.
  • outputs/optimized_squad: timestamped optimizer exports.
  • outputs/selected_lineups: canonical per-arena selected-lineup JSON snapshots. A newer confirmed selection replaces only that arena's file.
  • archive: superseded notebooks, historical data, and any unique recovered Jupyter checkpoints.
  • project_paths.py: the authoritative filesystem interface used by notebooks.
  • selected_lineups.py: shared selected-lineup persistence and replacement prompts.
  • manual_lineup_helpers.py: shared non-solver player-pool, rule, and validation logic used by the manual lineup notebook.

Generated JSON, CSV, and debug HTML must be written through project_paths.py; do not write generated files beside a notebook or into the project root.

Timestamped output retention

Timestamped output exporters invoke the shared cleanup in project_paths.py. The cleanup uses the final timestamp in a filename as the output creation time and retains the 10 newest files in each applicable family. Files without a supported creation timestamp in their filename are never removed.

Most families are distinguished by output directory, filename pattern with timestamps removed, and file extension. Meaningful labels such as matchday, percentile, and datatype remain separate. Two high-volume CSV directories use a single limit across their methods: outputs/expected_points retains its 10 newest expected-points CSVs, and outputs/optimized_squad retains its 10 newest optimizer CSVs. Run timestamped-output notebooks through their final retention cell to apply the same cleanup after notebook exports.

Setup

From PowerShell in the project root:

.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
jupyter lab

Run the automated checks with:

python -m pytest

The existing .venv stays at the root because moving a virtual environment can invalidate absolute paths stored inside it. The browser-backed scraping notebooks expect a compatible Chrome installation; their current configuration targets Chrome 150. If Kicker presents a browser-verification page, complete it manually in the Chrome window when prompted; the notebook does not attempt to bypass it.

Version-control conventions

All portable project assets are versioned, including data/, archive/, and outputs/. The local .venv, Python caches, and automatic Jupyter checkpoints are intentionally excluded because they are machine-specific or reproducible.

Do not commit credentials, API tokens, browser profiles, cookies, screenshots, or other sensitive local material. Keep each code change and its related output refresh in a small, descriptive commit. A selected-lineup file represents the current canonical choice for one arena; replacing it is intentional rather than creating a timestamped history.

Recommended pipeline

  1. Run notebooks/01_fixtures_and_teams/01_sofascore_match_ids.ipynb and/or 02_fotmob_match_ids.ipynb for the desired matchday.
  2. Run 03_build_bundesliga_team_reference.ipynb after selecting its MATCHDAY.
  3. Run the appropriate notebooks in notebooks/02_odds.
  4. Run any needed collectors in notebooks/03_team_data. Recent form and team statistics require outputs/sofascore/reference/bundesliga_teams.json.
  5. Run the derived notebooks. The high-rated-player notebook automatically uses the newest valid timestamped file in outputs/sofascore/team_form.
  6. Run the required collectors in notebooks/05_predicted_lineups: RotoWire, LigaInsider, Kicker, and/or the source-specific manual Kickbase workflow. Their snapshots share the match/home/away/player envelope while retaining source-specific details. Default lineup-blend weights are LigaInsider 4, Kickbase 3, Kicker 2, and RotoWire 1; only sources covering a team contribute to that team's blend.
  7. Create the required expected-points score file in notebooks/06_score_creation.
  8. Run an optimizer in notebooks/07_squad_optimisation, or run manually_create_lineup.ipynb to enter a formation, players, and captain interactively. A confirmed selection is stored in outputs/selected_lineups.

The Transfermarkt, KBStats, and FotMob collectors can run independently of the SofaScore team-reference pipeline when their own inputs are available.

Inputs and outputs

NotebookReadsWrites
SofaScore match IDsLive SofaScore APIoutputs/sofascore/match_ids
FotMob match IDsLive FotMob pages/APIoutputs/fotmob/match_ids
Team-reference builderSofaScore match IDsoutputs/sofascore/reference
SofaScore oddsSofaScore match IDsoutputs/sofascore/odds
FotMob oddsFotMob match IDsoutputs/fotmob/odds
Recent formTeam referenceoutputs/sofascore/team_form
Team statisticsTeam referenceoutputs/sofascore/team_stats
Transfermarkt squadsLive Transfermarkt pagesoutputs/transfermarkt/squads
RotoWire predicted lineupsLive RotoWire Bundesliga lineups pageoutputs/rotowire/predicted_lineups
LigaInsider predicted lineupsLive LigaInsider team pagesoutputs/ligainsider/predicted_lineups
Kicker predicted lineupsLive Kicker matchday and fixture pagesoutputs/kicker/predicted_lineups
Kickbase screenshot lineupsUser-submitted screenshots and fixture referenceoutputs/kickbase/predicted_lineups
KBStats playersLive KBStats APIoutputs/kbstats/players
Bundesliga snapshotTeam reference and live source dataoutputs/derived/bundesliga_snapshots
High-rated playersLatest team-form snapshotoutputs/sofascore/high_rated_players
SofaScore Kickbase-point averagesLatest team-form snapshot and live SofaScore match payloadsoutputs/sofascore/player_kickbase_point_averages
KBStats high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_high_average_players
KBStats last-five high-average playersLatest KBStats player snapshotoutputs/derived/kbstats_last_5_high_average_players
Squad optimizersLatest expected-points CSV and matchday matchesTimestamped optimizer CSV and optional selected-lineup JSON
Manual lineupLatest expected-points CSV, matchday matches, arena, formation, and player choicesOptional canonical JSON in outputs/selected_lineups

Missing required inputs raise errors that include the exact expected path. Start Jupyter from the project root for the simplest path discovery; VS Code notebook execution is also supported.

Releases

Packages

Contributors

Languages