import degrees latitude y1 :float degrees longitude -output

import pandas as pdimport osfrom datetime import *import numpy as npfrom math import sin, cos, sqrt, atan2, radians, log, acos, asin, degreesfrom collections import Counter, defaultdictimport matplotlib.pyplot as pltfrom copy import deepcopyfrom itertools import chaindef roundTime(value): “”” -input value :str string of timestamp -returns dt :datetime -description rounds the time to the nearest minute “”” dt = datetime.strptime(value,”%Y-%m-%d %H:%M:%S”) if dt.second >= 30: dt = dt + timedelta(minutes=1) dt = dt.replace(second=0) return dt def getLocation(file): “”” fetches the name and location of the wind vanes in the given locations file -returns  locationDict :dict Keys are the names of the wind vanes, Values are the lat and long values “”” locationsFile = pd.read_excel(file)    locationsValues = locationsFile.values locationDict = {} for row in locationsValues:,1:4: locationDictrow0 = row1:3 return locationDict        def getDistance(x,y,x1,y1): “”” -input  x :float degrees latitude y :float degrees longitude x1 :float degrees latitude y1 :float degrees longitude -output Distance :float KM -description This function is the haversine formula. This formula calculates the distance between two coordinates. “”” R = 6373.0 # average radius earth lat1 = radians(x) lon1 = radians(y) lat2 = radians(x1) lon2 = radians(y1) dLon = lon2 – lon1 dLat = lat2 – lat1 a = sin(dLat / 2)**2 + cos(lat1) * cos(lat2) * sin(dLon / 2)**2 c = 2 * atan2(sqrt(a), sqrt(1 – a)) return R * cdef dirToClass(averageDir): “”” This function rounds the average direction to the nearest of the 16 possible wind directions. “”” if averageDir >= 348.75: return 0 return round(averageDir/22.5) * 22.5def speedToClass(averageSpeed): “”” round() doesn’t round .25 properly so a small amount is added.    “”” return round((averageSpeed+0.0000001)*10)/10 def errorFunction(trueValue, predictedValue): “”” -input trueValue :float This is a stored true value of the direction in degrees predictedValue :float “” -return error :float  -description the maximum error is 180 degrees. “”” if abs(trueValue – predictedValue) > 180: error = 360-abs(trueValue – predictedValue) else: error = abs(trueValue – predictedValue) return error def readFiles(dir=”UvA/”, speedThresh=0.7): “”” -input  dir :str Location of directory with the data files xlsx format tresh :Int A threshold for the minimum speed to call a datapoint reliable -return windlist :dict A dictionary where the key is a timestamp and the value is a list containing the direction, speed and name for all wind vanes -description This Function preprocesses the data. It loops over all wind vanes and rounds the timestamps to the nearest minute.  it adds the direction, speed and name of the wind vane to a Datarow which we store in a dictionary with the  rounded timestamp as key. We round the time because not all wind vanes have equal timestamps. Accessing the data is easier if all timestamps are equal “”” windDict = {} files = sorted(os.listdir(dir)) for i in range(0,len(files)-1,2): direction = pd.read_excel(dir+filesi).values     print(filesi.split()0) speed = pd.read_excel(dir+filesi+1).values  merged =     for j, row in enumerate(direction): if speedj1 > speedThresh: if roundTime(row0) in windDict: windDictroundTime(row0).append(row1,speedj1,filesi.split()0) else: windDictroundTime(row0) = row1,speedj1,filesi.split()0 return windDict def roundSpeed(row,r): “”” -input row :np.array containing all speeds r :number to round to -output newRow  :np.array containing all rounded speeds description takes a row and rounds all floats to closest N * r number “”” newRow = for speed in row: newRow.append(round(float(speed)/r) * r) return newRow    def getMostCommons(datarow): “”” -input datarow :np.array containing all data for a dateTime -output mostCommonSpeed : float mostCommon : float numberOfMostCommons : int directions : np.array description This function takes a datarow, loops over all items and counts the most common  direction and speed. When multiple most commons their directions are stored, and  the number of most directions will be set. “”” #direction mostCommon = Counter(datarow:,0).most_common() directions,countsList = list(zip(*mostCommon)) numberOfMostCommons = countsList.count(countsList0) mostCommon = float(mostCommon00) #speed roundedSpeedRow = roundSpeed(datarow:,1,5) mostCommonSpeed = float(Counter(roundedSpeedRow).most_common()00) return mostCommonSpeed, mostCommon, numberOfMostCommons, directions0:numberOfMostCommonsdef choseClosestMostCommon(directions,datarow,lat,long,locations): “”” -input directions : np.array datarow : np.array lat : float long : float locations : dict  -output most common : float description This function is called upon when multiple most commons are found and the closest one needs to be chosen. It loops in the datarow to find all wind vanes that point to the  most common direction and calculates the accumulative distance. The lowest distance is chosen. “”” nameDict = Counter() #for mostCommonDirection in directions: for direction,speed,name in datarow: if str(direction) in directions: nameDictdirection += getDistance(lat,long,locationsname0,locationsname1) # chose closest most common return sorted(nameDict.items(),key=lambda x:x1)00