weather_judge 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +55 -14
- data/lib/weather_judge/configuration.rb +32 -1
- data/lib/weather_judge/version.rb +1 -1
- data/lib/weather_judge/weather_data.rb +30 -9
- data/lib/weather_judge.rb +15 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b16a105944c44f8c8570ceecaf92d4bce60d87e9
|
4
|
+
data.tar.gz: 2083d9db3e5990d7a1c7ef7f9e7a604310f917b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69ee399124f40a141c80f6accbda48b3e2fc48196d213e67c1dc039c9fbe9facc4ccb2a10be3c2d0cb06271ba9011c7dea2d1dc9eaaf555920c3a87885957773
|
7
|
+
data.tar.gz: 5fed51dce6328ed31f0086c73cbb1b41556cd32c613d49a64593026ea7929eb5dfee2f6cf963cc287cabf717776077fac24c902f7d212fe676c5c44c45f4750c
|
data/README.md
CHANGED
@@ -2,18 +2,26 @@
|
|
2
2
|
|
3
3
|
This gem retrieves weather forecasting data from Forecast.IO via [forecast-ruby](https://github.com/darkskyapp/forecast-ruby)
|
4
4
|
using longitude and latitude and returns an overall score. The following criteria are used to judge
|
5
|
-
the quality of weather. The
|
5
|
+
the quality of weather. The maximum score you can get is 100.
|
6
6
|
|
7
7
|
- Temperature
|
8
8
|
- Sky Cover
|
9
9
|
- Wind speed
|
10
|
-
-
|
10
|
+
- Chance of Rain
|
11
11
|
|
12
12
|
Currently it only evaluates today's data but I plan on adding an ability to take a specified date. This is
|
13
|
-
more of a proof of concept at this point. Since there are four criteria
|
14
|
-
up to 25 points.
|
13
|
+
more of a proof of concept at this point. Since there are four criteria, each criteria can be given
|
14
|
+
up to 25 points. By default, optimal weather is considered as a day with comfortable temperature (67-77F), less than 15 mph wind,
|
15
15
|
low chance of rain, and low sky cover.
|
16
16
|
|
17
|
+
## Why I Developed This Gem
|
18
|
+
|
19
|
+
I currently live in Portland, OR, USA, where we have access to great outdoors. You can easily drive to the
|
20
|
+
coast (Pacific Ocean) or the mountains (Cascade Range) within a few hours. Consequently, we have
|
21
|
+
micro-climates and the weather can vary depending on where you are. I like to hike a lot, so I need
|
22
|
+
to know where would be the best place to go for a day trip easily. I plan to use this gem for an app
|
23
|
+
that will rank specified locations to help me decide where to go on the day of the trip.
|
24
|
+
|
17
25
|
## Installation
|
18
26
|
|
19
27
|
Add this line to your application's Gemfile:
|
@@ -31,21 +39,54 @@ Or install it yourself as:
|
|
31
39
|
$ gem install weather_judge
|
32
40
|
|
33
41
|
## Usage
|
34
|
-
`WeatherJudge` returns overall weather score, and scores of weather aspect.
|
42
|
+
`WeatherJudge` takes longitude and latitude as input and then returns an overall weather score, and scores of weather aspect via `WeatherData` class.
|
35
43
|
|
36
44
|
Please see [Forecast IO's documentation](https://developer.forecast.io/) for creating an api key.
|
37
45
|
|
46
|
+
To configure you can do:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
WeatherJudge.configure do |configuration|
|
50
|
+
configuration.forecast_io_api_key = `(your api key here)`
|
51
|
+
configuration.max_cloud_cover = 0.60
|
52
|
+
configuration.max_percent_rain = 0.30
|
53
|
+
configuration.max_wind_speed = 22
|
54
|
+
configuration.ideal_temp_range = { min: 50, max: 80}
|
55
|
+
configuration.temp_range_delta = 10
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
or
|
60
|
+
|
38
61
|
```ruby
|
39
|
-
WeatherJudge.forecast_io_api_key =
|
40
|
-
|
62
|
+
WeatherJudge.forecast_io_api_key = `(your api key here)`
|
63
|
+
WeatherJudge.max_cloud_cover = 0.60
|
64
|
+
# and so forth
|
65
|
+
```
|
66
|
+
|
67
|
+
More details on configuration
|
68
|
+
- `max_cloud_cover`: Maximum cloud cover you are willing to tolerate. A decimal number between 0 to 1
|
69
|
+
- `max_percent_rain`: Maximum change of rain you are willing to tolerate. A decimal number between 0 to 1
|
70
|
+
- `max_wind_speed`: Maximum wind speed you are willing to tolerate. Default is 15 mph.
|
71
|
+
- `ideal_temp_range`: Ideal temperature range in fahrenheit expressed in hash
|
72
|
+
- `temp_range_delta`: The delta for slightly less than ideal temperate range in fahrenheit
|
73
|
+
|
74
|
+
To run, you need to pass in a valid coordinates.
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
data = WeatherJudge.run(44.123, -122.123)
|
41
78
|
# => Returns `WeatherData` object
|
42
79
|
|
43
80
|
data.total_location_score
|
44
|
-
# => returns a score of
|
81
|
+
# => returns a score of up to 100
|
45
82
|
```
|
46
83
|
|
47
|
-
|
48
|
-
- `raw_data`
|
84
|
+
List of available methods for `WeatherData`
|
85
|
+
- `raw_data` returns forecast data in `Hashie` (More info on Hashie [here](https://github.com/intridea/hashie)) . Example:
|
86
|
+
```
|
87
|
+
=> #<Hashie::Mash apparentTemperatureMax=85.83 apparentTemperatureMaxTime=1472702400 apparentTemperatureMin=79.79 apparentTemperatureMinTime=1472734800 cloudCover=0.17 dewPoint=70.42 humidity=0.72 icon="partly-cloudy-night" moonPhase=0.99 ozone=280.5 precipIntensity=0.001 precipIntensityMax=0.0025 precipIntensityMaxTime=1472677200 precipProbability=0.07 precipType="rain" pressure=1009.95 summary="Partly cloudy in the morning." sunriseTime=1472673538 sunsetTime=1472719928 temperatureMax=81.76 temperatureMaxTime=1472702400 temperatureMin=79.79 temperatureMinTime=1472734800 time=1472652000 windBearing=186 windSpeed=4.09>
|
88
|
+
|
89
|
+
```
|
49
90
|
- `total_location_score`
|
50
91
|
- `cloud_cover_score`
|
51
92
|
- `wind_score`
|
@@ -64,11 +105,11 @@ update the version number in `version.rb`, and then run `bundle exec rake releas
|
|
64
105
|
git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
65
106
|
|
66
107
|
## Future Plans/Disclaimer
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
- Add ability to change preferred weather aspects for scoring
|
108
|
+
This gem was originally developed to be used in my personal project for ranking overall weather of
|
109
|
+
different locations, but feel free to use it for any other purpose. This gem will be evolving in the
|
110
|
+
near future. A few of obvious future plans are:
|
71
111
|
- Add ability to specify a date for retrieving scored data
|
112
|
+
- Other weather criteria to evaluate
|
72
113
|
|
73
114
|
## Contributing
|
74
115
|
|
@@ -1,9 +1,40 @@
|
|
1
1
|
module WeatherJudge
|
2
2
|
module Configuration
|
3
|
-
attr_writer :forecast_io_api_key
|
3
|
+
attr_writer :forecast_io_api_key, :max_cloud_cover, :max_percent_rain, :max_wind_speed,
|
4
|
+
:ideal_temp_range, :temp_range_delta
|
5
|
+
|
6
|
+
# For configuring WeatherJudge with block style
|
7
|
+
def configure
|
8
|
+
yield self
|
9
|
+
end
|
4
10
|
|
5
11
|
def forecast_io_api_key
|
6
12
|
@forecast_io_api_key
|
7
13
|
end
|
14
|
+
|
15
|
+
# Maximum cloud cover you are willing to tolerate
|
16
|
+
def max_cloud_cover
|
17
|
+
@max_cloud_cover
|
18
|
+
end
|
19
|
+
|
20
|
+
# Maximum change of rain you are willing to tolerate
|
21
|
+
def max_percent_rain
|
22
|
+
@max_percent_rain
|
23
|
+
end
|
24
|
+
|
25
|
+
# Maximum wind speed you are willing to tolerate. Default is 15mph.
|
26
|
+
def max_wind_speed
|
27
|
+
@max_wind_speed || 15
|
28
|
+
end
|
29
|
+
|
30
|
+
# Ideal temperature range in fahrenheit expressed in hash
|
31
|
+
def ideal_temp_range
|
32
|
+
@ideal_temp_range || { min: 67, max: 77 }
|
33
|
+
end
|
34
|
+
|
35
|
+
# The delta for slightly less than ideal temperate range in fahrenheit
|
36
|
+
def temp_range_delta
|
37
|
+
@temp_range_delta || 10
|
38
|
+
end
|
8
39
|
end
|
9
40
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
require 'bigdecimal/util'
|
3
|
+
|
1
4
|
# Calculates score for 4 different weather aspects: sky cover,
|
2
5
|
# chance of rain, wind, and temperature
|
3
6
|
|
@@ -21,19 +24,17 @@ module WeatherJudge
|
|
21
24
|
end
|
22
25
|
|
23
26
|
def cloud_cover_score
|
24
|
-
@forecast_today.cloudCover
|
27
|
+
score_from_decimal_data(WeatherJudge.max_cloud_cover, @forecast_today.cloudCover)
|
25
28
|
end
|
26
29
|
|
27
30
|
def percent_rain_score
|
28
|
-
@forecast_today.precipProbability
|
31
|
+
score_from_decimal_data(WeatherJudge.max_percent_rain, @forecast_today.precipProbability)
|
29
32
|
end
|
30
33
|
|
31
34
|
def wind_score
|
32
35
|
wind_speed = @forecast_today.windSpeed
|
33
|
-
max_wind_speed =
|
34
|
-
if wind_speed
|
35
|
-
SCORE_WEIGHT
|
36
|
-
elsif wind_speed < max_wind_speed
|
36
|
+
max_wind_speed = WeatherJudge.max_wind_speed.to_f
|
37
|
+
if wind_speed < max_wind_speed
|
37
38
|
((max_wind_speed - wind_speed) / max_wind_speed) * SCORE_WEIGHT
|
38
39
|
else
|
39
40
|
0
|
@@ -41,15 +42,35 @@ module WeatherJudge
|
|
41
42
|
end
|
42
43
|
|
43
44
|
def temperature_score
|
44
|
-
|
45
|
+
high_today = @forecast_today.temperatureMax
|
46
|
+
min_ideal_temp = WeatherJudge.ideal_temp_range[:min]
|
47
|
+
max_ideal_temp = WeatherJudge.ideal_temp_range[:max]
|
48
|
+
delta = WeatherJudge.temp_range_delta
|
45
49
|
|
46
|
-
if
|
50
|
+
if high_today > min_ideal_temp && high_today < max_ideal_temp
|
47
51
|
SCORE_WEIGHT
|
48
|
-
elsif
|
52
|
+
elsif high_today > min_ideal_temp - delta && high_today < min_ideal_temp ||
|
53
|
+
high_today > max_ideal_temp && high_today < max_ideal_temp + delta
|
49
54
|
SCORE_WEIGHT.to_f / 2
|
50
55
|
else
|
51
56
|
SCORE_WEIGHT.to_f / 4
|
52
57
|
end
|
53
58
|
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Calculates weather quality from decimal data, with an assumption that larger the
|
63
|
+
# data value the worse. E.g. (80% cloud cover returns smaller score than 50% cloud cover.)
|
64
|
+
def score_from_decimal_data(max_allowed, data)
|
65
|
+
if !max_allowed.nil?
|
66
|
+
if data < max_allowed
|
67
|
+
(((max_allowed.to_d - data) / max_allowed) * SCORE_WEIGHT).to_f
|
68
|
+
else
|
69
|
+
0
|
70
|
+
end
|
71
|
+
else
|
72
|
+
((1.to_d - data) * SCORE_WEIGHT).to_f
|
73
|
+
end
|
74
|
+
end
|
54
75
|
end
|
55
76
|
end
|
data/lib/weather_judge.rb
CHANGED
@@ -10,11 +10,26 @@ module WeatherJudge
|
|
10
10
|
|
11
11
|
# Retrieves WeatherData object for today's forecast given latitude and longitude.
|
12
12
|
def run(latitude, longitude)
|
13
|
+
validate_coordinates(latitude, longitude)
|
14
|
+
|
13
15
|
ForecastIO.api_key = WeatherJudge.forecast_io_api_key
|
14
16
|
forecast = ForecastIO.forecast(latitude, longitude, params: { exclude: 'hourly,minutely,alerts,flags'})
|
17
|
+
|
18
|
+
if forecast.nil?
|
19
|
+
raise StandardError.new("Unable to obtain forecast! Check your network connectivity and API key")
|
20
|
+
end
|
21
|
+
|
15
22
|
@forecast_today = forecast.daily.data.first
|
16
23
|
|
17
24
|
WeatherData.new(@forecast_today)
|
18
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def validate_coordinates(latitude, longitude)
|
30
|
+
unless latitude >= -90 && latitude <= 90 && longitude >= -180 && longitude <= 180
|
31
|
+
raise ArgumentError.new("Invalid coordinates!")
|
32
|
+
end
|
33
|
+
end
|
19
34
|
end
|
20
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: weather_judge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Makoto Scott-Hinkle
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|