1

I've written code below to retrieve the current temperature from openweathermap , when the connection fails it should return the previous temperature.

Everything is working but i would like to avoid using the global variable last_temperature to save the previous retrieved temperature , how can I do this?

import time    
from pyowm import OWM

API_key="**********************************"
owm=OWM(API_key)
last_temperature= 15.0

def getcurrentTemperature(city_id): # Gent is 2797656
    global last_temperature 
    try:
        obs = owm.weather_at_id(city_id) #by ID
        w = obs.get_weather()
        temps=w.get_temperature(unit='celsius')
        last_temperature = round(temps['temp'],1)
        return last_temperature
    except:
        return last_temperature

while 1 :
    print getcurrentTemperature(2797656)
    time.sleep(30)
tubos
  • 69
  • 2
  • 9

4 Answers4

1

You have several design options:

  • You could use a static_var as described here: What is the Python equivalent of static variables inside a function?
  • You could implement a class with last_temperature as class member. The using code would then have the responsibility to create and hold the class instance.
  • Or the option described by user2233706 (providing last_temperature as function argument to getcurrentTemperature)

I'd avoid the global variable and also the static_var approach, as they both correspond to static state. For example, when creating unit-tests you would always have to keep this state set up and cleaned to avoid cross-dependencies between tests.

Community
  • 1
  • 1
Dirk Herrmann
  • 5,550
  • 1
  • 21
  • 47
0

As user2233706 says, you can simply pass last_temperature as an argument to getcurrentTemperature().

You can also skip returning the temperature in try and except and instead calculate it and then return it in finally.

import time    
from pyowm import OWM

API_key="**********************************"
owm=OWM(API_key)
last_temperature = 15.0

def getcurrentTemperature(city_id, last_temperature): # Gent is 2797656
    try:
        # If it works it will set the temperature
        obs = owm.weather_at_id(city_id) # by ID
        w = obs.get_weather()
        temps=w.get_temperature(unit='celsius')
        temperature = round(temps['temp'],1)
    except:
        # If it doesn't then simply set the return value to the current temperature
        temperature = last_temperature
    finally:
        # You don't need to include the return in both places - this will be run either way
        return temperature

while 1 :
    current_temperature = getcurrentTemperature(2797656, last_temperature) # Get the current temp
    print current_temperature
    last_temperature = current_temperature # Now set the last temperature to the current one and repeat
    time.sleep(30)

Let me know if this is confusing or unclear.

ASCIIThenANSI
  • 865
  • 1
  • 9
  • 27
0

I assume you are using it in other parts of your code otherwise it wouldn't make a lot of sense.

For me the most logical way would be to create a class like this:

class TemperatureData:
    def __init__(self, *args, **kwargs):
        self.temperature = 15.0

    def update(self, city_id):
        try:
            temperature = own.weather_at_id(city_id).get_weather().get_temperature(unit='celsius')
            self.temperature = round(temperature['temp'], 1)
        except:
            # please catch only the necessary exceptions, not all of them at once, otherwise you might jsut miss important issues on your code 
            pass

def get_temperature(self):
    return self.temperature

Then you can create a TemperatureData object (or several, which is nice), and update them. You even have a get_temperature function that you can customize for example to encode the temperature, or put it in Kelvin.

Mijamo
  • 3,436
  • 1
  • 21
  • 21
0

As I mentioned in the comment, you could make last_temperature an attribute of your function and return that.

def getcurrentTemperature(city_id):
    try:
        # try to compute last_temperature
        getcurrentTemperature.last_temperature = last_temperature
    except SomeException: # you should be more specific here!
        pass

    return getcurrentTemperature.last_temperature

getcurrentTemperature.last_temperature = None

Demo with a silly function:

>>> def foo(number):
...     try:
...         foo.last_result = int(number)
...     except ValueError:
...         pass
...     return foo.last_result
... 
>>> foo.last_result = None
>>> 
>>> foo(10)
10
>>> foo(23.5)
23
>>> foo('hi')
23
>>> foo('test')
23
>>> foo(11.11)
11
timgeb
  • 76,762
  • 20
  • 123
  • 145