campos20

Top Distance between 1st and 2nd WCA competition

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