Skip to content

Instantly share code, notes, and snippets.

@mmzsource
Last active February 6, 2017 19:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmzsource/84e3ad3e854420148348d71507fd6512 to your computer and use it in GitHub Desktop.
Save mmzsource/84e3ad3e854420148348d71507fd6512 to your computer and use it in GitHub Desktop.
League Tables with clojure boot
#!/usr/bin/env boot
(set-env! :dependencies '[[clj-http "2.3.0"] [cheshire "5.7.0"]])
(require '[clj-http.client :as client])
(require '[clojure.pprint :as pp])
;; Fifa country codes - https://en.wikipedia.org/wiki/List_of_FIFA_country_codes
(def countries [
{:id 426 :key :ENG :description "England"}
{:id 436 :key :ESP :description "Spain"}
{:id 430 :key :GER :description "Germany"}
{:id 433 :key :NED :description "Netherlands"}])
;; Team codes - https://liaison.reuters.com/tools/sports-team-codes
;; - Chanched Leipzig (LEI) to LEP to avoid clash with Leicester (LEI)
;; - Added VfL Wolfsburg (WOL)
;; - Added Werder Bremen (WER)
;; - Added FC Ingolstadt 04 (ING)
(def teams
{
"ADO Den Haag" :ADO
"Ajax Amsterdam" :AJA
"Deportivo Alavés" :ALV
"Arsenal FC" :ARS
"Athletic Bilbao" :ATB
"Athletic Club" :ATB
"Club Atlético de Madrid" :ATM
"FC Augsburg" :AUG
"AZ Alkmaar" :AZA
"FC Bayern Munich" :BAY
"FC Bayern München" :BAY
"Hertha BSC" :BER
"Betis" :BET
"Real Betis" :BET
"A.F.C. Bournemouth" :BOU
"AFC Bournemouth" :BOU
"Burnley" :BUR
"Burnley FC" :BUR
"Chelsea" :CHE
"Chelsea FC" :CHE
"Celta Vigo" :CLV
"RC Celta de Vigo" :CLV
"Deportivo La Coruña" :COR
"RC Deportivo La Coruna" :COR
"Crystal Palace" :CRY
"Crystal Palace FC" :CRY
"SV Darmstadt 98" :DAR
"Borussia Dortmund" :DOR
"Eibar" :EIB
"SD Eibar" :EIB
"Espanyol" :ESY
"RCD Espanyol" :ESY
"Everton" :EVE
"Everton FC" :EVE
"Excelsior" :EXC
"FC Barcelona" :FCB
"FC Ingolstadt" :FCI
"Feyenoord" :FEY
"Feyenoord Rotterdam" :FEY
"SC Freiburg" :FRE
"Go Ahead Eagles" :GAE
"Go Ahead Eagles Deventer" :GAE
"Getafe" :GET
"Sporting de Gijón" :GIJ
"Sporting Gijón" :GIJ
"Granada" :GRA
"Granada CF" :GRA
"FC Groningen" :GRO
"Hannover 96" :HAN
"Heracles Almelo" :HEA
"Heerenveen" :HEE
"SC Heerenveen" :HEE
"Hamburger SV" :HSV
"Hull City" :HUL
"Hull City FC" :HUL
"FC Ingolstadt 04" :ING
"1. FC Köln" :KOE
"Las Palmas" :LAP
"UD Las Palmas" :LAP
"Leganes" :LEG
"CD Leganes" :LEG
"Leicester City FC" :LEI
"RB Leipzig" :LEP
"Red Bull Leipzig" :LEP
"Bayer 04 Leverkusen" :LEV
"Bayer Leverkusen" :LEV
"FC Liverpool" :LIV
"Liverpool FC" :LIV
"Levante" :LVT
"1. FSV Mainz 05" :MAI
"Manchester City FC" :MCI
"Middlesbrough" :MID
"Middlesbrough FC" :MID
"Málaga" :MLA
"Málaga CF" :MLA
"Borussia Monchengladbach" :MON
"Bor. Mönchengladbach" :MON
"Manchester United" :MUN
"Manchester United FC" :MUN
"NEC" :NEC
"NEC Nijmegen" :NEC
"Osasuna" :OSA
"CA Osasuna" :OSA
"PEC Zwolle" :PEC
"PSV Eindhoven" :PSV
"Rayo Vallecano" :RAY
"Real Madrid" :REA
"Real Madrid CF" :REA
"Roda JC" :ROD
"Roda JC Kerkrade" :ROD
"FC Schalke 04" :SCH
"Sevilla FC" :SEV
"Eintracht Frankfurt" :SGE
"Real Sociedad" :SOC
"Real Sociedad de Fútbol" :SOC
"Southampton" :SOU
"Southampton FC" :SOU
"Sparta Rotterdam" :SPR
"Stoke City FC" :STK
"VfB Stuttgart" :STU
"Sunderland AFC" :SUN
"Swansea City AFC" :SWA
"Swansea City FC" :SWA
"Tottenham Hotspur FC" :TOT
"TSG 1899 Hoffenheim" :TSG
"Twente" :TWE
"FC Twente Enschede" :TWE
"Utrecht" :UTR
"FC Utrecht" :UTR
"Valencia CF" :VAL
"FC Villarreal" :VIL
"Villarreal CF" :VIL
"Vitesse" :VIT
"Vitesse Arnhem" :VIT
"Watford FC" :WAT
"West Bromwich Albion FC" :WBA
"Werder Bremen" :WER
"West Ham United" :WHU
"West Ham United FC" :WHU
"Willem II" :WIL
"Willem II Tilburg" :WIL
"VfL Wolfsburg" :WOL})
(def bets [
{:name "MasterMind" :pred-key :mas-pred :pen-key :mas-pen :predictions {
:ENG {
:MUN 1 :MCI 2 :ARS 3 :CHE 4 :LIV 5 :TOT 6 :EVE 7 :WHU 8 :LEI 9 :SOU 10
:STK 11 :SWA 12 :WBA 13 :CRY 14 :MID 15 :WAT 16 :BOU 17 :SUN 18 :HUL 19 :BUR 20
}
:ESP {
:FCB 1 :REA 2 :ATM 3 :SEV 4 :VAL 5 :VIL 6 :ATB 7 :CLV 8 :SOC 9 :COR 10
:GRA 11 :ESY 12 :MLA 13 :GIJ 14 :EIB 15 :LAP 16 :BET 17 :LEG 18 :ALV 19 :OSA 20
}
:GER {
:BAY 1 :DOR 2 :WOL 3 :LEV 4 :SCH 5 :MON 6 :BER 7 :MAI 8 :KOE 9 :AUG 10
:HSV 11 :ING 12 :WER 13 :TSG 14 :SGE 15 :DAR 16 :FRE 17 :LEP 18
}
:NED {
:PSV 1 :FEY 2 :AJA 3 :VIT 4 :AZA 5 :UTR 6 :HEA 7 :GRO 8 :PEC 9 :HEE 10
:ADO 11 :SPR 12 :NEC 13 :WIL 14 :GAE 15 :TWE 16 :EXC 17 :ROD 18
}}}
{:name "The Legend" :pred-key :leg-pred :pen-key :leg-pen :predictions {
:ENG {
:MCI 1 :MUN 2 :CHE 3 :LIV 4 :ARS 5 :TOT 6 :EVE 7 :WHU 8 :SOU 9 :LEI 10
:STK 11 :SWA 12 :CRY 13 :WAT 14 :WBA 15 :MID 16 :SUN 17 :HUL 18 :BUR 19 :BOU 20
}
:ESP {
:REA 1 :FCB 2 :ATM 3 :VAL 4 :VIL 5 :SEV 6 :ATB 7 :MLA 8 :SOC 9 :ESY 10
:CLV 11 :COR 12 :LAP 13 :BET 14 :ALV 15 :EIB 16 :GIJ 17 :LEG 18 :GRA 19 :OSA 20
}
:GER {
:BAY 1 :DOR 2 :WOL 3 :SCH 4 :LEV 5 :MON 6 :HSV 7 :BER 8 :MAI 9 :TSG 10
:AUG 11 :KOE 12 :SGE 13 :WER 14 :LEP 15 :FRE 16 :ING 17 :DAR 18
}
:NED {
:PSV 1 :AJA 2 :FEY 3 :VIT 4 :AZA 5 :GRO 6 :UTR 7 :PEC 8 :HEE 9 :HEA 10
:NEC 11 :ADO 12 :SPR 13 :ROD 14 :WIL 15 :TWE 16 :EXC 17 :GAE 18
}}}
{:name "The Scientist" :pred-key :sci-pred :pen-key :sci-pen :predictions {
:ENG {
:ARS 1 :MUN 2 :MCI 3 :CHE 4 :TOT 5 :LIV 6 :EVE 7 :STK 8 :WHU 9 :SOU 10
:SWA 11 :WBA 12 :SUN 13 :LEI 14 :CRY 15 :HUL 16 :WAT 17 :BOU 18 :MID 19 :BUR 20
}
:ESP {
:FCB 1 :REA 2 :ATM 3 :SEV 4 :VAL 5 :ATB 6 :VIL 7 :MLA 8 :SOC 9 :ESY 10
:CLV 11 :BET 12 :OSA 13 :COR 14 :GRA 15 :GIJ 16 :LAP 17 :EIB 18 :ALV 19 :LEG 20
}
:GER {
:BAY 1 :DOR 2 :LEV 3 :SCH 4 :WOL 5 :MON 6 :WER 7 :MAI 8 :HSV 9 :TSG 10
:SGE 11 :AUG 12 :BER 13 :FRE 14 :KOE 15 :ING 16 :DAR 17 :LEP 18
}
:NED {
:AJA 1 :PSV 2 :FEY 3 :AZA 4 :TWE 5 :GRO 6 :HEE 7 :VIT 8 :UTR 9 :HEA 10
:ADO 11 :PEC 12 :NEC 13 :ROD 14 :WIL 15 :EXC 16 :GAE 17 :SPR 18
}}}])
(defn filter-team-stats [team-stats]
(map team-stats [:position :teamName :playedGames :wins :draws :losses :points :goals :goalsAgainst]))
(defn transform-team-stats [team-stats]
(zipmap [:pos :team :games :win :draw :loss :pts :goals :against] (filter-team-stats team-stats)))
(defn compose-prediction [country-key team-key position bet]
(let [
pred-key (:pred-key bet)
prediction (team-key (country-key (:predictions bet)) 999)
pen-key (:pen-key bet)
penalty (Math/abs (- prediction position))
result {pred-key prediction pen-key penalty}]
result))
(defn concat-predictions [team-stat country-key team-key]
(merge team-stat (mapcat (partial compose-prediction country-key team-key (:pos team-stat)) bets)))
(defn add-bet-scores [country-key team-stat]
(let [
team-key (get teams (:team team-stat))
pred-map (concat-predictions team-stat country-key team-key)]
pred-map))
(defn get-penalty [pen-key bet-score]
(pen-key bet-score))
(defn avg [coll] (double (/ (reduce + coll) (count coll))))
(defn compose-bet-stats [bet-scores bet]
(let [
name (:name bet)
pen-key (:pen-key bet)
penalty-points (map (partial get-penalty pen-key) bet-scores)
penalty-sum (reduce + penalty-points)
best3 (list (take 3 (sort penalty-points)))
worst3 (list (take 3 (reverse (sort penalty-points))))
avg (format "%.2f" (avg penalty-points))
result {:name name :penalty-points penalty-points :sum-penalty penalty-sum :best3 best3 :worst3 worst3 :avg avg}]
result))
(defn report [country]
(let [
response (client/get (str "http://api.football-data.org/v1/competitions/" (:id country) "/leagueTable") {:as :json})
league-table (map transform-team-stats (:standing (:body response)))
bet-scores (map (partial add-bet-scores (:key country)) league-table)
bet-stats (map (partial compose-bet-stats bet-scores) bets)]
(println)
(println "=======================================================================================================")
(println "Date: " (java.util.Date.))
(pp/print-table [:pos :team :games :win :draw :loss :pts :goals :against :mas-pred :mas-pen :leg-pred :leg-pen :sci-pred :sci-pen] bet-scores)
(println)
(pp/print-table [:name :sum-penalty :best3 :worst3 :avg] (sort-by :sum-penalty bet-stats))
(println)
(println "=======================================================================================================")
(println)))
;; TODO:
;; - calculate total penalty over all leagues
;; - slechtste en beste competitie
;; - remove key duplication in code --> (concat [:a :b :c] [:d :e])
;; - extract methods
;; - add tests (and test mode?)
;; - cleanup teams?
;; - store results and diff with later calculations
(defn -main [& args]
(doall (map report countries))
(System/exit 0))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment