diff --git a/.ionide/symbolCache.db b/.ionide/symbolCache.db new file mode 100644 index 0000000..8a73c4f Binary files /dev/null and b/.ionide/symbolCache.db differ diff --git a/submissions/eoneoff/weather-api/color.py b/submissions/eoneoff/weather-api/color.py new file mode 100644 index 0000000..5a0c1e6 --- /dev/null +++ b/submissions/eoneoff/weather-api/color.py @@ -0,0 +1,5 @@ +def _print_color(string, code): return f'\033[38;5;{code}m{string}\033[37m' + +def y(string): return _print_color(string, 3) +def c(string): return _print_color(string, 6) +def g(string): return _print_color(string, 8) \ No newline at end of file diff --git a/submissions/eoneoff/weather-api/get_weather.py b/submissions/eoneoff/weather-api/get_weather.py new file mode 100644 index 0000000..43b598c --- /dev/null +++ b/submissions/eoneoff/weather-api/get_weather.py @@ -0,0 +1,30 @@ +import requests +from datetime import datetime + +_baseUrl = 'http://api.openweathermap.org/data/2.5/' + +_params = {'APPID': 'c4ad7974f3977f8f388a60b5c0267caa'} + +def get_weather(mode, location, units): + _params['q'] = location + _params['units'] = units + data = requests.get(url=f'{_baseUrl}{mode}', params=_params).json() + return [_make_weather_data(data, data['name'])] if mode=='weather' \ + else [_make_weather_data(day, data['city']['name']) for day in data['list']] + + + +def _make_weather_data(data, name): + return { + 'icon': data['weather'][0]['icon'], + 'city': name, + 'date': datetime.fromtimestamp(data['dt']), + 'description': data['weather'][0]['description'], + 'temp': data['main']['temp'], + 'maxTemp': data['main']['temp_max'], + 'minTemp': data['main']['temp_min'], + 'wind': { + 'deg': data['wind']['deg'], + 'speed': data['wind']['speed'] + } + } \ No newline at end of file diff --git a/submissions/eoneoff/weather-api/icons.py b/submissions/eoneoff/weather-api/icons.py new file mode 100644 index 0000000..96601b3 --- /dev/null +++ b/submissions/eoneoff/weather-api/icons.py @@ -0,0 +1,71 @@ +from color import y,g,c + +icons = { + '01d':f''' {y('OOO')} + {y('OOOOO')} + {y('(OOOOO)')} + {y('OOOOO')} + {y('OOO')}''', + '01n': ''' OOO + OOOOO + (OOOOO) + OOOOO + OOO''', + '02d': f''' {c('@@@')} {y('OOO')} + {c('@ @@@')}{y('OOO')} + {c('@@ @@@')}{y('OO)')} + {c('@@@ @@@@@@')} + {c('@@@@@@@@@@@@@@')}''', + '02n': f''' {c('@@@')} OOO + {c('@ @@@')}OOO + {c('@@ @@@')}OO) + {c('@@@ @@@@@@')} + {c('@@@@@@@@@@@@@@')}''', + '03d':f''' {c('@@@')} + {c('@ @@@')} + {c('@@ @@@')} + {c('@@@ @@@@@@')} +{c('@@@@@@@@@@@@@@')}''', + '04d': f''' {c('@@@')}{g('##')} + {c('@ @@@')}{g('##')} + {c('@@ @@@')}{g('##')} + {c('@@@ @@@@@')}{g('###')} +{c('@@@@@@@@@@@@@@')}''', + '09d': f''' {c('@@@')}{g('##')} + {c('@ @@@')}{g('##')} + {c('@@ @@@')}{g('##')} + {c('@@@@@@@@@@@@')} + {g(",',',',',',',")}''', + '10d': f''' {c('@@@')} {y('OOO')} + {c('@@ @@@')}{y('OOO')} + {c('@@@ @@@@')}{y('O)')} + {c('@@@@@@@@@@@@')} + {g(",',',',',','")}''', + '10n': f''' {c('@@@')} OOO + {c('@@ @@@')}OOO + {c('@@@ @@@@')}O) + {c('@@@@@@@@@@@@')} + {g(",',',',',','")}''', + '11d': f''' {c('@@@')}{g('##')} + {c('@@@')}{y('/')}{c('@@')}{g('##')} +{c('@@@')}{y('/_')}{c('@@@')}{g('##')} + {y('/')} + {y('/')}''', + '13d': ''' * +***** + *** +***** + *''', + '50d':g(''' — + --—— + —--— + —---—-- + —--—''') +} + +icons['03n'] = icons['03d'] +icons['04n'] = icons['04d'] +icons['09n'] = icons['09d'] +icons['11n'] = icons['11d'] +icons['13n'] = icons['13d'] +icons['50n'] = icons['50d'] \ No newline at end of file diff --git a/submissions/eoneoff/weather-api/main.py b/submissions/eoneoff/weather-api/main.py new file mode 100644 index 0000000..924f502 --- /dev/null +++ b/submissions/eoneoff/weather-api/main.py @@ -0,0 +1,15 @@ +import argparse +from show_weather import show_weather + +parser = argparse.ArgumentParser() + +parser.add_argument('-l', '--location', default='') +parser.add_argument('-r', '--range', default='day') +parser.add_argument('-u', '--units', default='celsius') + +args=parser.parse_args() + +mode = 'forecast' if args.range == 'week' else 'weather' +units = 'imperial' if args.units == 'farenheit' else 'metric' + +show_weather(mode, args.location, units) \ No newline at end of file diff --git a/submissions/eoneoff/weather-api/manage_cities.py b/submissions/eoneoff/weather-api/manage_cities.py new file mode 100644 index 0000000..c89f445 --- /dev/null +++ b/submissions/eoneoff/weather-api/manage_cities.py @@ -0,0 +1,37 @@ +def save_city(city): + save_recent(city) + save_favourite(city) + +def save_recent(city): + recent = read_recent() + if city in recent: return + recent.insert(0, city) + write_recent(recent[0:10]) + +def save_favourite(city): + favourite = read_favourite() + count = favourite.setdefault(city, 0) + favourite[city]=count+1 + write_favourite({k:v for k,v in sorted(favourite.items(), key=lambda c: c[1], reverse=True)[0:10]}) + +def read_recent(): + try: + with open('recent.csv', 'r') as f: + return f.read().splitlines() + except: + return [] + +def write_recent(recent): + with open('recent.csv', 'w') as f: + f.writelines(map(lambda c: f'{c}\n', recent)) + +def read_favourite(): + try: + with open('favourite.csv', 'r') as f: + return {name: int(count) for name, count in [city.split(';') for city in f.read().splitlines()]} + except: + return {} + +def write_favourite(favourite): + with open('favourite.csv', 'w') as f: + f.writelines([f'{name};{count}\n' for name,count in favourite.items()]) \ No newline at end of file diff --git a/submissions/eoneoff/weather-api/requirements.txt b/submissions/eoneoff/weather-api/requirements.txt new file mode 100644 index 0000000..dc759f5 --- /dev/null +++ b/submissions/eoneoff/weather-api/requirements.txt @@ -0,0 +1,6 @@ +certifi==2019.11.28 +chardet==3.0.4 +idna==2.8 +requests==2.22.0 +terminaltables==3.1.0 +urllib3==1.25.7 diff --git a/submissions/eoneoff/weather-api/show_weather.py b/submissions/eoneoff/weather-api/show_weather.py new file mode 100644 index 0000000..c583849 --- /dev/null +++ b/submissions/eoneoff/weather-api/show_weather.py @@ -0,0 +1,48 @@ +from get_weather import get_weather +from icons import icons +from terminaltables import SingleTable +from color import c +from manage_cities import save_city +from wrong_city import wrong_city + +def show_weather(mode, location, units): + weather = {} + while not weather: + try: + weather = get_weather(mode, location, units) + except KeyError: + location = wrong_city(location) + + _weather_block(weather, + 'F°' if units=='imperial' else 'C°', + 'mph' if units=='imperial' else 'm/s') + save_city(location) + +def _weather_block(data, tUnit, wUnit): + weather = SingleTable(list(map(lambda day: [ + f'\n\n{icons[day["icon"]]}', + _weather_data(day, tUnit, wUnit) + ], data))) + weather.inner_column_border = False + weather.inner_row_border = True + print(weather.table) + +def _weather_data(data, tUnit, wUnit): + return f'\n{c("Location:")} {data["city"]}\n'+ \ + f'{c("Date:")} {data["date"].strftime("%d %b %Y")}\n' + \ + f'{c("Time: ")} {data["date"].strftime("%H:%M")}\n' + \ + f'{data["description"]}\n' + \ + f'{c("Temperature: ")} {data["temp"]}{tUnit}\n' + \ + f'{c("Maximum temperature:")} {data["maxTemp"]}{tUnit}\n' + \ + f'{c("Minimum temperature:")} {data["minTemp"]}{tUnit}\n' + \ + f'{c("Wind")} {_wind_direction(float(data["wind"]["deg"]))} {data["wind"]["speed"]}{wUnit}' + +def _wind_direction(wind): + if wind > 338 or wind < 22: return 'N' + if wind < 67: return 'NE' + if wind < 113: return 'E' + if wind < 157: return 'SE' + if wind < 202: return 'S' + if wind < 247: return 'SW' + if wind < 292: return 'W' + return 'NW' \ No newline at end of file diff --git a/submissions/eoneoff/weather-api/wrong_city.py b/submissions/eoneoff/weather-api/wrong_city.py new file mode 100644 index 0000000..7dbd162 --- /dev/null +++ b/submissions/eoneoff/weather-api/wrong_city.py @@ -0,0 +1,41 @@ +from manage_cities import read_recent, read_favourite + +def wrong_city(city): + print(f'here is no weather data for the city with the name {city}' if city \ + else 'There is no city name provided') + print('''1. Select city form recent +2. Select city from favourite +3. Enter city +0. Cancel''') + choice = get_choice(3) + if choice == '1': + return select_recent() + elif choice == '2': + return select_favourite() + elif choice == '3': + return input('Enter city name: ') + else: exit(0) + +def select_recent(): + recent = read_recent() + for i in range(len(recent)): + print(f'{i+1}. {recent[i]}') + print('0. Cancel') + choice = get_choice(len(recent)) + if choice == '0': return '' + else: return recent[int(choice)-1] + +def select_favourite(): + favourite = [name for name in read_favourite().keys()] + for i in range(len(favourite)): + print(f'{i+1}. {favourite[i]}') + print('0. Cancel') + choice = get_choice(len(favourite)) + if choice == '0': return '' + else: return favourite[int(choice)-1] + +def get_choice(number): + choice = '' + while not choice.isdigit() or int(choice) not in range(number+1): + choice = input(f'Select {", ".join(map(str, range(1, number+1)))} or 0: ') + return choice \ No newline at end of file