def checkMaxDrop(city, name, recentLimit=180): maxDiff = 0.0 maxDiffD = None lastV = None lastD = None lastUtcTime = None for utcTime in sorted(data.keys(), reverse=True): localTime = utcTime.astimezone(stations.city[city].timezone) date = localTime.date() v = data[utcTime].TEMP if v is None: lastV = None continue if lastV != None and (lastUtcTime - utcTime) == dt.timedelta(hours=1): diff = v - lastV if diff >= maxDiff: if (dt.date.today() - date).days > recentLimit: dayName = dayOfWeek(maxDiffD[1].date()) if (dt.date.today() - maxDiffD[0].date()).days == 1: dayName = 'Yesterday' elif (dt.date.today() - maxDiffD[0].date()).days == 0: dayName = 'Today' since = sinceWhen.sinceWhen(city, daily.AVG_WIND.index, date) text = ("{} between {}➜{}," " the temp dropped from {:.1f}℃➜{:.1f}℃" " which was #{}'s largest 1-hour drop {}".format( dayName, clock12(city, 'H{}'.format(maxDiffD[0].hour)), clock12(city, 'H{}'.format(maxDiffD[1].hour)), float(maxDiffValue[0]), float(maxDiffValue[1]), stations.city[city].name, since)) (use, tweet) = shouldTweetSuffix(city, text) if use: delayedTweets.addToListForCity(city, tweet, urgent=True) print('ok') else: print('skipping') break if (utcTime.timestamp() <= lastdatetimestamp.get(name, 0) or (dt.date.today() - date).days >= 7): break maxDiff = diff maxDiffValue = v, lastV maxDiffD = localTime, lastD lastV = v lastD = localTime lastUtcTime = utcTime lastdatetimestamp[name] = int(sorted(data.keys())[-1].timestamp())
def checkMaxDrop2(city, name, recentLimit=180): maxDiff = 0.0 maxDiffD = None lastV = None lastD = None lastUtcTime = None for utcTime, v in genReverseTemperatures(): localTime = utcTime.astimezone(stations.city[city].timezone) date = localTime.date() print(v) if v is None: lastV = None continue if lastV != None: diff = v - lastV if diff >= maxDiff: if (dt.date.today() - date).days > recentLimit: dayName = dayOfWeek(maxDiffD[1].date()) if (dt.date.today() - maxDiffD[0].date()).days == 1: dayName = 'Yesterday' elif (dt.date.today() - maxDiffD[0].date()).days == 0: dayName = 'Today' since = sinceWhen.sinceWhen( city, daily.AVG_WIND.index, date) text = ("{} between {}➜{}," " the temp dropped from {:.1f}℃➜{:.1f}℃" " which was #{}'s largest 1-hour drop {}" .format(dayName, clock12(city, 'H{}'.format(maxDiffD[0].hour)), clock12(city, 'H{}'.format(maxDiffD[1].hour)), float(maxDiffValue[0]), float(maxDiffValue[1]), stations.city[city].name, since)) (use, tweet) = shouldTweetSuffix( city, text) if use: delayedTweets.addToListForCity(city, tweet, urgent=True) print('ok') else: print('skipping') break maxDiff = diff maxDiffValue = v, lastV maxDiffD = localTime, lastD lastV = v lastD = localTime lastUtcTime = utcTime
def checkMinWindchill(city, name): #import pudb; pu.db if 'MIN_WINDCHILL' in stations.city[city].skipDailyFields: return None minWindchill = 99.0 minWindchillD = None for utcTime in reversed(sorted(data.keys())): localTime = utcTime.astimezone(stations.city[city].timezone) date = localTime.date() windchill = data[utcTime].windchill if windchill is not None: if windchill <= minWindchill: if (dt.date.today() - date).days > 180: dayName = dayOfWeek(minWindchillD.date()) if (dt.date.today() - minWindchillD.date()).days == 1: dayName = 'Yesterday' elif (dt.date.today() - minWindchillD.date()).days == 0: dayName = 'Today' since = sinceWhen.sinceWhen(city, daily.MIN_WINDCHILL.index, date) text = ( "{} at {}, the windchill was {:.1f}" " which made it #{}'s windchilliest hour {}".format( dayName, clock12(city, 'H{}'.format(minWindchillD.hour)), float(minWindchill), stations.city[city].name, since)) (use, tweet) = shouldTweetSuffix(city, text) if use: delayedTweets.addToListForCity(city, tweet, urgent=True) print('ok') else: print('skipping') break if (utcTime.timestamp() <= lastdatetimestamp.get(name, 0) or (dt.date.today() - date).days >= 7): break minWindchill = windchill minWindchillD = localTime lastdatetimestamp[name] = int(sorted(data.keys())[-1].timestamp())
def checkMaxHumidity(city, name): if 'MEAN_HUMIDITY' in stations.city[city].skipDailyFields: return None maxHumidity = 0 maxHumidityD = None for utcTime in reversed(sorted(data.keys())): localTime = utcTime.astimezone(stations.city[city].timezone) date = localTime.date() v = data[utcTime].REL_HUM if (v is not None and ((type(v) is str and len(v) > 0) or type(v) is not str)): humidity = int(v) if humidity >= maxHumidity: if (dt.date.today() - date).days > 180: dayName = dayOfWeek(maxHumidityD.date()) if (dt.date.today() - maxHumidityD.date()).days == 1: dayName = 'Yesterday' elif (dt.date.today() - maxHumidityD.date()).days == 0: dayName = 'Today' since = sinceWhen.sinceWhen(city, daily.AVG_WIND.index, date) text = ("{} at {}, the humidity was {}%" " which made it #{}'s moistest hour {}".format( dayName, clock12(city, 'H{}'.format(maxHumidityD.hour)), maxHumidity, stations.city[city].name, since)) #import pudb; pu.db (use, tweet) = shouldTweetSuffix(city, text) if use: delayedTweets.addToListForCity(city, tweet, urgent=True) print('ok') else: print('skipping') break if (utcTime.timestamp() <= lastdatetimestamp.get(name, 0) or (dt.date.today() - date).days >= 7): break maxHumidity = humidity maxHumidityD = localTime lastdatetimestamp[name] = int(sorted(data.keys())[-1].timestamp())
def checkMaxWind(city, name): maxWind = 0.0 maxWindD = None for utcTime in reversed(sorted(data.keys())): localTime = utcTime.astimezone(stations.city[city].timezone) date = localTime.date() v = data[utcTime].WIND_SPD if (v is not None and ((type(v) is str and len(v) > 0) or type(v) is not str)): wind = int(v) if wind >= maxWind: if (dt.date.today() - date).days > 180: dayName = dayOfWeek(maxWindD.date()) if (dt.date.today() - maxWindD.date()).days == 1: dayName = 'Yesterday' elif (dt.date.today() - maxWindD.date()).days == 0: dayName = 'Today' since = sinceWhen.sinceWhen(city, daily.AVG_WIND.index, date) text = ("{} at {}, the wind was {}km/h" " which made it #{}'s windiest hour {}".format( dayName, clock12(city, 'H{}'.format(maxWindD.hour)), maxWindValue, stations.city[city].name, since)) (use, tweet) = shouldTweetSuffix(city, text) if use: delayedTweets.addToListForCity(city, tweet, urgent=True) print('ok') else: print('skipping') break if (utcTime.timestamp() <= lastdatetimestamp.get(name, 0) or (dt.date.today() - date).days >= 7): break maxWind = wind maxWindValue = wind maxWindD = localTime lastdatetimestamp[name] = int(sorted(data.keys())[-1].timestamp())
def checkMaxRise(city, name): offsets = tuple(range(2)) maxDiff = [0.0 for o in offsets] maxDiffValue = [None for o in offsets] maxDiffD = [None for o in offsets] lastV = deque([None for o in offsets]) lastD = deque([None for o in offsets]) done = [False for o in offsets] for utcTime, vals in fillReverseSortedGapsWithNone(data): if sum(done) == len(done): break if vals is None: lastV.insert(0, None) lastD.insert(0, None) continue localTime = utcTime.astimezone(stations.city[city].timezone) #print dateTime date = localTime.date() v = vals.TEMP if v is None: lastV.insert(0, None) lastD.insert(0, None) continue #print v for offset in offsets: if lastV[offset] == None or done[offset]: continue diff = lastV[offset] - v if diff >= maxDiff[offset]: if (dt.date.today() - date).days > 180: dayName = dayOfWeek(maxDiffD[offset][1].date()) if (dt.date.today() - maxDiffD[offset][0].date()).days == 1: dayName = 'Yesterday' elif (dt.date.today() - maxDiffD[offset][0].date()).days == 0: dayName = 'Today' #import pudb; pu.db since = sinceWhen.sinceWhen(city, daily.MAX_TEMP.index, date) text = ("{} between {} and {}," " the temp jumped from {:.1f}℃➜{:.1f}℃" " which was #{}'s largest {}-hour jump {}".format( dayName, clock12(city, 'H{}'.format( maxDiffD[offset][0].hour)), clock12(city, 'H{}'.format( maxDiffD[offset][1].hour)), float(maxDiffValue[offset][0]), float(maxDiffValue[offset][1]), stations.city[city].name, offset + 1, since)) (use, tweet) = shouldTweetSuffix(city, text) if use: delayedTweets.addToListForCity(city, tweet, urgent=True) print('ok') else: print('skipping') done[offset] = True if (utcTime.timestamp() <= lastdatetimestamp.get(name, 0) or (dt.date.today() - date).days >= 7): done[offset] = True maxDiff[offset] = diff maxDiffValue[offset] = v, lastV[offset] maxDiffD[offset] = localTime, lastD[offset] lastV.insert(0, v) lastD.insert(0, localTime) lastdatetimestamp[name] = int(sorted(data.keys())[-1].timestamp())
def maybeTweetRecordSince( self, city, v, recordValue, alreadyReportedRecord, hour, sampleDay, datemarker, maxRecord): #if sampleDay.day == 3 and self.field.name == 'TOTAL_SNOW_CM': # import pudb; pu.db if ( maxRecord is False and self.field in (daily.MAX_HUMIDEX, daily.TOTAL_RAIN_MM, daily.SNOW_ON_GRND_CM, daily.SPD_OF_MAX_GUST_KPH, ) ): return if ( maxRecord is True and self.field in (daily.MIN_WINDCHILL, ) ): return media=None limit=90 #days if self.field in (daily.MAX_TEMP, daily.MIN_TEMP, daily.MAX_HUMIDEX, daily.MIN_WINDCHILL, daily.AVG_WINDCHILL, daily.MEAN_TEMP, daily.AVG_DEWPOINT): limit=400 #days if self.limitToThisMonth: limit=365*4+32 #days #print (sampleDay, float(v), self.field.name, repr(recordValue)) if recordValue != None: ageOfRecord = (today(city) - recordValue[1]).days if recordValue == None or ageOfRecord > limit: alreadyReportedRecordTweet = None if alreadyReportedRecord != None: alreadyReportedRecordTweet = alreadyReportedRecord.tweet #print("\n--------------------------------------------------------------------------------\nCorrecting a previous record of {:.1f}".format(alreadyReportedRecord.value)) #print("OldTweet: ", alreadyReportedRecord.tweet) dayString = 'today is' possessiveDayString = 'Today\'s' if sampleDay == today(city)-datetime.timedelta(days=1): dayString = 'yesterday was' possessiveDayString = 'Yesterday\'s' elif sampleDay != today(city): dayString = '{} was'.format(dayOfWeek(sampleDay)) possessiveDayString = '{}\'s'.format(dayOfWeek(sampleDay)) sinceWhat = sinceWhen.sinceWhen( city, self.field.index, recordDate = recordValue[1] if recordValue is not None else None) if self.field == daily.MAX_TEMP: recordDescription = 'warmest' if v > 24: recordDescription = 'hottest' if maxRecord is False: recordDescription = 'coldest' tweet = ( 'With a high of just {value:.1f}{deg}, {day} {cityName}' ' {record} {filter}day {since}.' ) else: tweet = ( 'With a high of {value:.1f}{deg}, {day} {cityName}' ' {record} {filter}day {since}.' ) if hour != None: tweet = ( 'With a {hour} temp of {value:.1f}{deg}, {day}' ' {cityName} {record} {filter}day {since}.' ) elif self.field == daily.MIN_TEMP: recordDescription = 'warmest' if v > 24: recordDescription = 'hottest' tweet = ( 'With a low of {value:.1f}{deg}, {day} {cityName} {record}' ' {filter}day {since}.' ) if maxRecord is False: tweet = ( '{possessiveDayString} temp of {value:.1f}{deg} is the' ' coldest {simpleCityName} has been {since}.' ) if self.limitToThisMonth: tweet = ( '{possessiveDayString} temp of {value:.1f}{deg} is' ' the coldest {simpleCityName} has been during' ' {filter}{since}.' ) recordDescription = 'coldest' if hour != None: recordDescription = None tweet = ( '{possessiveDayString} {hour} temp of {value:.1f}{deg}' ' was {cityName} coldest {since}.' ) if self.limitToThisMonth: tweet = ( '{possessiveDayString} {hour} temp of' ' {value:.1f}{deg} was {cityName} coldest' ' {filter}{since}.' ) elif self.field == daily.MAX_HUMIDEX: recordDescription = 'muggiest' tweet = 'With a humidex of {value:.1f}, {day} {cityName} {record} {filter}day {since}.' if hour != None: tweet = 'With a {hour} humidex of {value:.1f}, {day} {cityName} {record} {filter}day {since}.' elif self.field == daily.MIN_WINDCHILL: assert(hour is not None) recordDescription = 'windchilliest' #tweet = 'With a windchill of {value:.1f}, {day} {cityName} {record} {filter}day {since}.' #if hour != None: tweet = 'With a {hour} windchill of {value:.1f}, {day} {cityName} {record} {filter}day {since}.' elif self.field == daily.TOTAL_RAIN_MM: recordDescription = 'wettest' tweet = 'With {value:.1f}mm of rain, {day} {cityName} {record} {filter}day {since}.' elif self.field == daily.TOTAL_SNOW_CM: recordDescription = 'snowiest' tweet = ( 'With {value:.1f}cm of snow, {day} {cityName}' ' {record} {filter}day {since}.' ) if hour != None: tweet = ( 'With a {hour} snow total of {value:.0f}cm, {day} {cityName}' ' {record} {filter}day {since}.' ) media = metarSnowChart.main( city, sampleDay, recently=True, thisDayInHistory=False, thisMonthInHistory=False, days=1, field=daily.TOTAL_SNOW_CM) elif self.field == daily.SNOW_ON_GRND_CM: recordDescription = 'deepest' tweet = ( 'With {value}cm of snow-on-the-ground, {day} {cityName}' ' {record} {filter}day {since}.' ) media = recordSinceChart.main( city, sampleDay, recently=True, thisDayInHistory=False, field=daily.SNOW_ON_GRND_CM) elif self.field == daily.SPD_OF_MAX_GUST_KPH: recordDescription = 'windiest' tweet = ( 'With a wind gust of {value:.1f}km/h, {day} {cityName}' ' {record} {filter}day {since}.' ) elif self.field == daily.AVG_WIND: recordDescription = 'windiest' if maxRecord is False: recordDescription = 'calmest' tweet = 'With an avg wind of {value:.0f}km/h, {day} {cityName} {record} {filter}day {since}.' elif self.field == daily.MIN_HUMIDITY: assert(hour is not None) recordDescription = 'moistest' if maxRecord is False: recordDescription = 'driest' if hour != None: tweet = 'With a {hour} humidity of {value:.0f}%, {day} {cityName} {record} {filter}day {since}.' else: tweet = 'With a min humidity of {value:.0f}%, {day} {cityName} {record} {filter}day {since}.' elif self.field == daily.MEAN_HUMIDITY: recordDescription = 'moistest' if maxRecord is False: recordDescription = 'driest' tweet = 'With a humidity of {value:.1f}%, {day} {cityName} {record} {filter}day {since}.' hourText = clock12(city, hour) tweet = tweet.format(value=v, deg=chr(0x2103), hour=hourText, day=dayString, possessiveDayString=possessiveDayString, cityName='#'+possessive(stations.city[city].name), simpleCityName='#'+stations.city[city].name, record=recordDescription, since=sinceWhat, filter=['',monthName(sampleDay.month, long=True)+' '][self.limitToThisMonth]) (use, tweet) = shouldTweetSuffix( city, tweet, oldText=alreadyReportedRecordTweet) if use is True: delayedTweets.addToEndOfListForCity(city, tweet, media) if city == 'ottawa': sendMail.sendMailConsole("*****@*****.**", self.address, subject = self.title, text = tweet, auto = True) self.datemarker[datemarker] = PreviousReport(v, tweet)
def maybeTweetRecordSince( self, city, v, recordValue, alreadyReportedRecord, dayCount, sampleDay, datemarker): limit=365 #days #print (sampleDay, float(v), self.field.name, repr(recordValue)) if recordValue != None: ageOfRecord = (today(city) - recordValue[1]).days if recordValue == None or ageOfRecord > limit: alreadyReportedRecordTweet = None if alreadyReportedRecord != None: alreadyReportedRecordTweet = alreadyReportedRecord.tweet #print("\n--------------------------------------------------------------------------------\nCorrecting a previous record of {:.1f}".format(alreadyReportedRecord.value)) #print("OldTweet: ", alreadyReportedRecord.tweet) if dayCount == 1: dayString = '{} was'.format( dayStr(city, sampleDay)) else: dayString = '{}-{} were'.format( dayStr(city, sampleDay-datetime.timedelta(days=dayCount-1)), dayStr(city, sampleDay)) sinceWhat = sinceWhen.sinceWhen( city, self.field.index, recordDate = recordValue[1] if recordValue is not None else None) if self.field == daily.MAX_TEMP: recordDescription = 'warmest' if v > 24: recordDescription = 'hottest' if maxRecord is False: recordDescription = 'coldest' tweet = 'With a high of just {value:.1f}{deg}, {day} {cityName} {record} day {since}.' else: tweet = 'With a high of {value:.1f}{deg}, {day} {cityName} {record} day {since}.' if hour != None: tweet = 'With a {hour} temp of {value:.1f}{deg}, {day} {cityName} {record} day {since}.' elif self.field == daily.MIN_TEMP: recordDescription = 'warmest' if v > 24: recordDescription = 'hottest' tweet = 'With a low of {value:.1f}{deg}, {day} {cityName} {record} day {since}.' if maxRecord is False: recordDescription = 'coldest' if hour != None: tweet = 'With a {hour} temp of {value:.1f}{deg}, {day} {cityName} {record} day {since}.' elif self.field == daily.MAX_HUMIDEX: recordDescription = 'muggiest' tweet = 'With a humidex of {value:.1f}, {day} {cityName} {record} day {since}.' if hour != None: tweet = 'With a {hour} humidex of {value:.1f}, {day} {cityName} {record} day {since}.' elif self.field == daily.MIN_WINDCHILL: assert(hour is not None) recordDescription = 'windchilliest' #tweet = 'With a windchill of {value:.1f}, {day} {cityName} {record} day {since}.' #if hour != None: tweet = 'With a {hour} windchill of {value:.1f}, {day} {cityName} {record} day {since}.' elif self.field == daily.TOTAL_RAIN_MM: recordDescription = 'wettest' tweet = 'With {dayCount}-day rainfall of {value:.1f}mm, {day} {cityName} {record} {dayCount} days {since}.' elif self.field == daily.TOTAL_SNOW_CM: recordDescription = 'snowiest' tweet = 'With {dayCount}-day snowfall of {value:.1f}cm, {day} {cityName} {record} {dayCount} days {since}.' elif self.field == daily.SNOW_ON_GRND_CM: recordDescription = 'snowiest' tweet = 'With {value:.1f}cm of snow-on-the-ground, {day} {cityName} {record} day {since}.' elif self.field == daily.SPD_OF_MAX_GUST_KPH: recordDescription = 'windiest' tweet = 'With a wind gust of {value:.1f}km/h, {day} {cityName} {record} day {since}.' elif self.field == daily.AVG_WIND: recordDescription = 'windiest' tweet = 'With a {dayCount}-day wind of {value:.1f}km/h, {day} {cityName} {record} {dayCount} days {since}.' elif self.field == daily.MIN_HUMIDITY: assert(hour is not None) recordDescription = 'moistest' if maxRecord is False: recordDescription = 'driest' if hour != None: tweet = 'With a {hour} humidity of {value:.0f}%, {day} {cityName} {record} day {since}.' else: tweet = 'With a min humidity of {value:.0f}%, {day} {cityName} {record} day {since}.' elif self.field == daily.MEAN_HUMIDITY: recordDescription = 'moistest' #if maxRecord is False: # recordDescription = 'driest' tweet = 'With a {dayCount}-day humidity of {value:.1f}%, {day} {cityName} {record} {dayCount} days {since}.' tweet = tweet.format(value=float(v), deg=chr(0x2103), day=dayString, cityName='#'+possessive(stations.city[city].name), record=recordDescription, since=sinceWhat, dayCount=dayCount) (use, tweet) = shouldTweetSuffix( city, tweet, oldText=alreadyReportedRecordTweet) if use is True: delayedTweets.addToEndOfListForCity(city, tweet) if city == 'ottawa': sendMail.sendMailConsole("*****@*****.**", self.address, subject = self.title, text = tweet, auto = True) self.datemarker[datemarker] = PreviousReport(round(float(v),1), tweet)