diff --git a/python_weather/base.py b/python_weather/base.py index e5d2d75..6804646 100644 --- a/python_weather/base.py +++ b/python_weather/base.py @@ -25,7 +25,7 @@ from enum import auto, Enum from .enums import WindDirection, Kind, Locale, Ultraviolet -from .constants import METRIC, VALID_UNITS +from .constants import _Unit class CustomizableBase: __slots__ = ('__unit', '__locale') @@ -56,7 +56,7 @@ def unit(self, to: auto): If the ``to`` argument is not either :attr:`METRIC` or :attr:`IMPERIAL`. """ - if to not in VALID_UNITS: + if not isinstance(to, _Unit): raise Error('Invalid measuring unit specified!') self.__unit = to @@ -107,8 +107,7 @@ def feels_like(self) -> int: """:class:`int`: What it felt like, in Celcius or Fahrenheit.""" return int( - self.__inner[ - f'FeelsLike{"C" if self._CustomizableBase__unit == METRIC else "F"}'] + self.__inner[f'FeelsLike{self._CustomizableBase__unit.temperature}'] ) @property @@ -121,18 +120,14 @@ def humidity(self) -> int: def temperature(self) -> int: """:class:`int`: The weather temperature in either Celcius or Fahrenheit.""" - return int( - self. - __inner[f'temp_{"C" if self._CustomizableBase__unit == METRIC else "F"}'] - ) + return int(self.__inner[f'temp_{self._CustomizableBase__unit.temperature}']) @property def precipitation(self) -> float: """:class:`float`: The precipitation in either Millimeters or Inches.""" return float( - self.__inner[ - f'precip{"MM" if self._CustomizableBase__unit == METRIC else "Inches"}'] + self.__inner[f'precip{self._CustomizableBase__unit.precipitation}'] ) @property @@ -140,8 +135,7 @@ def pressure(self) -> float: """:class:`float`: The pressure in either Pascal or Inches.""" return float( - self.__inner[ - f'pressure{"" if self._CustomizableBase__unit == METRIC else "Inches"}'] + self.__inner[f'pressure{self._CustomizableBase__unit.pressure}'] ) @property @@ -149,9 +143,7 @@ def visibility(self) -> int: """:class:`int`: The visibility distance in either Kilometers or Miles.""" return int( - self.__inner[ - f'visibility{"" if self._CustomizableBase__unit == METRIC else "Miles"}' - ] + self.__inner[f'visibility{self._CustomizableBase__unit.visibility}'] ) @property @@ -159,9 +151,7 @@ def wind_speed(self) -> int: """:class:`int`: The wind speeds in either Kilometers per hour or Miles per hour.""" return int( - self.__inner[ - f'windspeed{"Kmph" if self._CustomizableBase__unit == METRIC else "Miles"}' - ] + self.__inner[f'windspeed{self._CustomizableBase__unit.velocity}'] ) @property diff --git a/python_weather/client.py b/python_weather/client.py index d2be0c4..0f47f74 100644 --- a/python_weather/client.py +++ b/python_weather/client.py @@ -28,7 +28,7 @@ from asyncio import sleep from enum import auto -from .constants import METRIC, VALID_UNITS +from .constants import _Unit, METRIC from .base import CustomizableBase from .forecast import Weather from .errors import Error @@ -115,7 +115,7 @@ async def get( elif self.__session.closed: raise Error('Client is already closed') - if unit not in VALID_UNITS: + if not isinstance(unit, _Unit): unit = self._CustomizableBase__unit if not isinstance(locale, Locale): diff --git a/python_weather/constants.py b/python_weather/constants.py index fa54e37..8a7b7cb 100644 --- a/python_weather/constants.py +++ b/python_weather/constants.py @@ -22,11 +22,36 @@ SOFTWARE. """ +from typing import Union from re import compile from enum import auto -METRIC = auto() -IMPERIAL = auto() +class _Unit: + __slots__ = ( + 'temperature', 'velocity', 'pressure', 'precipitation', 'visibility', + 'cm_divisor' + ) + + def __init__( + self, + temperature: str, + velocity: str, + pressure: str, + precipitation: str, + visibility: str, + cm_divisor: Union[int, float], + ): + self.temperature = temperature + self.velocity = velocity + self.pressure = pressure + self.precipitation = precipitation + self.visibility = visibility + self.cm_divisor = cm_divisor + + def __repr__(self) -> str: + return f'' + +METRIC = _Unit('C', 'Kmph', '', 'MM', '', 1) +IMPERIAL = _Unit('F', 'Miles', 'Inches', 'Inches', 'Miles', 2.54) LATLON_REGEX = compile(r'^Lat (\-?[\d\.]+) and Lon (\-?[\d\.]+)$') -VALID_UNITS = (METRIC, IMPERIAL) \ No newline at end of file diff --git a/python_weather/forecast.py b/python_weather/forecast.py index 11e1c69..cb795b0 100644 --- a/python_weather/forecast.py +++ b/python_weather/forecast.py @@ -26,9 +26,9 @@ from datetime import datetime, date, time from enum import auto -from .enums import Phase, Locale -from .constants import LATLON_REGEX, METRIC from .base import BaseForecast, CustomizableBase +from .constants import LATLON_REGEX +from .enums import Phase, Locale class Area: """Represents the location of the weather forecast.""" @@ -182,7 +182,7 @@ def dew_point(self) -> int: """:class:`int`: The dew point in either Celcius or Fahrenheit.""" return int( - self._BaseForecast__inner[f'DewPoint{"C" if self._CustomizableBase__unit == METRIC else "F"}'] + self._BaseForecast__inner[f'DewPoint{self._CustomizableBase__unit.temperature}'] ) # yapf: disable @property @@ -190,7 +190,7 @@ def heat_index(self) -> int: """:class:`int`: The heat index in either Celcius or Fahrenheit.""" return int( - self._BaseForecast__inner[f'HeatIndex{"C" if self._CustomizableBase__unit == METRIC else "F"}'] + self._BaseForecast__inner[f'HeatIndex{self._CustomizableBase__unit.temperature}'] ) # yapf: disable @property @@ -198,14 +198,14 @@ def wind_chill(self) -> int: """:class:`int`: The wind chill value in either Celcius or Fahrenheit.""" return int( - self._BaseForecast__inner[f'WindChill{"C" if self._CustomizableBase__unit == METRIC else "F"}'] + self._BaseForecast__inner[f'WindChill{self._CustomizableBase__unit.temperature}'] ) # yapf: disable @property def wind_gust(self) -> int: """:class:`int`: The wind gust value in either Kilometers per hour or Miles per hour.""" - key = f'WindGust{"Kmph" if self._CustomizableBase__unit == METRIC else "Miles"}' + key = f'WindGust{self._CustomizableBase__unit.velocity}' return int(self._BaseForecast__inner[key]) @property @@ -310,7 +310,7 @@ def lowest_temperature(self) -> int: """:class:`int`: The lowest temperature in either Celcius or Fahrenheit.""" return int( - self.__inner[f'mintemp{"C" if self._CustomizableBase__unit == METRIC else "F"}'] + self.__inner[f'mintemp{self._CustomizableBase__unit.temperature}'] ) # yapf: disable @property @@ -318,7 +318,7 @@ def highest_temperature(self) -> int: """:class:`int`: The highest temperature in either Celcius or Fahrenheit.""" return int( - self.__inner[f'maxtemp{"C" if self._CustomizableBase__unit == METRIC else "F"}'] + self.__inner[f'maxtemp{self._CustomizableBase__unit.temperature}'] ) # yapf: disable @property @@ -326,7 +326,7 @@ def temperature(self) -> int: """:class:`int`: The average temperature in either Celcius or Fahrenheit.""" return int( - self.__inner[f'avgtemp{"C" if self._CustomizableBase__unit == METRIC else "F"}'] + self.__inner[f'avgtemp{self._CustomizableBase__unit.temperature}'] ) # yapf: disable @property @@ -339,8 +339,9 @@ def sunlight(self) -> float: def snowfall(self) -> float: """:class:`float`: Total snowfall in either Centimeters or Inches.""" - width = float(self.__inner['totalSnow_cm']) - return width if self._CustomizableBase__unit == METRIC else width / 2.54 + return float( + self.__inner['totalSnow_cm'] + ) / self._CustomizableBase__unit.cm_divisor @property def hourly(self) -> Iterable[HourlyForecast]: