Source Code Table Tennis Ranking
Total Page:16
File Type:pdf, Size:1020Kb
Init ClearAll["Global`*"] SetDirectory[NotebookDirectory[]]; Function Country IOC Shorts (CHN) to short name (China). ITTF use IOC code not ISO- Alpha 3. countryCodeList= Import["input/countries(204)_olympics.csv"]; (* Remove the first title*) countryCodeList= Rest[countryCodeList]; Shortnamecountry= countryCodeList[[All, 2]]; IOC3country= countryCodeList[[All, 1]]; ToShortNameRule= Thread[IOC3country -> Shortnamecountry]; Take[ToShortNameRule, 10] {AFG→ Afghanistan, ALB→ Albania, ALG→ Algeria, AND→ Andorra, ANG→ Angola, ANT→ Antigua and Barbuda, ARG→ Argentina, ARM→ Armenia, ARU→ Aruba, ASA→ American Samoa} Data is a mix name (player name and country name) nametoFlag[mixName_]:= Block{split}, split= StringExtract[mixName,-1]; (*CHN*) split= StringDelete[split, "("]; split= StringDelete[split, ")"]; (*CHN→ CHN*) split= split/. ToShortNameRule; Show[CountryData[split, "Flag"], ImageSize→ 22] getNameFromMix[mixName_]:= Block[{playerName}, (* remove the country short name*) playerName= StringExtract[mixName, 1 ;;-2]; (* add "space" in{MA,Long} and Join it "MA Long"*) playerName= StringRiffle[playerName] ] Data is a match getplayerNameFromMatch[match_]:= Block[{playerAName, playerXName, mixA, mixX}, mixA= match〚5〛; Printed by Wolfram Mathematica Student Edition 2 ittf ranking.nb mixX= match〚11〛; (* return playerA Name and playerX Name*) playerAName= getNameFromMix[mixA]; playerXName= getNameFromMix[mixX]; {playerAName, playerXName} ] getplayerMixNameFromMatch[match_]:= Block[{mixA, mixX}, (* get player Name and Country(MIX) *) mixA= match〚5〛; mixX= match〚11〛; (* return mixA and mixX*) {mixA, mixX} ] matchPoint[match_]:= Block[{winnerID, looserID, playerIDA, playerIDX, round, point, eventcoeff, eventName, scorecoeff, scoreA, scoreX, deltascore, tourName, tourcoeff}, tourName= match[[2]]; tourcoeff= Which[ StringContainsQ[tourName, "Olympic Games"], 9, StringContainsQ[tourName, "World Table Tennis Championships"], 7, StringContainsQ[tourName, "Men's World Cup"], 5, StringContainsQ[tourName, "World Tour"], 4, StringContainsQ[tourName, "Asian Cup"], 3, StringContainsQ[tourName, "European"], 2, StringContainsQ[tourName, "ITTF Asian Championships"], 3.5, StringContainsQ[tourName, "ITTF Europe Cup"], 3, StringContainsQ[tourName, "Challenge"], 1.5, StringContainsQ[tourName, "Oceania Cup"], 1, StringContainsQ[tourName, "Panam Cup"], 1, StringContainsQ[tourName, "Africa Cup"], 1, (* Else*) True, 0.8 ]; winnerID= match[[20]]; playerIDA= match[[3]]; playerIDX= match[[9]]; If[winnerID⩵ playerIDA, looserID= playerIDX, looserID= playerIDA]; scoreA= match[[18]]; scoreX= match[[19]]; deltascore= Abs[scoreA- scoreX]; scorecoeff= Which[ deltascore⩵ 4, 1.5, deltascore⩵ 3, 1.332, deltascore⩵ 2, 1.166, deltascore⩵ 1, 1 ]; eventName= match[[15]]; round= match[[17]]; point= Which[ Printed by Wolfram Mathematica Student Edition ittf ranking.nb 3 (* "Men's Singles(Pre. Rounds)"*) eventName⩵ "Men's Singles(Pre. Rounds)", 2, (* "Men's Singles"*) eventName⩵ "Men's Singles" && round⩵ 128, 7, eventName⩵ "Men's Singles" && round⩵ 64, 10, eventName⩵ "Men's Singles" && round⩵ 32, 13, eventName⩵ "Men's Singles" && round⩵ 16, 17, eventName⩵ "Men's Singles" && round⩵ 8, 21, eventName⩵ "Men's Singles" && round⩵ 4, 24, eventName⩵ "Men's Singles" && round⩵ 2, 25, (* Else*) True, 1 ]; {winnerID, point* tourcoeff* scorecoeff} ] Data is a tournament (list of match) takeSingle[data_]:= Block{}, Select[data, #[[-1]]⩵1&] (* Select only The last columnKind equal to 1Single*) takeDouble[data_]:= Block{}, Select[data, #[[-1]]⩵2&] (* Select only The last columnKind equal to 2Double*) takeYear[data_, year_Number]:= Block[{}, Select[data, #[[1]]⩵ year &] ] takeEvent[data_, event_String]:= Block[{}, Select[data, #[[15]]⩵ event &] ] takeCountry[data_, country_String]:= Block{}, Selectdata,#[[4]]⩵ country ||#[[10]]⩵ country& takePlayer[data_, playerName_String]:= Block{}, (*Selectdata,#[[5]]⩵playerName||#[[11]]⩵playerName&*) Selectdata,StringContainsQ[#[[5]], playerName] || StringContainsQ[#[[11]], playerName]& getplayerName[data_, ID_]:= Block[{line, firstPosition, name}, line= First[FirstPosition[data, ID]]; (* that could be playerA or playerX, so please verify*) (* firstPostion= 3, is the player A, firstPosition= 9, is the player X*) firstPosition= First@FirstPosition[data[[line]], ID]; name= Which[firstPosition⩵ 3, data[[line, 5]], firstPosition⩵ 9, data[[line, 11]]] Printed by Wolfram Mathematica Student Edition 4 ittf ranking.nb ] findAllMatchOfPlayerName[data_, name_]:= Block[{listMixA, listMixX, listA, listX, lineA, lineX}, (* player name and country short name*) listMixA= data〚All, 5〛; listMixX= data〚All, 11〛; (* remove the country short name*) listA= StringExtract[#, 1 ;;-2]&/@ listMixA; listA= StringRiffle/@ listA; listX= StringExtract[#, 1 ;;-2]&/@ listMixX; listX= StringRiffle/@ listX; (* return the match line in the Data*) lineA= Flatten@Position[listA, name]; lineX= Flatten@Position[listX, name]; Flatten[{lineA, lineX}] ] takeMatchBetweenPlayer[data_, name1_, name2_]:= Block{}, (* return the match results*) Selectdata, StringContainsQ[#[[5]], name1]&&StringContainsQ[#[[11]], name2] || StringContainsQ[#[[5]], name2]&&StringContainsQ[#[[11]], name1]& getplayerID[data_, name_]:= Block[{matchlineList, firstline, playercolumn, match, nameA, nameX, id}, matchlineList= findAllMatchOfPlayerName[data, name]; firstline= First[matchlineList]; (* that could be playerA or playerX, so please verify*) match= data〚firstline〛; {nameA, nameX} = getplayerNameFromMatch[match]; id= Which[name⩵ nameA, match〚3〛, name⩵ nameX, match〚9〛] ] pointRun[data_]:= Block[{list, result}, (* list of{winnerID, point} *) list= matchPoint[#]&/@ data; result= List @@@ Normal[GroupBy[list, First→ Last, Total]]; Reverse[SortBy[result, Last]] ] showRanking[data_, pointList_, topn_]:= Block[{topnData, result, title}, topnData= Take[pointList, topn]; result = {#, getplayerName[data, topnData[[#, 1]]], topnData[[#, 2]], nametoFlag[getplayerName[data, topnData[[#, 1]]]]}&/@ Range[topn]; title= "World Ranking Men Senior by EmRatThich(May- 2018)"; Labeled[Grid[result, Frame→ All], title, Top] ] Input Data from Several Years Printed by Wolfram Mathematica Student Edition ittf ranking.nb 5 (* inputData[{2016,2017}] *) inputData[years_List]:= Block[{fileNameList}, fileNameList= "input/" <> ToString[#]&/@ years; fileNameList= StringJoin[#, ".csv"]&/@ fileNameList; Flatten[Import/@ fileNameList, 1] ] Input data= inputData[{2016, 2017}];// Timing Take[data, 5] // TableForm {5.99044, Null} Year Tournament Player ID A 2016 2016- 11th Fajr Cup, Junior and Cadet Open, Qarvin(IRI) 131 536 2016 2016- 11th Fajr Cup, Junior and Cadet Open, Qarvin(IRI) 134 259 2016 2016- 11th Fajr Cup, Junior and Cadet Open, Qarvin(IRI) 131 522 2016 2016- 11th Fajr Cup, Junior and Cadet Open, Qarvin(IRI) 121 940 data// Length 87 690 Printed by Wolfram Mathematica Student Edition 6 ittf ranking.nb Test getplayerID[data, "FAN Zhendong"] takeMatchBetweenPlayer[data, "FAN Zhendong", "XU Xin"] 121 404 {{2016, 2016- Men's World Cup, Saarbrucken(GER), 121 404, CHN, FAN Zhendong(CHN),,,(), 110 267, CHN, XU Xin(CHN), ,,(), Men's Singles, , 2, 4, 1, 121 404, FAN Zhendong, , , 1}, {2016, 2016- World Tour Grand Finals, Doha(QAT), 110 267, CHN, XU Xin(CHN),,,(), 121 404, CHN, FAN Zhendong(CHN),,, (), Men's Singles, , 4, 2, 4, 121 404, FAN Zhendong, , , 1}, {2016, 2016- World Tour, Korea Open, Incheon(KOR), 110 267, CHN, XU Xin(CHN),,,(), 121 404, CHN, FAN Zhendong(CHN), ,,(), Men's Singles, , 4, 4, 3, 110 267, XU Xin, , , 1}, {2016, 2016- World Tour, Kuwait Open, Kuwait City(KUW), 110 267, CHN, XU Xin(CHN), 110 553, CHN, ZHANG Jike(CHN), 121 404, CHN, FAN Zhendong(CHN), 105 649, CHN, MA Long(CHN), Men's Doubles, , 4, 3, 0, 110 267, XU Xin, 110 553, ZHANG Jike, 2}, {2016, 2016- World Tour, LAOX Japan Open, Tokyo(JPN), 110 267, CHN, XU Xin(CHN),,,(), 121 404, CHN, FAN Zhendong(CHN),, ,(), Men's Singles, , 2, 1, 4, 121 404, FAN Zhendong, , , 1}, {2016, 2016- World Tour, Qatar Open, Doha(QAT), 110 267, CHN, XU Xin(CHN),,,(), 121 404, CHN, FAN Zhendong(CHN),,, (), Men's Singles, , 4, 2, 4, 121 404, FAN Zhendong, , , 1}, {2017, 2017- World Tour, Swedish Open, Stockholm(SWE), 121 404, CHN, FAN Zhendong(CHN),,,(), 110 267, CHN, XU Xin(CHN), ,,(), Men's Singles, , 2, 1, 4, 110 267, XU Xin, , , 1}} Run test= takeEvent[data, "Men's Singles(Pre. Rounds)"]~ Join~takeEvent[data, "Men's Singles"]; currentRate= pointRun[test]; Top 100 Old Rating (Dec 2017) --> Make the first Old Rating (Do not run again) Printed by Wolfram Mathematica Student Edition ittf ranking.nb 7 New Rate = 0.7 Old Rate + 0.3 Current Rate newRateCalculate[old_, current_]:= Block[{list, result, oldcoeff, currentcoeff, old2, current2}, oldcoeff= 0.7; currentcoeff= 0.3; old2= Transpose[{old[[All, 1]], old[[All, 2]] * oldcoeff}]; current2= Transpose[{current[[All, 1]], current[[All, 2]] * currentcoeff}]; list= Join[old2, current2]; result= List @@@ Normal[GroupBy[list, First→ Last, Total]]; Reverse[SortBy[result, Last]] ] oldRate100= ReadList["old rate.dat",{Number, Number}]; currentRate100= Take[currentRate, 100]; newRate= newRateCalculate[oldRate100, currentRate100]; (* Top 15 Current Rate*) showRanking[test, currentRate, 20]; ListPlot[Take[currentRate[[All, 2]], 20], PlotRange→ All]; (* Top 15 New Rate*) showRanking[test, newRate, 20] ListPlot[Take[newRate[[All, 2]], 20], PlotRange→ All] Take[newRate, 20] // TableForm Printed by Wolfram Mathematica Student Edition 8 ittf ranking.nb World Ranking Men Senior by EmRatThich(May- 2018) 1 MA Long(CHN) 4455.72 2 FAN Zhendong(CHN) 4045.46 3 BOLL Timo(GER)