Advertisement
campos20

Top Distance between 1st and 2nd WCA competition

Jan 17th, 2019
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.62 KB | None | 0 0
  1. # acampos@worldcubeassociation.org
  2.  
  3. # program made after a request from Felipe Cardim
  4. # place this program alongside with the tsv (unziped) export from
  5. # https://www.worldcubeassociation.org/results/misc/WCA_export.tsv.zip
  6. # and run it with
  7. # python program.py
  8. # it takes about 24 min on my PC
  9.  
  10. import csv
  11. from datetime import date
  12. from math import sin, cos, sqrt, atan2, radians
  13.  
  14. class Location:
  15.    
  16.     def __init__(self, latitude, longitude):
  17.    
  18.         self.latitude = latitude
  19.         self.longitude = longitude
  20.    
  21.     def get_latitude(self):
  22.         return self.latitude
  23.  
  24.     def get_longitude(self):
  25.         return self.longitude
  26.    
  27. class Competition:
  28.  
  29.     def __init__(self, name, date, location):
  30.  
  31.         self.name = name
  32.         self.date = date
  33.         self.location = location
  34.    
  35.     def get_name(self):
  36.         return self.name
  37.    
  38.     def get_date(self):
  39.         return self.date
  40.    
  41.     def get_location(self):
  42.         return self.location
  43.    
  44.     def __lt__(self, other):
  45.          return self.date < other.date
  46.    
  47.     def __str__(self):
  48.         return self.name
  49.  
  50. def dist(loc1, loc2):
  51.     # https://stackoverflow.com/questions/19412462/getting-distance-between-two-points-based-on-latitude-longitude
  52.  
  53.     R = 6373.0
  54.  
  55.     lat1, lon1 = loc1.get_latitude(), loc1.get_longitude()
  56.     lat2, lon2 = loc2.get_latitude(), loc2.get_longitude()
  57.  
  58.     dlon = lon2 - lon1
  59.     dlat = lat2 - lat1
  60.  
  61.     a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
  62.     c = 2 * atan2(sqrt(a), sqrt(1 - a))
  63.  
  64.     return R*c
  65.  
  66. def dis_comp(competition1, competition2):
  67.     return dist(competition1.get_location(), competition2.get_location())
  68.  
  69. def new_competition(name):
  70.  
  71.     with open("WCA_export_Competitions.tsv") as tsvfile:
  72.  
  73.         tsvreader = csv.reader(tsvfile, delimiter="\t")
  74.        
  75.         for line in tsvreader:
  76.        
  77.             if name == line[0]:
  78.  
  79.                 year = int(line[5])
  80.                 month = int(line[6])
  81.                 day = int(line[7])
  82.                
  83.                 this_date = date(year, month, day)
  84.                
  85.                 latitude = radians(float(line[18])/pow(10,6))
  86.                 longitude = radians(float(line[19])/pow(10,6))
  87.                
  88.                 location = Location(latitude, longitude)
  89.                
  90.                 return Competition(name, date, location)
  91.    
  92.     raise ValueError('Name for competition not found.')
  93.  
  94. def show_results(labels, results_list, list_of_lists, limit = float("inf"), direction = "asc"):
  95.     """Labels is intuitive. Results_list is the main order list and list_of_lists are other lists that are gonna be ordered as well (eg.: country, name, etc). You can set limit if you wish. Direction = 'asc' if you wanna the lower results first; direction = 'des' if you wanna bigger results first."""
  96.  
  97.     pos = 1
  98.  
  99.     prev = None
  100.    
  101.     out = "Pos"
  102.     for x in labels:
  103.         out += "\t"+x
  104.     print out
  105.    
  106.     temp = []
  107.     if direction == "asc":
  108.         temp = sorted(zip(results_list, range(len(results_list))))
  109.     elif direction == "des":
  110.         temp = sorted(zip(results_list, range(len(results_list))))[::-1]
  111.  
  112.     for a, b in temp:
  113.         out = ""
  114.         if a != prev:
  115.             if pos > limit:
  116.                 break
  117.             out+="%s)\t"%pos
  118.         else:
  119.             out += "---\t"
  120.         out += str(a)+"\t"
  121.         for x in list_of_lists:
  122.             out += str(x[b])+"\t"
  123.         print out.strip()
  124.         prev = a
  125.         pos += 1
  126.  
  127. def main():
  128.  
  129.     with open("WCA_export_Results.tsv") as tsvfile:
  130.  
  131.         tsvreader = csv.reader(tsvfile, delimiter="\t")
  132.        
  133.         ids = []
  134.         names = [] # competitors names
  135.         competitions = []
  136.        
  137.         prev = None
  138.         competition = None
  139.        
  140.         header = True
  141.  
  142.         for line in tsvreader:
  143.        
  144.             if header:
  145.                 header = False
  146.                 continue
  147.            
  148.             name = line[0] # competition name
  149.             if name != prev:
  150.                 competition = new_competition(name)
  151.             prev = name
  152.            
  153.             this_id = line[7]
  154.            
  155.             i = -1
  156.             try:
  157.                 i = ids.index(this_id)
  158.             except:
  159.                 this_name = line[6]
  160.  
  161.                 ids.append(this_id)
  162.                 names.append(this_name)
  163.            
  164.                 competitions.append([competition])
  165.                
  166.                 continue
  167.            
  168.             flag = True
  169.             for x in competitions[i]: # perhaps I could define the method __eq__ for the class and skip a few lines here
  170.                 if competition.get_name() == x.get_name():
  171.                     flag = False
  172.                     break
  173.             if flag:
  174.                 competitions[i].append(competition)
  175.    
  176.         for i in range(len(ids)):
  177.             competitions[i] = sorted(competitions[i])
  178.        
  179.         dist_list = []
  180.         name_list = []
  181.         comp1_list = []
  182.         comp2_list = []
  183.        
  184.         for i in range(len(ids)):
  185.             if len(competitions[i]) < 2:
  186.                 continue
  187.            
  188.             comp1 = competitions[i][0]
  189.             comp2 = competitions[i][1]
  190.            
  191.             dist_list.append(dis_comp(comp1, comp2))
  192.             name_list.append(names[i])
  193.             comp1_list.append(str(comp1))
  194.             comp2_list.append(str(comp2))
  195.        
  196.         labels = ["Dist (km)", "Name", "Competition 1", "Competition 2"]
  197.         list_of_lists = [name_list, comp1_list, comp2_list]
  198.         limit = 1000
  199.         show_results(labels, dist_list, list_of_lists, limit, "des")
  200.            
  201. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement