From aee7eccc285e8bfc86eee7a480a3837a0f0605f7 Mon Sep 17 00:00:00 2001 From: Anker166 Date: Sun, 8 Sep 2019 18:43:50 +0300 Subject: [PATCH 1/2] =?UTF-8?q?=D0=9D=D0=B5=20=D1=83=D1=81=D0=BF=D0=B5?= =?UTF-8?q?=D0=BB=20=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D1=81=D1=82=D1=8C=D1=8E?= =?UTF-8?q?=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C=20=D0=B4=D0=B7.?= =?UTF-8?q?=20=D0=9F=D0=BE=D0=BA=D0=B0=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87?= =?UTF-8?q?=D0=B8=D0=BB=D0=BE=D1=81=D1=8C=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA?= =?UTF-8?q?=D0=BE=20=D0=BF=D0=BE=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81?= =?UTF-8?q?=D1=83=20=D0=B3=D0=BE=D1=80=D0=BE=D0=B4=D0=BE=D0=B2=20=D0=B8?= =?UTF-8?q?=D0=B7=20=D1=81=D0=BF=D0=B8=D1=81=D0=BA=D0=B0=20=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B0=D1=82=D1=8C=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=B3=D0=BE=D0=B4=D1=8B=20=D0=B8=20=D1=81=D0=BE?= =?UTF-8?q?=D1=85=D1=80=D0=B0=D0=BD=D1=8F=D1=82=D1=8C=20=D0=B8=D0=BD=D1=84?= =?UTF-8?q?=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8E,=20=D1=81=20=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D1=8C=D1=8E=20?= =?UTF-8?q?=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D1=83=D1=8E=D1=89?= =?UTF-8?q?=D0=B8=D1=85=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85,=20=D0=B2?= =?UTF-8?q?=20=D0=B1=D0=B0=D0=B7=D1=83=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D1=85.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lesson08/home_work/openweather.py | 114 ++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/lesson08/home_work/openweather.py b/lesson08/home_work/openweather.py index a9debfa1c..1307ca33d 100644 --- a/lesson08/home_work/openweather.py +++ b/lesson08/home_work/openweather.py @@ -123,3 +123,117 @@ def gen_ns(tag): """ +import json +import requests +import os +import sqlite3 +from datetime import datetime + + +with open('city_list.json', 'rb') as read_city_list: + city_list = json.load(read_city_list) + +with open('app.id', 'r') as read_app_id: + app_id = read_app_id.read().strip() + + +def city_id(cities, city_name): + id_of_city = '' + for c in city_name: + for city in cities: + if c[0] == city['name'] and c[1] == city['country']: + id_of_city += f'{city["id"]},' + id_of_city = id_of_city[:-1] + return id_of_city + + +city_name = [['Moskva', 'RU'], ['Sankt-Peterburg', 'RU'], ['Noginsk', 'RU'], ['Reutov', 'RU']] +id_param = city_id(city_list, city_name) + +if id_param.count(',') == 0: + api_url = 'http://api.openweathermap.org/data/2.5/weather' + params = { + 'id': id_param, + 'appid': app_id, + 'units': 'metric', + } + + res = requests.get(api_url, params=params) + print(res.url) + first_data = res.json() + print(first_data) + write_data = [first_data['id'], first_data['name'], + datetime.utcfromtimestamp(first_data['dt']).strftime('%d-%m-%Y'), + first_data['main']['temp'], first_data['weather'][0]['id'] + ] + print(write_data) +else: + api_url = 'http://api.openweathermap.org/data/2.5/group' + params = { + 'id': id_param, + 'appid': app_id, + 'units': 'metric', + } + + res = requests.get(api_url, params=params) + print(res.url) + first_data = res.json() + print(first_data) + write_data = [] + for data in first_data['list']: + write_data.append([data['id'], data['name'], + datetime.utcfromtimestamp(data['dt']).strftime('%d-%m-%Y'), + data['main']['temp'], data['weather'][0]['id'] + ]) + print(write_data) + + +db_weather = 'weather.db' + +if db_weather not in os.listdir('.'): + with sqlite3.connect(db_weather) as conn: + conn.execute("""CREATE TABLE Погода( + id_города INTEGER PRIMARY KEY, + Город VARCHAR(255), + Дата DATE, + Температура INTEGER, + id_погоды INTEGER + ) + """) + +else: + with sqlite3.connect(db_weather) as conn: + for i in range(len(write_data)): + conn.execute("""INSERT OR REPLACE INTO Погода VALUES (?,?,?,?,?)""", write_data[i]) + + with sqlite3.connect('weather.db') as conn: + conn.row_factory = sqlite3.Row + cur = conn.cursor() + cur.execute("select * from Погода") + for row in cur.fetchall(): + id_города, Город, Дата, Температура, id_погоды = row + print(f'|id_города: {id_города}|Город: {Город}|Дата: {Дата}|Температура: {Температура}|id_погоды: {id_погоды}|') + +# def countries(cities): +# country = set() +# for city in cities: +# country.add(city['country']) +# country_list = list(country) +# country_list.sort() +# return country_list +# +# def country_cities(cities, country): +# while True: +# ans = input('Введите страну для которой хотите получить список городов\n').upper() +# if ans in country: +# break +# cities_list = [] +# for city in cities: +# if city['country'] == ans: +# cities_list.append(city['name']) +# cities_list.sort() +# return cities_list + + + + From 309304f62dcfb1e67f28da646310cd0dd4ccd168 Mon Sep 17 00:00:00 2001 From: Anker166 <53167870+Anker166@users.noreply.github.com> Date: Wed, 11 Sep 2019 16:54:08 +0300 Subject: [PATCH 2/2] Add files via upload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Загрузку погоды вроде бы сделал, правда поиск по городам не понял как сделать регуляркой. Получилось довольно громоздко, пока не знаю как сократить Экспорт Сделал для csv и json форматов. в csv при сохранении открытии эксель температуру почему-то сохраняет как дату... --- lesson08/home_work/export_openweather.py | 132 ++++- lesson08/home_work/openweather.py | 589 ++++++++++++++--------- 2 files changed, 458 insertions(+), 263 deletions(-) diff --git a/lesson08/home_work/export_openweather.py b/lesson08/home_work/export_openweather.py index 0ae937519..39985c9fc 100644 --- a/lesson08/home_work/export_openweather.py +++ b/lesson08/home_work/export_openweather.py @@ -1,24 +1,108 @@ - -""" OpenWeatherMap (экспорт) - -Сделать скрипт, экспортирующий данные из базы данных погоды, -созданной скриптом openweather.py. Экспорт происходит в формате CSV или JSON. - -Скрипт запускается из командной строки и получает на входе: - export_openweather.py --csv filename [<город>] - export_openweather.py --json filename [<город>] - export_openweather.py --html filename [<город>] - -При выгрузке в html можно по коду погоды (weather.id) подтянуть -соответствующие картинки отсюда: http://openweathermap.org/weather-conditions - -Экспорт происходит в файл filename. - -Опционально можно задать в командной строке город. В этом случае -экспортируются только данные по указанному городу. Если города нет в базе - -выводится соответствующее сообщение. - -""" - -import csv -import json + +""" OpenWeatherMap (экспорт) + +Сделать скрипт, экспортирующий данные из базы данных погоды, +созданной скриптом openweather.py. Экспорт происходит в формате CSV или JSON. + +Скрипт запускается из командной строки и получает на входе: + export_openweather.py --csv filename [<город>] + export_openweather.py --json filename [<город>] + export_openweather.py --html filename [<город>] + +При выгрузке в html можно по коду погоды (weather.id) подтянуть +соответствующие картинки отсюда: http://openweathermap.org/weather-conditions + +Экспорт происходит в файл filename. + +Опционально можно задать в командной строке город. В этом случае +экспортируются только данные по указанному городу. Если города нет в базе - +выводится соответствующее сообщение. + +""" + +import csv +import json +import sys +import sqlite3 + +db_weather = 'weather.db' +csv.register_dialect('excel-semicolon', delimiter=';') +#encoding = 'utf-8' +encoding = 'windows-1251' + + +def open_db(): + with sqlite3.connect(db_weather) as conn: + cur = conn.cursor() + cur.execute("SELECT * FROM Погода") + column_names = [description[0] for description in cur.description] + table_content = cur.fetchall() + content = [] + for _ in range(len(table_content)): + content.append(dict(zip(column_names, table_content[_]))) + return content, column_names + + +def export_json(fname, c_name=None): + content, column_names = open_db() + fname = fname + '.json' + write_content = [] + if c_name: + for elem in content: + if c_name in elem.values(): + write_content.append(elem) + else: + write_content = content + if len(write_content) == 0: + print('Данных нет в базе') + exit() + with open(fname, 'w', encoding='UTF8') as write_json: + json.dump(write_content, write_json, ensure_ascii=False, indent=2) + + +def export_csv(fname, c_name=None): + content, column_names = open_db() + fname = fname + '.csv' + write_content = [] + if c_name: + for elem in content: + if c_name in elem.values(): + write_content.append(elem) + else: + write_content = content + if len(write_content) == 0: + print('Данных нет в базе') + exit() + with open(fname, 'w', encoding=encoding) as csvfile: + writer = csv.DictWriter(csvfile, fieldnames=column_names, dialect='excel-semicolon') + headers = {name: name for name in column_names} + writer.writerow(headers) + for _ in range(len(write_content)): + writer.writerow(write_content[_]) + + +do = { + '--csv': export_csv, + '--json': export_json, +} + +try: + city_name = sys.argv[3] +except IndexError: + city_name = None + +try: + filename = sys.argv[2] +except IndexError: + filename = None + +try: + operation = sys.argv[1] +except IndexError: + operation = None + +if operation: + if do[operation]: + do[operation](filename, city_name) + else: + print("Задана неверная команда") \ No newline at end of file diff --git a/lesson08/home_work/openweather.py b/lesson08/home_work/openweather.py index 1307ca33d..e5f64bcfd 100644 --- a/lesson08/home_work/openweather.py +++ b/lesson08/home_work/openweather.py @@ -1,239 +1,350 @@ - -""" -== OpenWeatherMap == - -OpenWeatherMap — онлайн-сервис, который предоставляет бесплатный API - для доступа к данным о текущей погоде, прогнозам, для web-сервисов - и мобильных приложений. Архивные данные доступны только на коммерческой основе. - В качестве источника данных используются официальные метеорологические службы - данные из метеостанций аэропортов, и данные с частных метеостанций. - -Необходимо решить следующие задачи: - -== Получение APPID == - Чтобы получать данные о погоде необходимо получить бесплатный APPID. - - Предлагается 2 варианта (по желанию): - - получить APPID вручную - - автоматизировать процесс получения APPID, - используя дополнительную библиотеку GRAB (pip install grab) - - Необходимо зарегистрироваться на сайте openweathermap.org: - https://home.openweathermap.org/users/sign_up - - Войти на сайт по ссылке: - https://home.openweathermap.org/users/sign_in - - Свой ключ "вытащить" со страницы отсюда: - https://home.openweathermap.org/api_keys - - Ключ имеет смысл сохранить в локальный файл, например, "app.id" - - -== Получение списка городов == - Список городов может быть получен по ссылке: - http://bulk.openweathermap.org/sample/city.list.json.gz - - Далее снова есть несколько вариантов (по желанию): - - скачать и распаковать список вручную - - автоматизировать скачивание (ulrlib) и распаковку списка - (воспользоваться модулем gzip - или распаковать внешним архиватором, воспользовавшись модулем subprocess) - - Список достаточно большой. Представляет собой JSON-строки: -{"_id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}} -{"_id":519188,"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}} - - -== Получение погоды == - На основе списка городов можно делать запрос к сервису по id города. И тут как раз понадобится APPID. - By city ID - Examples of API calls: - http://api.openweathermap.org/data/2.5/weather?id=2172797&appid=b1b15e88fa797225412429c1c50c122a - - Для получения температуры по Цельсию: - http://api.openweathermap.org/data/2.5/weather?id=520068&units=metric&appid=b1b15e88fa797225412429c1c50c122a - - Для запроса по нескольким городам сразу: - http://api.openweathermap.org/data/2.5/group?id=524901,703448,2643743&units=metric&appid=b1b15e88fa797225412429c1c50c122a - - - Данные о погоде выдаются в JSON-формате - {"coord":{"lon":38.44,"lat":55.87}, - "weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}], - "base":"cmc stations","main":{"temp":280.03,"pressure":1006,"humidity":83, - "temp_min":273.15,"temp_max":284.55},"wind":{"speed":3.08,"deg":265,"gust":7.2}, - "rain":{"3h":0.015},"clouds":{"all":76},"dt":1465156452, - "sys":{"type":3,"id":57233,"message":0.0024,"country":"RU","sunrise":1465087473, - "sunset":1465149961},"id":520068,"name":"Noginsk","cod":200} - - -== Сохранение данных в локальную БД == -Программа должна позволять: -1. Создавать файл базы данных SQLite со следующей структурой данных - (если файла базы данных не существует): - - Погода - id_города INTEGER PRIMARY KEY - Город VARCHAR(255) - Дата DATE - Температура INTEGER - id_погоды INTEGER # weather.id из JSON-данных - -2. Выводить список стран из файла и предлагать пользователю выбрать страну -(ввиду того, что список городов и стран весьма велик - имеет смысл запрашивать у пользователя имя города или страны - и искать данные в списке доступных городов/стран (регуляркой)) - -3. Скачивать JSON (XML) файлы погоды в городах выбранной страны -4. Парсить последовательно каждый из файлов и добавлять данные о погоде в базу - данных. Если данные для данного города и данного дня есть в базе - обновить - температуру в существующей записи. - - -При повторном запуске скрипта: -- используется уже скачанный файл с городами; -- используется созданная база данных, новые данные добавляются и обновляются. - - -При работе с XML-файлами: - -Доступ к данным в XML-файлах происходит через пространство имен: -