diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6480e36 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true + +# Matches multiple files with brace expansion notation +# Set default charset +[*.{js,py}] +charset = utf-8 + +# 4 space indentation +[*.py] +indent_style = space +indent_size = 4 + +# 2 space indentation +[*.js] +indent_style = space +indent_size = 2 \ No newline at end of file diff --git a/README.md b/README.md index dedc2e8..e4a1c03 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,12 @@ Here are my Python solutions to the book Exercises for Programmers: 57 Challenges to Develop Your Coding Skills by Brian P. Hogan. +# Setup +virtualenv env -p python3.7 + +source env/bin/activate + +pip install -r requirements.txt # Run tests python -m unittest discover -p "*_test.py" -v \ No newline at end of file diff --git a/grabbing_the_weather/app.py b/grabbing_the_weather/app.py new file mode 100644 index 0000000..ad3cdbf --- /dev/null +++ b/grabbing_the_weather/app.py @@ -0,0 +1,55 @@ +import os +import requests + + +def print_header(): + """ Print header + """ + header_text = '' + TEXT = f' Grabbing the weather \n' + line = '-' * len(TEXT) + line += '\n' + + header_text += line + header_text += TEXT + header_text += line + print(header_text) + +def get_location(): + + while True: + location = input('Where are you? ') + if len(location) > 0: + return location + else: + print('A valid input required.') + + +def get_weather_for_city(city_name): + + api_key = os.environ.get('OPEN_WEATHER_MAP_API_KEY', None) + if not api_key: + print('API KEY NOT FOUND') + print('export OPEN_WEATHER_MAP_API_KEY={YOUR KEY}') + return + + response = requests.get(f'https://api.openweathermap.org/data/2.5/weather?units=metric&q={city_name}&appid={api_key}') + response.raise_for_status + if response.ok: + return response + +def print_weather_data(temp, location): + + print(f'{location} weather:') + print(f'{temp} degrees celsius') + +if __name__ == "__main__": + print_header() + location = get_location() + response = get_weather_for_city(location) + if response: + if response.status_code == 200: + data = response.json() + main = data['main'] + temp = main['temp'] + print_weather_data(temp, location) \ No newline at end of file diff --git a/grabbing_the_weather/tests/__init__.py b/grabbing_the_weather/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/grabbing_the_weather/tests/system/__init__.py b/grabbing_the_weather/tests/system/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/grabbing_the_weather/tests/system/app_test.py b/grabbing_the_weather/tests/system/app_test.py new file mode 100644 index 0000000..6b81c45 --- /dev/null +++ b/grabbing_the_weather/tests/system/app_test.py @@ -0,0 +1,38 @@ +import os +from unittest import TestCase +from unittest.mock import patch, call +import app + + +class AppTest(TestCase): + + def test_print_header(self): + + expected = '-----------------------\n Grabbing the weather \n-----------------------\n' + with patch('builtins.print') as mocked_print: + app.print_header() + mocked_print.assert_called_with(expected) + + + def test_get_weather_for_city(self): + city_name = 'Sheffield' + response_json = {'coord': {'lon': -1.47, 'lat': 53.38}, 'weather': [{'id': 801, 'main': 'Clouds', 'description': 'few clouds', 'icon': '02d'}], 'base': 'stations', 'main': {'temp': 19.99, 'pressure': 1007, 'humidity': 49, 'temp_min': 17.78, 'temp_max': 22.22}, 'visibility': 10000, 'wind': {'speed': 7.2, 'deg': 230}, 'clouds': {'all': 20}, 'dt': 1565007677, 'sys': {'type': 1, 'id': 1382, 'message': 0.0072, 'country': 'GB', 'sunrise': 1564979280, 'sunset': 1565034948}, 'timezone': 3600, 'id': 2638077, 'name': 'Sheffield', 'cod': 200} + with patch('requests.get') as mocked_request_get: + mocked_request_get.return_value.status_code = 200 + mocked_request_get.return_value.json.return_value = response_json + response = app.get_weather_for_city(city_name) + self.assertEqual(response.status_code, 200) + api_key = os.environ['OPEN_WEATHER_MAP_API_KEY'] + mocked_request_get.assert_called_with(f'https://api.openweathermap.org/data/2.5/weather?units=metric&q=Sheffield&appid={api_key}') + self.assertEqual(response.json(), response_json) + + + def test_print_people_in_space(self): + + expected = [call('Sheffield weather:'), call('20 degrees celsius')] + temp = 20 + location = 'Sheffield' + + with patch('builtins.print') as mocked_print: + app.print_weather_data(temp, location) + mocked_print.assert_has_calls(expected) \ No newline at end of file diff --git a/grabbing_the_weather/tests/unit/__init__.py b/grabbing_the_weather/tests/unit/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/grabbing_the_weather/tests/unit/unit_test.py b/grabbing_the_weather/tests/unit/unit_test.py new file mode 100644 index 0000000..4918ff7 --- /dev/null +++ b/grabbing_the_weather/tests/unit/unit_test.py @@ -0,0 +1,5 @@ +from unittest import TestCase +import app + +class FilteringRecordsTest(TestCase): + pass \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..5ba33e6 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,18 @@ +appdirs==1.4.3 +attrs==19.1.0 +autopep8==1.4.4 +black==19.3b0 +certifi==2019.6.16 +chardet==3.0.4 +Click==7.0 +Flask==1.1.1 +idna==2.8 +itsdangerous==1.1.0 +Jinja2==2.10.1 +MarkupSafe==1.1.1 +pkg-resources==0.0.0 +pycodestyle==2.5.0 +requests==2.22.0 +toml==0.10.0 +urllib3==1.25.3 +Werkzeug==0.15.5