def test_clean_cache(self): instance = LRUCache(3, 1000 * 60 * 60) # max 3 items instance.set("1", "aaa") instance.set("2", "bbb") instance.set("3", "ccc") self.assertEqual(3, instance.size()) instance.clean() self.assertEqual(0, instance.size())
def test_cache_max_size_preserved_when_setting(self): instance = LRUCache(3, 1000 * 60 * 60) # max 3 items instance.set("1", "aaa") instance.set("2", "bbb") instance.set("3", "ccc") cache_size = instance.size() instance.set("4", "ddd") self.assertEqual(cache_size, instance.size())
def weather(): #weather duh API_key cache = LRUCache() owm = OWM(API_key) obs = owm.weather_at_id(6183235) w = obs.get_weather() sky = w.get_detailed_status() temp = w.get_temperature(unit='celsius') tempnow = temp['temp'] tempnow1 = str(tempnow) tempnow1.split('.') tempnow2 = int(tempnow1[0:2]) speak('It\'s ' + str(tempnow2) + ' degrees with ' + sky) speak('Would you like to know more.') while 1: data = recordAudio() data data = data.split(' ') if 'yes' in data: hi = w.get_temperature(str(temp['temp_max']), unit='celsius') lo = w.get_temperature(str(temp['temp_min']), unit='celsius') if int(now.strftime('%H')) < 13: speak('Today will reach a high of ' + str(hi) + ' with ' + w.get_clouds()) else: speak('Tonight will reach a low of ' + str(lo) + ' with ' + w.get_clouds()) else: speak('Moving on then.') break
def test_insert_already_cached_item(self): instance = LRUCache(3, 1000 * 60 * 60) # max 3 items instance.set("1", "aaa") instance.set("2", "bbb") self.assertEqual(2, instance.size()) most_recent_cache_item = instance._usage_recency._first_node instance.set("1", "aaa") self.assertEqual(2, instance.size()) result = instance._usage_recency._first_node self.assertNotEqual(most_recent_cache_item, result)
def test_miss_getting_old_items(self): instance = LRUCache(3, 1) # 1 millisecond lifetime for cache items instance.set(self.__test_url, self.__test_data) cache_size = instance.size() sleep(2) # wait 2 seconds result = instance.get(self.__test_url) self.assertFalse(result) self.assertEqual(cache_size - 1, instance.size())
def test_set_cache_item(self): instance = LRUCache(3, 1000 * 60 * 60) # 1 hour lifetime for items cache_size = instance.size() ref_to_original_set = LRUCache.set instance.set(self.__test_url, self.__test_data) LRUCache.set = ref_to_original_set self.assertEqual(cache_size + 1, instance.size()) result = instance.get(self.__test_url) self.assertEqual(self.__test_data, result)
def get_our_weather(coordinates=None, cityname=None, id=None): API_key = 'afb077071af62fa3b00cb43e3eccbaf1' owm = pyowm.OWM(API_key=API_key) # Cache provider to be used cache = LRUCache() obs = None ans = None if coordinates: obs = owm.weather_at_coords(coordinates[0], coordinates[1]) if cityname: obs = owm.weather_at_place(cityname) weather = obs.get_weather() return weather
def test_cache_limits(self): """ Test that when cache is full, cached elements undergo a turnover and the real OWM web API is invoked """ cache = LRUCache(3, 1000 * 60 * 60) # Only three cacheable elements! wrapped_cache = CacheWrapper(cache) owm = OWM25(parsers, '5746e1a976021a0', wrapped_cache) owm.weather_at_place('London,uk') # Comes from OWM web API owm.weather_at_place('Kiev') # Comes from OWM web API owm.weather_at_place('Madrid') # Comes from OWM web API self.assertEqual(3, wrapped_cache.api_calls()) owm.weather_at_place('London,uk') # Comes from cache owm.weather_at_place('Kiev') # Comes from cache self.assertEqual(3, wrapped_cache.api_calls()) owm.weather_at_place('Tokyo') self.assertEqual(4, wrapped_cache.api_calls()) owm.weather_at_place('Madrid') # Now Madrid should have been pulled out of cache self.assertEqual(5, wrapped_cache.api_calls())
def test_caching_times(self): """ Test that subsequent calls to the same endpoint and with the same query parameters are cached if OWM instance is configured with a non-null cache. """ cache = LRUCache(20, 1000 * 60 * 60) owm = OWM25(parsers, API_key=self.API_KEY, cache=cache) before_request = time() o1 = owm.weather_at_place('London,GB') # Comes from OWM Weather API after_request = time() o2 = owm.weather_at_place('London,GB') # Comes from cache after_cache_hit_1 = time() owm.weather_at_place('Kiev') # Comes from OWM Weather API owm.weather_at_coords(-33.936524, 18.503723) # Comes from OWM Weather API owm.weather_at_coords(-33.936524, 18.503723) # Cached, we don't care owm.weather_at_coords(-33.936524, 18.503723) # Cached, we don't care before_cache_hit_2 = time() o3 = owm.weather_at_place('London,GB') # Comes from cache after_cache_hit_2 = time() #Check results: difference in reception time should not be less than 20 sec self.assertAlmostEqual(o1.get_reception_time(), o2.get_reception_time(), places=None, msg=None, delta=20) self.assertAlmostEqual(o1.get_reception_time(), o3.get_reception_time(), places=None, msg=None, delta=20) #Check times: all cache hit times must be less than the former OWM web #API request time and ratio between cache hit times and request time #should be far less than 1 req_delay = after_request - before_request cache_hit_1_delay = after_cache_hit_1 - after_request cache_hit_2_delay = after_cache_hit_2 - before_cache_hit_2 self.assertTrue(cache_hit_1_delay < req_delay) self.assertTrue(cache_hit_2_delay < req_delay) self.assertTrue(cache_hit_1_delay / req_delay < 1) self.assertTrue(cache_hit_2_delay / req_delay < 1)
def test_caching_prevents_API_calls(self): cache = LRUCache(20, 1000 * 60 * 60) wrapped_cache = CacheWrapper(cache) owm = OWM25(parsers, '5746e1a976021a0', wrapped_cache) self.assertFalse(wrapped_cache.last_request_was_hit()) self.assertEqual(0, wrapped_cache.api_calls()) owm.weather_at_place('London,uk') # Comes from OWM web API self.assertFalse(wrapped_cache.last_request_was_hit()) self.assertEqual(1, wrapped_cache.api_calls()) owm.weather_at_place('London,uk') # Comes from cache self.assertTrue(wrapped_cache.last_request_was_hit()) self.assertEqual(1, wrapped_cache.api_calls()) owm.weather_at_place('London,uk') # Comes from cache again self.assertTrue(wrapped_cache.last_request_was_hit()) self.assertEqual(1, wrapped_cache.api_calls()) owm.weather_at_place('Kiev') # Comes from OWM web API self.assertFalse(wrapped_cache.last_request_was_hit()) self.assertEqual(2, wrapped_cache.api_calls()) owm.weather_at_place('Kiev') # Comes from cache self.assertTrue(wrapped_cache.last_request_was_hit()) self.assertEqual(2, wrapped_cache.api_calls()) owm.weather_at_place('London,uk') # Comes from cache self.assertTrue(wrapped_cache.last_request_was_hit()) self.assertEqual(2, wrapped_cache.api_calls())
def __reply(self, commandInfo: Union[dict, list], *, backup: Optional[dict], dataFromCache: bool) -> (str, dict): """ Generates a reply to the user's query. A dictionary of content or a list of content dictionaries can be passed in. """ # Each type of command is assigned an ID number. For details about what each number # means, see `../doc/command-ids.md`. commandID = int() # The index numbers of the usable template replies for each ID number. For example ID 1 can # use `TEMPLATES[2]`, `TEMPLATES[3]`, and `TEMPLATES[5]` to talk about the weather, so 2, 3, # and 5 are appended to the list. usable_replies = list() response: Optional[str] = None # Responses for Quinton if it can't do something or doesn't # understand the command. UNKNOWN = [ "I'm sorry, I don't understand", "I'm not sure I understand" ] if commandInfo is None: # Pick an "unknown" response try: if sys.version_info.minor > 8: random.seed() else: random.seed( datetime.now(tz=pytz.timezone(self.cfg.timezone))) except pytz.exceptions.UnknownTimeZoneError: raise TimezoneError return (random.choice(UNKNOWN), commandInfo) # Based on the type of data that is passed into the function, set it to its respective variable # to keep the naming neat ("l" denotes `list`, "d" denotes `dict`). For lists passed in, a sample # content dictionary is taken to determine what intent to reply to. In the case of a dictionary, this # variable will just be a copy of `commandInfo` (passed in data parameter). lCommandInfo = list() dCommandInfo = infoSample = dict() if type(commandInfo) is list: lCommandInfo = commandInfo else: dCommandInfo = commandInfo infoSample = commandInfo[0] if type( commandInfo) is list else commandInfo usingCache = False # Set to `True` if the cache is used filteredData = None try: timezone = pytz.timezone(self.cfg.timezone) # Get the timezone except pytz.exceptions.UnknownTimeZoneError: raise TimezoneError if infoSample.get("intent") == "command": if ((("tell" in infoSample.get("keywords") or ("get" in infoSample.get("keywords"))) and ("weather" in infoSample.get("keywords"))) or ("weather" == infoSample.get("keywords"))): # Weather if not self.perms.canUseLocation: raise LocationError # Get information from OpenWeatherMap owm = pyowm.OWM(self.OWM_KEY) cache = LRUCache() reg = owm.city_id_registry() idlist = reg.ids_for(city_name=self.cfg.city, country=self.cfg.country) obs = owm.weather_at_ids([idlist[0][0]]) weather = obs[0].get_weather() # Create the reply if (self.cfg.units == "imperial") or (self.cfg.units == "metric"): unit = "fahrenheit" if self.cfg.units == "imperial" else "celsius" else: unit = "fahrenheit" temp = str( round(weather.get_temperature(unit=unit).get("temp"))) response = f"{temp} degrees {unit.capitalize()} with {weather.get_detailed_status()}" if dataFromCache: content = lCommandInfo if type( commandInfo ) is list else dCommandInfo # The content to be filtered search = response filteredData = self.cmdPsr.filterIrrelevant( content, search) if filteredData is not None: usingCache = True if not usingCache: commandID = 1 elif ((("tell" in infoSample.get("keywords") or ("get" in infoSample.get("keywords"))) and ("time" in infoSample.get("keywords"))) and (infoSample.get("subject") == "user")): # Telling time # Get the current time time = datetime.now(pytz.timezone(timezone.zone)) if dataFromCache: content = lCommandInfo if type( commandInfo ) is list else dCommandInfo # The content to be filtered # When searching for a time, make sure to remove the leading zero from hours before 10 (A.M. or P.M.) # # TIME EDITING (Using 5:00 PM for the time) # time.strftime("%I %M %p") -> 05 00 PM # time.strftime("%I %M %p")[1:] -> 5 00 PM # time.strftime("%I %M %p")[:1] -> 05 orig_time = time.strftime("%I %M %p")[1:] if int( time.strftime("%I %M %p")[:2]) < 10 else time.strftime( "%I %M %p") search = self.__normalizeTime(orig_time) filteredData = self.cmdPsr.filterIrrelevant( content, search) if filteredData is not None: usingCache = True # If the cache isn't being used or no suitable content dictionaries are found, # a reply is generated. if not usingCache: commandID = 2 orig_time = time.strftime("%I %M %p")[1:] if int( time.strftime("%I %M %p")[:2]) < 10 else time.strftime( "%I %M %p") response = self.__normalizeTime(orig_time) elif (("tell" in infoSample.get("keywords") or ("get" in infoSample.get("keywords"))) and ("date" in infoSample.get("keywords"))): commandID = 3 # Get the current date time = datetime.now(pytz.timezone(timezone.zone)) dt = datetime.strptime((str(time.day) + "/" + str(time.month) + "/" + str(time.year)), "%d/%m/%Y") fmt = "%A, %B %d" response = dt.strftime(fmt) elif (("turn on" in infoSample.get("keywords")) and (infoSample.get("assets") is not None)): # Turn something on commandID = 4 response = None elif ( ("turn off" in infoSample.get("keywords")) and (infoSample.get("assets") is not None)): # Turn something off commandID = 4 response = None else: pass elif infoSample.get("intent") == "inquire": if (("what" in infoSample.get("question_words")) and ("weather" in infoSample.get("keywords"))): # Weather if not self.perms.canUseLocation: raise LocationError # Get information from OpenWeatherMap owm = pyowm.OWM(self.OWM_KEY) cache = LRUCache() reg = owm.city_id_registry() idlist = reg.ids_for(city_name=self.cfg.city, country=self.cfg.country) obs = owm.weather_at_ids([idlist[0][0]]) weather = obs[0].get_weather() # Create the reply if (self.cfg.units == "imperial") or (self.cfg.units == "metric"): unit = "fahrenheit" if self.cfg.units == "imperial" else "celsius" else: unit = "fahrenheit" temp = str( round(weather.get_temperature(unit=unit).get("temp"))) response = f"{temp} degrees {unit.capitalize()} with {weather.get_detailed_status()}" if dataFromCache: content = lCommandInfo if type( commandInfo ) is list else dCommandInfo # The content to be filtered search = response filteredData = self.cmdPsr.filterIrrelevant( content, search) if filteredData is not None: usingCache = True if not usingCache: commandID = 1 elif ((("what" in infoSample.get("question_words")) and ("time" in infoSample.get("keywords"))) and ("is it" in infoSample.get("command"))): # Telling time # Get the current time time = datetime.now(pytz.timezone(timezone.zone)) if dataFromCache: content = lCommandInfo if type( commandInfo ) is list else dCommandInfo # The content to be filtered # When searching for a time, make sure to remove the leading zero from hours before 10 (A.M. or P.M.) # # TIME EDITING (Using 5:00 PM for the time) # time.strftime("%I %M %p") -> 05 00 PM # time.strftime("%I %M %p")[1:] -> 5 00 PM # time.strftime("%I %M %p")[:1] -> 05 orig_time = time.strftime("%I %M %p")[1:] if int( time.strftime("%I %M %p")[:2]) < 10 else time.strftime( "%I %M %p") search = self.__normalizeTime(orig_time) filteredData = self.cmdPsr.filterIrrelevant( content, search) if filteredData is not None: usingCache = True # If the cache isn't being used or no suitable content dictionaries are found, # a reply is generated. if not usingCache: commandID = 2 orig_time = time.strftime("%I %M %p")[1:] if int( time.strftime("%I %M %p")[:2]) < 10 else time.strftime( "%I %M %p") response = self.__normalizeTime(orig_time) elif (("what" in infoSample.get("question_words")) and (("is" in infoSample.get("to_be")) or ("what's" in ci.egt("full_command"))) and ("date" in infoSample.get("keywords"))): # Getting the date commandID = 3 # Get the current date time = datetime.now(pytz.timezone(timezone.zone)) dt = datetime.strptime((str(time.day) + "/" + str(time.month) + "/" + str(time.year)), "%d/%m/%Y") fmt = "%A, %B %d" response = dt.strftime(fmt) else: pass elif infoSample.get("intent") == "state": if infoSample.get("subject") == "user": if "favorite" in infoSample.get("keywords"): if dataFromCache: usingCache = True else: usingCache = False if not usingCache: objtype = objname = str() foundStart = foundEnd = False stopWords = infoSample.get("to_be") if infoSample.get( "to_be") is not None else infoSample.get( "articles") # Filter out parts of the command to look for a situation where the user tells # Quinton something about themself. for word in infoSample.get("command").split(): if (not word in stopWords) and (not foundEnd): if word == "favorite": foundStart = True continue elif foundStart: objtype += word else: if not foundEnd: foundEnd = True if (not word in infoSample.get("articles") ) and (not word in infoSample.get("to_be")): objname += word objtype = objtype.strip() # Get rid of plural nouns if objtype.endswith("s") or objtype.endswith("es"): objtype.rstrip( "es") # Will take care of both cases if not foundEnd: # Not really necessary, as commandID is 0 by default commandID = 0 else: infoSample.get("references").update( {objtype: objname}) commandID = 5 else: pass if type(response) is str: response = response.strip() if (response is None) and (commandID != 5): raise NoReplyError # Use the backup content dictionary if all of the ones from the cache have # been filtered out. usingBackup = False if not usingCache: # Backup data is not sent from the command processor if the cache is not # used at the processing level. if dataFromCache: dCommandInfo = backup usingBackup = True else: commandInfo = filteredData if commandInfo is filteredData is lCommandInfo is dCommandInfo is backup is None: raise DataError # Each of these responses will be updated with the generated reply TEMPLATES = [ f"ok, {response}", f"good {response}", f"It is {response}", f"It is currently {response}", f"Today is {response}", f"In {self.cfg.city}, it is currently {response}", "Got it", f"It's {response}", "Okay, I'll remember that" ] UNABLE = [ f"I'm sorry, {self.cfg.username}, I'm afraid I can't do that", "I'm unable to do that" ] if commandID == 0: pass elif commandID == 1: usable_replies = [2, 3, 5] elif commandID == 2: usable_replies = [2, 3, 7] elif commandID == 3: usable_replies = [4] elif commandID == 4: usable_replies = [0] elif commandID == 5: usable_replies = [6, 8] # Make sure all timestamps are up to date try: if (self.perms.canTimestampHist) and ("timestamp" in ( infoSample if type(commandInfo) is list else commandInfo)): time = self.__generateTimestamp() if type(commandInfo) is list: for cdict in commandInfo: cdict.update({"timestamp": time}) else: if (commandInfo.get("timestamp") == str()) or ( commandInfo.get("timestamp") != time): commandInfo.update({"timestamp": time}) except TypeError: raise TimestampError if (response is None) and (usable_replies == list()): if sys.version_info.minor > 8: random.seed() else: random.seed(datetime.now(tz=timezone)) dCommandInfo.update({"reply": random.choice(UNABLE)}) return (dCommandInfo.get("reply"), dCommandInfo) else: # If there are multiple replies for the query's command ID, pick a random one. # Otherwise, just use the one that's there. This way, `random.choice()` # doesn't waste time picking from only one reply template. if ((dCommandInfo == commandInfo) or (usingBackup)) and (not usingCache): if sys.version_info.minor > 8: random.seed() else: random.seed(datetime.now(tz=timezone)) if len(usable_replies) > 1: dCommandInfo.update({ "reply": TEMPLATES.copy()[random.choice(usable_replies)] }) else: dCommandInfo.update( {"reply": TEMPLATES.copy()[usable_replies[0]]}) return (dCommandInfo.get("reply"), dCommandInfo ) # Return for a single content dictionary elif (lCommandInfo == commandInfo) and (not usingCache): if sys.version_info.minor > 8: random.seed() else: random.seed(datetime.now(tz=timezone)) # Pick a content dictionary to use. At this point, they all have the same intent and response, # so one is picked and given a full sentence reply. contDict = random.choice(lCommandInfo) if len(usable_replies) > 1: contDict.update({ "reply": TEMPLATES.copy()[random.choice(usable_replies)] }) else: contDict.update( {"reply": TEMPLATES.copy()[usable_replies[0]]}) return (contDict.get("reply"), contDict ) # Return statement for many content dictionaries else: # Return data from the cache if type(filteredData) == dict: filteredData.update({"from_cache": True}) return (filteredData.get("reply"), filteredData) elif type(filteredData) == list: if sys.version_info.minor > 8: random.seed() else: random.seed(datetime.now(tz=timezone)) # Update the randomly chosen content dictionary to say that the data is from the cache, # and update the timestamp if applicable contDict = random.choice(filteredData) contDict.update({"from_cache": True}) return (contDict.get("reply"), contDict)
from pyowm.caches.lrucache import LRUCache import datetime import math import subprocess from statistics import mean import sys import spotipy import spotipy.util as util import pandas as pd import numpy as np sp = spotipy.Spotify() API_key = '6ff7fde73bb9cccf854fd26d31b4fe6d' owm = OWM(API_key) cache = LRUCache() GLOBALMusicDataframe = pd.DataFrame() GLOBALCurrentSongList = pd.DataFrame() ######################################################################################################################################## userURL = "" userID = "" playListID = "" placeWeather="" def SaveIDs(user, playlist, place): global userID, playListID, placeWeather userID = user
def test_hit_when_getting_freshly_inserted_items(self): instance = LRUCache(3, 1000 * 60 * 60) # 1 hour lifetime for items instance.set(self.__test_url, self.__test_data) result = instance.get(self.__test_url) self.assertEqual(self.__test_data, result)
""" Algumas pequenas mudanças na configuração """ from pyowm.caches.lrucache import LRUCache from pyowm.weatherapi25.weathercoderegistry import WeatherCodeRegistry from pyowm.weatherapi25.configuration25 import * # uso de um cache LRU simples pra tentar reduzir os requests no OWM cache = LRUCache(cache_max_size=50) # tradução para português language = 'pt'