five-star 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +52 -35
- data/five-star.gemspec +1 -0
- data/lib/five-star.rb +47 -0
- data/lib/five-star/base_rater.rb +121 -1
- data/lib/five-star/rateable.rb +76 -0
- data/lib/five-star/rating_calculator.rb +16 -3
- data/lib/five-star/version.rb +1 -1
- metadata +16 -3
- data/LICENSE.txt +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0ec61a85ec090995b6030203a9b8808e85ff27e
|
4
|
+
data.tar.gz: a21d6768ecb083c34b4b103d78100f2095d726dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca8a6fdb9c2f2fd00d25ea31ca507fafa6cd69c0c9eb3bbe7d3509f368b67a35329012be76909f56a71defb91be16a3d35358eed729e8623a7d586466f810aa2
|
7
|
+
data.tar.gz: b1734c47ace30591629843cc41dfda108c2671e13cf2c15831972659db6b55025a5c5f74b869e76dfd815f4438a539e250bf1cf7bc9d202799836d054d4595f1
|
data/README.md
CHANGED
@@ -1,21 +1,19 @@
|
|
1
1
|
# FiveStar
|
2
|
-
### A generic rating library :star:
|
3
2
|
|
4
3
|
[![Build Status](https://travis-ci.org/rob-murray/five-star.svg?branch=master)](https://travis-ci.org/rob-murray/five-star)
|
5
|
-
[![Code Climate](https://codeclimate.com/github/rob-murray/five-star.
|
6
|
-
[![Coverage Status](https://coveralls.io/repos/rob-murray/five-star/badge.
|
7
|
-
[![Dependency Status](https://gemnasium.com/rob-murray/five-star.svg)](https://gemnasium.com/rob-murray/five-star)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/rob-murray/five-star.svg)](https://codeclimate.com/github/rob-murray/five-star)
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/rob-murray/five-star/badge.svg?branch=master&service=github)](https://coveralls.io/github/rob-murray/five-star?branch=master)
|
8
6
|
[![Gem Version](https://badge.fury.io/rb/five-star.svg)](http://badge.fury.io/rb/five-star)
|
9
7
|
|
10
|
-
:star: **FiveStar** :star: is a library to build a rating system - it allows you to rate *something* in your domain by classification or criteria you define. This library gives you the structure to rate your object with as many of these different classifications as you like with the overall rating as a weighted average.
|
11
8
|
|
12
|
-
|
9
|
+
:star: **FiveStar** :star: is a library to build a rating system - it allows you to rate *something* in your domain by various classification or criteria you define. This library gives you the structure to rate your object with as many of these different classifications as you like with the overall rating calculated from the weighted average.
|
10
|
+
|
11
|
+
This uses *Plain Old Ruby Objects* so can be used in any project.
|
13
12
|
|
14
|
-
> Not sure if this is a gem or just a code design pattern :/
|
15
13
|
|
16
14
|
## Example
|
17
15
|
|
18
|
-
Say you implemented a film rating system, you have lots of `Film` objects each with different attributes and you would like to show an overall rating for each film based on classifications below.
|
16
|
+
Say you implemented a film rating system, you have lots of `Film` objects each with different attributes and you would like to show an overall rating for each film based on classifications below. You might give the amount of swearing in the film slightly less weighting that the amount of sex and violence.
|
19
17
|
|
20
18
|
* Gore - Amount of blood in the movie - weighting: 40%
|
21
19
|
* Sex - Number of references to sex in the movie - weighting: 40%
|
@@ -29,18 +27,32 @@ class Film
|
|
29
27
|
|
30
28
|
rate_with GoreRater, SwearingRater, SexRater
|
31
29
|
|
32
|
-
# rest of
|
30
|
+
# rest of your implementation
|
31
|
+
def blood_spilt
|
32
|
+
# ...
|
33
|
+
end
|
34
|
+
|
35
|
+
def number_of_swear_words
|
36
|
+
# ...
|
37
|
+
end
|
33
38
|
end
|
34
39
|
|
35
40
|
class GoreRater < FiveStar.base_rater
|
36
41
|
rating_weight 0.4
|
37
42
|
|
38
43
|
def description
|
39
|
-
"
|
44
|
+
"The film #{film.title} was rated #{rating} for gore"
|
40
45
|
end
|
41
46
|
|
42
47
|
def rating
|
43
|
-
# count the pints of blood spilt in the film
|
48
|
+
# count the pints of blood spilt in the film and return a rating
|
49
|
+
if film.blood_spilt == :a_lot
|
50
|
+
10
|
51
|
+
elsif film.blood_spilt == :a_little
|
52
|
+
5
|
53
|
+
else
|
54
|
+
0
|
55
|
+
end
|
44
56
|
end
|
45
57
|
end
|
46
58
|
|
@@ -48,17 +60,18 @@ class SwearingRater < FiveStar.base_rater
|
|
48
60
|
rating_weight 0.2
|
49
61
|
|
50
62
|
def description
|
51
|
-
"
|
63
|
+
"The film #{film.title} has #{film.number_of_swear_words} and was rated at #{rating}"
|
52
64
|
end
|
53
65
|
|
54
66
|
def rating
|
55
|
-
# count the number of swear words in the film
|
67
|
+
# count the number of swear words in the film & convert to our rating scale
|
68
|
+
linear_conversion(film.number_of_swear_words)
|
56
69
|
end
|
57
70
|
end
|
58
71
|
|
59
72
|
film = Film.new
|
60
73
|
film.rating # => 6
|
61
|
-
film.rating_descriptions # => ["
|
74
|
+
film.rating_descriptions # => ["The film Alien was rated 8 for gore", ...]
|
62
75
|
|
63
76
|
```
|
64
77
|
|
@@ -81,21 +94,23 @@ Or install it yourself as:
|
|
81
94
|
|
82
95
|
## Usage
|
83
96
|
|
84
|
-
There are two components required, the thing being rated and how it is rated - the thing you want rated is defined as being rateable and you can have one or more
|
97
|
+
There are two components required, the thing being rated and how it is rated - the thing you want rated is defined as being rateable and you can have one or more rating classes to give it a rating. You must implement your these raters and provide the classes to the item being rated, this library takes care of the rest.
|
98
|
+
|
99
|
+
* `rateable` - This is the object that can be rated - this is your domain model that has various attributes that you need rated.
|
100
|
+
* `rater` - A class that knows how to give a rating to the object being rated based on classification of the rateable's attributes.
|
85
101
|
|
86
|
-
|
87
|
-
* `Rater` - A class that knows how to give a rating to the object being rated
|
102
|
+
Each `rater` must return a rating within the scale given and a weighting which will be used to calculate the overall rating.
|
88
103
|
|
89
|
-
|
104
|
+
The default rating scale used is 0 - 10 as floating point numbers although this can be overriden and customised.
|
90
105
|
|
91
|
-
The
|
106
|
+
The rating calculation will take the rating value from each rater along with the weighting to calculate the overall average rating.
|
92
107
|
|
93
108
|
### Rateable
|
94
109
|
|
95
110
|
This module when included gives the object the following interface on the instance.
|
96
111
|
|
97
|
-
* `rating` -
|
98
|
-
* `rating_descriptions` -
|
112
|
+
* `rating` - `@return [Float]` - The overall rating calculated for the rateable object.
|
113
|
+
* `rating_descriptions` - `@return [Array]` - A list of description from each raters. This is delegated to the rater.
|
99
114
|
|
100
115
|
The classes used to rate the object can be specified using the class method `rate_with(*class_names)` and passing in one or more rating classes.
|
101
116
|
|
@@ -104,29 +119,31 @@ class Film
|
|
104
119
|
include FiveStar.rateable
|
105
120
|
|
106
121
|
rate_with GoreRater, SwearingRater, SexRater
|
107
|
-
...
|
122
|
+
# ...
|
123
|
+
end
|
108
124
|
|
109
125
|
film = Film.new
|
110
126
|
film.rating # => 6
|
111
|
-
film.rating_descriptions # => ["
|
127
|
+
film.rating_descriptions # => ["The film Alien was rated 8 for gore", ...]
|
112
128
|
```
|
113
129
|
|
114
130
|
### Rater
|
115
131
|
|
116
132
|
You can create your own rating classes however you like but they should respond to the following methods;
|
117
133
|
|
118
|
-
* `
|
119
|
-
* `
|
120
|
-
* `
|
134
|
+
* `build` - `@param [Rateable], @return [instance of rater]` - Create a new instance of rater with rateable as argument.
|
135
|
+
* `rating` - `@return [Float]` - The rating for the object being rated. Calculate this by your own classification.
|
136
|
+
* `description` - `@return [String]` - A description of the rating, eg reason it was rated at that value.
|
137
|
+
* `weighting` - `@return [Float]` - The weighting for this classification. Withing range 0.0 - 1.0
|
121
138
|
|
122
|
-
The **FiveStar** will call `build` method on the `Rater` with the argument of the instance of class being rated which should do any setup and return an instance of the rater.
|
139
|
+
The **FiveStar** library will call the `build` method on the `Rater` with the argument of the instance of class being rated which should do any setup and return an instance of the rater.
|
123
140
|
|
124
|
-
For simplicity you can subclass `FiveStar.base_rater` and get the following for free.
|
141
|
+
For simplicity you can subclass `FiveStar.base_rater` and get the following for free. If the above methods are not overriden then the default implementation will be used.
|
125
142
|
|
126
|
-
* `rating_weight` - Class method to set the weighting for this rater
|
127
|
-
* `rateable` - Instance method referencing the object being rated
|
128
|
-
* `min_rating` - Instance method returning the minimum rating value
|
129
|
-
* `max_rating` - Instance method returning the maximum rating value
|
143
|
+
* `rating_weight` - `@param [Float]` - Class method to set the weighting for this rater
|
144
|
+
* `rateable` - `@return [Rateable]` - Instance method referencing the object being rated
|
145
|
+
* `min_rating` - `@return [Float]` - Instance method returning the minimum rating value
|
146
|
+
* `max_rating` - `@return [Float]` - Instance method returning the maximum rating value
|
130
147
|
|
131
148
|
For example a basic version could be something like this;
|
132
149
|
|
@@ -135,7 +152,7 @@ class GoreRater < FiveStar.base_rater
|
|
135
152
|
rating_weight 0.4
|
136
153
|
|
137
154
|
def description
|
138
|
-
"
|
155
|
+
"The film #{film.title} has #{film.number_of_swear_words} and was rated at #{rating}"
|
139
156
|
end
|
140
157
|
|
141
158
|
def rating
|
@@ -146,9 +163,9 @@ end
|
|
146
163
|
|
147
164
|
### Rating calculation
|
148
165
|
|
149
|
-
The calculation used will be a weighted average based on each rating and the weighting. If weighting is not required then all will be use the default value and therefore be weighted the same
|
166
|
+
The calculation used will be a weighted average based on each rating and the weighting defined in that class. If weighting is not required then all will be use the default value (of 1.0) and therefore be weighted the same, this being just a normal mean average calculation.
|
150
167
|
|
151
|
-
The
|
168
|
+
The default rating scale used is 0 - 10 as floating point numbers although this can be overriden and customised.
|
152
169
|
|
153
170
|
|
154
171
|
## Development
|
data/five-star.gemspec
CHANGED
data/lib/five-star.rb
CHANGED
@@ -3,12 +3,59 @@ require "five-star/base_rater"
|
|
3
3
|
require "five-star/rateable"
|
4
4
|
require "five-star/rating_calculator"
|
5
5
|
|
6
|
+
# Base module for library interface
|
6
7
|
module FiveStar
|
7
8
|
class << self
|
9
|
+
# Include this in your class that can be rated - this is your domain model
|
10
|
+
# object that has various attributes that you need rated.
|
11
|
+
# Being +rateable+ is defined as an object that has attributes on which a
|
12
|
+
# rating can be calculated based on varying attributes of that model.
|
13
|
+
#
|
14
|
+
# This adds the public class and instance methods from the Rateable module.
|
15
|
+
# See FiveStar::Rateable
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# class Film
|
19
|
+
# include FiveStar.rateable
|
20
|
+
#
|
21
|
+
# rate_with GoreRater, SwearingRater, SexRater
|
22
|
+
# # ...
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# @return [Class]
|
26
|
+
#
|
27
|
+
# @api public
|
8
28
|
def rateable
|
9
29
|
Rateable
|
10
30
|
end
|
11
31
|
|
32
|
+
# The base class of a class that gives a rating and weighting to something
|
33
|
+
# that is rateable. See FiveStar.rateable.
|
34
|
+
#
|
35
|
+
# This implements the interface necessary to calculate a rating for the
|
36
|
+
# rateable instance. At a minium this must be +build+, +rating+,
|
37
|
+
# +description+ and +weighting+.
|
38
|
+
#
|
39
|
+
# The method +build+ *will* be called on each class with the argument of
|
40
|
+
# the instance being rated.
|
41
|
+
# See FiveStar::BaseRater
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# class GoreRater < FiveStar.base_rater
|
45
|
+
# rating_weight 0.4
|
46
|
+
#
|
47
|
+
# def description
|
48
|
+
# "The Film #{film.title} has #{film.number_of_swear_words} and was rated at #{rating}"
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# def rating
|
52
|
+
# # calculate rating somehow
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# @return [Class]
|
57
|
+
#
|
58
|
+
# @api public
|
12
59
|
def base_rater
|
13
60
|
BaseRater
|
14
61
|
end
|
data/lib/five-star/base_rater.rb
CHANGED
@@ -1,29 +1,123 @@
|
|
1
1
|
module FiveStar
|
2
|
+
# Base implementation of a class to give a rating, weighting and description
|
3
|
+
# to a +rateable+ instance.
|
4
|
+
#
|
5
|
+
# Default implementation is defined below, users should override methods
|
6
|
+
# with their own implementation.
|
2
7
|
class BaseRater
|
8
|
+
# Called to build a new instance of the rater with the given object
|
9
|
+
# being rated.
|
10
|
+
#
|
11
|
+
# @param [Object] rateable
|
12
|
+
# the instance of the Object being rated
|
13
|
+
#
|
14
|
+
# @return [Object] the instance created ready to rate
|
15
|
+
#
|
16
|
+
# @api public
|
3
17
|
def self.build(rateable)
|
4
18
|
new(rateable)
|
5
19
|
end
|
6
20
|
|
21
|
+
# Set the weighting for this rating classifcation class. This can be any
|
22
|
+
# valid floating point number at present, the weighting system is up to
|
23
|
+
# the user to ensure correct.
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# class GoreRater < FiveStar.base_rater
|
27
|
+
# rating_weight 0.4
|
28
|
+
# # ...
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# @param [Float] weighting
|
32
|
+
# the weighting value
|
33
|
+
#
|
34
|
+
# @return [undefined]
|
35
|
+
#
|
36
|
+
# @api public
|
7
37
|
def self.rating_weight(weighting)
|
8
38
|
@weighting = weighting
|
9
39
|
end
|
10
40
|
|
41
|
+
# Return the weighting value for this rating classifcation class.
|
42
|
+
#
|
43
|
+
# @return [Float]
|
44
|
+
# the weighting value
|
45
|
+
#
|
46
|
+
# @api public
|
11
47
|
def self.weighting
|
12
48
|
@weighting ||= 1.0
|
13
49
|
end
|
14
50
|
|
51
|
+
# Create a new instance of rater
|
52
|
+
#
|
53
|
+
# @param [Object] rateable
|
54
|
+
# the instance of the Object being rated
|
55
|
+
#
|
56
|
+
# @api private
|
15
57
|
def initialize(rateable)
|
16
58
|
@rateable = rateable
|
17
59
|
end
|
18
60
|
|
61
|
+
# Return the rating description for the rater given to the `rateable`
|
62
|
+
# object.
|
63
|
+
# Override to customise this message.
|
64
|
+
#
|
65
|
+
# @example
|
66
|
+
# class GoreRater < FiveStar.base_rater
|
67
|
+
# rating_weight 0.4
|
68
|
+
#
|
69
|
+
# def description
|
70
|
+
# "The film #{film.title} has #{film.number_of_swear_words} and was rated at #{rating}"
|
71
|
+
# end
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# rater.description # => "The film Alien was rated 8 for gore"
|
75
|
+
#
|
76
|
+
# @return [String] the description
|
77
|
+
#
|
78
|
+
# @api public
|
19
79
|
def description
|
20
|
-
"#{self.class} rated #{
|
80
|
+
"#{self.class} rated #{rateable_name} at #{rating} with weighting of #{weighting}"
|
21
81
|
end
|
22
82
|
|
83
|
+
# Return the rating for the rater given to the `rateable` object.
|
84
|
+
# Override this method to perform your own calculation for the rating based
|
85
|
+
# on your own criteria. If this is an expensive operation then the result
|
86
|
+
# should be cached as this method *can* be called more than once, for
|
87
|
+
# example by the +description+ method.
|
88
|
+
#
|
89
|
+
# @example
|
90
|
+
# class GoreRater < FiveStar.base_rater
|
91
|
+
# rating_weight 0.4
|
92
|
+
#
|
93
|
+
# def rating
|
94
|
+
# # count the pints of blood spilt in the film and return a rating
|
95
|
+
# if film.blood_spilt == :a_lot
|
96
|
+
# 10
|
97
|
+
# elsif film.blood_spilt == :a_little
|
98
|
+
# 5
|
99
|
+
# else
|
100
|
+
# 0
|
101
|
+
# end
|
102
|
+
# end
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
# rater.rating # => 6
|
106
|
+
#
|
107
|
+
# @return [Float] the rating value
|
108
|
+
# defaults to 0 unless overridden
|
109
|
+
#
|
110
|
+
# @api public
|
23
111
|
def rating
|
24
112
|
0
|
25
113
|
end
|
26
114
|
|
115
|
+
# Return the weighting value for this rating classifcation class.
|
116
|
+
#
|
117
|
+
# @return [Float]
|
118
|
+
# the weighting value
|
119
|
+
#
|
120
|
+
# @api public
|
27
121
|
def weighting
|
28
122
|
self.class.weighting
|
29
123
|
end
|
@@ -32,12 +126,38 @@ module FiveStar
|
|
32
126
|
|
33
127
|
attr_reader :rateable
|
34
128
|
|
129
|
+
# Return the maximum weighting value for this rating classifcation class.
|
130
|
+
#
|
131
|
+
# Override if required - this should be the same for each rater class.
|
132
|
+
#
|
133
|
+
# @return [Fixnum]
|
134
|
+
# the maximum rating value.
|
135
|
+
#
|
136
|
+
# @api protected
|
35
137
|
def max_rating
|
36
138
|
10
|
37
139
|
end
|
38
140
|
|
141
|
+
# Return the minimum weighting value for this rating classifcation class.
|
142
|
+
#
|
143
|
+
# Override if required - this should be the same for each rater class.
|
144
|
+
#
|
145
|
+
# @return [Fixnum]
|
146
|
+
# the minimum rating value.
|
147
|
+
#
|
148
|
+
# @api protected
|
39
149
|
def min_rating
|
40
150
|
0
|
41
151
|
end
|
152
|
+
|
153
|
+
# Return the name of the given rateable instance.
|
154
|
+
#
|
155
|
+
# @return [String]
|
156
|
+
# the name of the object being rated.
|
157
|
+
#
|
158
|
+
# @api protected
|
159
|
+
def rateable_name
|
160
|
+
rateable.name
|
161
|
+
end
|
42
162
|
end
|
43
163
|
end
|
data/lib/five-star/rateable.rb
CHANGED
@@ -1,29 +1,105 @@
|
|
1
1
|
module FiveStar
|
2
|
+
# A module to be included to enhance an object with the interface below
|
2
3
|
module Rateable
|
4
|
+
# Extends base class or a module with Rateable methods
|
5
|
+
#
|
6
|
+
# @param [Object] object
|
7
|
+
# the object to mix in this +Rateable+ module
|
8
|
+
#
|
9
|
+
# @return [undefined]
|
10
|
+
#
|
11
|
+
# @api private
|
3
12
|
def self.included(base)
|
4
13
|
base.extend(ClassMethods)
|
5
14
|
end
|
6
15
|
|
7
16
|
module ClassMethods
|
17
|
+
# Set which rating classes will be used to rate the object
|
18
|
+
# using this module.
|
19
|
+
# Each class must implement the rater methods, see FiveStar::BaseRater
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# class Film
|
23
|
+
# include FiveStar.rateable
|
24
|
+
#
|
25
|
+
# rate_with GoreRater, SwearingRater, SexRater
|
26
|
+
# # ...
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# @param [Class] *klasses
|
30
|
+
# constants referencing classes to rate object included with
|
31
|
+
#
|
32
|
+
# @return [undefined]
|
33
|
+
#
|
34
|
+
# @see FiveStar.rateable
|
35
|
+
#
|
36
|
+
# @api public
|
8
37
|
def rate_with(*klasses)
|
9
38
|
@rating_klasses = Array(klasses)
|
10
39
|
end
|
11
40
|
|
41
|
+
# Define which rating classes will be used to rate the object
|
42
|
+
# using this module.
|
43
|
+
#
|
44
|
+
# @return [Array] list of classes to rate with
|
45
|
+
#
|
46
|
+
# @see FiveStar.rateable
|
47
|
+
#
|
48
|
+
# @api private
|
12
49
|
def rating_klasses
|
13
50
|
@rating_klasses ||= []
|
14
51
|
end
|
15
52
|
end
|
16
53
|
|
54
|
+
# Return the rating given to the `rateable` object by calculating based on
|
55
|
+
# set raters and their configuration.
|
56
|
+
#
|
57
|
+
# @example
|
58
|
+
# film = Film.new
|
59
|
+
# film.rating # => 6
|
60
|
+
#
|
61
|
+
# @return [Float] rating calculated by set raters for the object
|
62
|
+
#
|
63
|
+
# @api public
|
17
64
|
def rating
|
18
65
|
rating_calculator.rate(raters)
|
19
66
|
end
|
20
67
|
|
68
|
+
# Return the rating description for each rater given to the `rateable`
|
69
|
+
# object.
|
70
|
+
# These are returned in the order in which the rating classes were
|
71
|
+
# defined in `rate_with`.
|
72
|
+
#
|
73
|
+
# @example
|
74
|
+
# film = Film.new
|
75
|
+
# film.rating_descriptions # => ["The film Alien was rated 8 for gore", ...]
|
76
|
+
#
|
77
|
+
# @return [Array] list of descriptions from each rater
|
78
|
+
#
|
79
|
+
# @api public
|
21
80
|
def rating_descriptions
|
22
81
|
raters.map { |rater| rater.description }
|
23
82
|
end
|
24
83
|
|
84
|
+
# The name of the object that is rateable. This may be used by raters
|
85
|
+
# when generating descriptions.
|
86
|
+
# This can be overridden to provide a better response, otherwise is the class
|
87
|
+
# name.
|
88
|
+
#
|
89
|
+
# @return [String] name of the class
|
90
|
+
#
|
91
|
+
# @api public
|
92
|
+
def name
|
93
|
+
self.class.name
|
94
|
+
end
|
95
|
+
|
25
96
|
protected
|
26
97
|
|
98
|
+
# The instance that included this module
|
99
|
+
#
|
100
|
+
# @return [Object] self
|
101
|
+
#
|
102
|
+
# @api protected
|
27
103
|
def rateable
|
28
104
|
self
|
29
105
|
end
|
@@ -1,4 +1,7 @@
|
|
1
1
|
module FiveStar
|
2
|
+
# Calculate overall rating for the rateable object from each rater.
|
3
|
+
# Each instance must implement `rating` and `weighting`.
|
4
|
+
# @api private
|
2
5
|
class RatingCalculator
|
3
6
|
def self.rate(raters)
|
4
7
|
new(raters).calculate_rating
|
@@ -8,17 +11,27 @@ module FiveStar
|
|
8
11
|
@raters = raters
|
9
12
|
end
|
10
13
|
|
14
|
+
# Calculate the overall weighting from each rating class
|
15
|
+
#
|
16
|
+
# @return [Float] the calculated rating
|
17
|
+
#
|
18
|
+
# @api private
|
11
19
|
def calculate_rating
|
12
20
|
return 0 unless raters.any?
|
13
21
|
|
14
|
-
sum_total = raters.map { |rater| rater.rating * rater.weighting }.inject(&:+)
|
15
|
-
weights_total = raters.map(&:weighting).inject(&:+)
|
16
|
-
|
17
22
|
sum_total / weights_total.to_f
|
18
23
|
end
|
19
24
|
|
20
25
|
private
|
21
26
|
|
22
27
|
attr_reader :raters
|
28
|
+
|
29
|
+
def sum_total
|
30
|
+
raters.map { |rater| rater.rating * rater.weighting }.inject(&:+)
|
31
|
+
end
|
32
|
+
|
33
|
+
def weights_total
|
34
|
+
raters.map(&:weighting).inject(&:+)
|
35
|
+
end
|
23
36
|
end
|
24
37
|
end
|
data/lib/five-star/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: five-star
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Murray
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: byebug
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
description: A Rating system for your Ruby objects; Rate an object with one or more
|
98
112
|
rating classifications.
|
99
113
|
email:
|
@@ -108,7 +122,6 @@ files:
|
|
108
122
|
- CODE_OF_CONDUCT.md
|
109
123
|
- Gemfile
|
110
124
|
- LICENSE
|
111
|
-
- LICENSE.txt
|
112
125
|
- README.md
|
113
126
|
- Rakefile
|
114
127
|
- bin/console
|
data/LICENSE.txt
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
The MIT License (MIT)
|
2
|
-
|
3
|
-
Copyright (c) 2015 Rob Murray
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
7
|
-
in the Software without restriction, including without limitation the rights
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
10
|
-
furnished to do so, subject to the following conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be included in
|
13
|
-
all copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
THE SOFTWARE.
|