chorewheel 0.0.1

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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZDBhZjI3YmVlMzRhZjNhNDcyZDliYzkxNTViNTU0OTQwM2U0YzE3NQ==
5
+ data.tar.gz: !binary |-
6
+ MmNiMTkxZmFlN2Q5M2EyNjg3NWVhODJhZTUyMTE1NjBiMTBhNjJhNw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NGQ0YWM0NzA4ZTFmNzc3YjNhOTEwM2Q0NzI2YmY1MDMzZWUyMmQxZTJlYjRi
10
+ MDJkZjQyYTQ3NWNjZmZmYzRkYWE1NTIwMTc3OTMzYzQyNWIyMzk3ZDdjOGQ5
11
+ ZTVjYTQwZTg3MDhlMjU2YTBiZjdmMDk2MDhiNjczNTQ4ZDhkODc=
12
+ data.tar.gz: !binary |-
13
+ MDhiN2E5ZDY2YTQ5NzA5ODM5ZWM5MjE5NmU0NTA2ZjViNGE2YzUxZmY3NWVh
14
+ OTQ1M2Q2ZmM0NjQxOGM0MmMzY2I4YzFlMDA0NjkyNzAxNzc0ODRiOWQ1YmIw
15
+ YmQ4ZDA4ZTA0MWEzYzM2Y2RhMWFiNWQ0MDQwM2Q4MDcwOTUzY2M=
File without changes
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "contracts", "~> 0.11.0"
6
+
7
+ group :test do
8
+ gem "rspec"
9
+ gem "rubocop", "~> 0.29.1", :platform => [:ruby_20, :ruby_21, :ruby_22]
10
+ end
11
+
12
+ group :development do
13
+ gem "rake"
14
+ end
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Aditya Bhargava
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.
22
+
23
+
@@ -0,0 +1,5 @@
1
+ # chorewheel
2
+
3
+ ![travis-ci](https://travis-ci.org/egonSchiele/chorewheel.svg)
4
+
5
+ Simple chore scheduler in Ruby.
@@ -0,0 +1,5 @@
1
+ task :default => [:spec]
2
+
3
+ # you can do `rake rubocop` as well
4
+ require "rspec/core/rake_task"
5
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1 @@
1
+ - extra chore i.e. person X needs to make up an extra day of chores
@@ -0,0 +1,11 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "chorewheel"
3
+ s.version = "0.0.1"
4
+ s.summary = "Simple chore scheduler in Ruby."
5
+ s.description = "Make a chore wheel, with options for specifying multiple people, vacation days, etc."
6
+ s.author = "Aditya Bhargava"
7
+ s.email = "bluemangroupie@gmail.com"
8
+ s.files = `git ls-files`.split("\n")
9
+ s.homepage = "http://github.com/egonSchiele/chorewheel"
10
+ s.add_dependency("contracts", "~> 0.11")
11
+ end
@@ -0,0 +1,168 @@
1
+ # A chore schedule takes place over a timespan.
2
+ # In intervals.
3
+ # And it is done by some people.
4
+
5
+ require "util"
6
+ require "contracts"
7
+ require "timespan"
8
+ require "interval"
9
+ include Contracts
10
+
11
+ class ChoreWheel
12
+ GenericString = Or[String, Symbol]
13
+ attr_accessor :workers_per_shift, :people, :timespan, :interval
14
+ def initialize people, timespan, interval, opts = {}
15
+ unless people.is_a?(Array)
16
+ people = [people]
17
+ end
18
+ @people = people
19
+ @timespan = timespan
20
+ @interval = interval
21
+ @workers_per_shift = opts[:workers_per_shift] || 1
22
+ create
23
+ end
24
+
25
+ Contract Hash
26
+ def chunks
27
+ @chunks ||= make_chunks @timespan, @interval
28
+ @chunks
29
+ end
30
+
31
+ def chunks= c
32
+ @chunks = c
33
+ end
34
+
35
+ def map &blk
36
+ arr = []
37
+ chunks.values.map do |val|
38
+ arr << blk.call[val]
39
+ end
40
+ arr
41
+ end
42
+
43
+ Contract ArrayOf[String]
44
+ def shifts
45
+ chunks.keys
46
+ end
47
+
48
+ Contract ArrayOf[ArrayOf[GenericString]]
49
+ def workers
50
+ chunks.values
51
+ end
52
+
53
+ Contract ArrayOf[[String, ArrayOf[GenericString]]]
54
+ def to_a
55
+ chunks.to_a
56
+ end
57
+
58
+ def each &blk
59
+ chunks.values.each do |val|
60
+ blk.call(val)
61
+ end
62
+ self
63
+ end
64
+
65
+ def set_each &blk
66
+ chunks.each do |key, val|
67
+ chunks[key] = blk.call key
68
+ end
69
+ self
70
+ end
71
+
72
+ def count &blk
73
+ counter = 0
74
+ chunks.each do |key, val|
75
+ result = blk.call key, val
76
+ counter += 1 if result
77
+ end
78
+ counter
79
+ end
80
+
81
+ Contract Timespan::WEEK, Interval::WEEKDAY => Hash
82
+ def make_chunks timespan, interval
83
+ make_hash weekdays
84
+ end
85
+
86
+ Contract Timespan::WEEK, Interval::DAY => Hash
87
+ def make_chunks timespan, interval
88
+ make_hash days
89
+ end
90
+
91
+ Contract Timespan::WEEK, Interval::SPECIFIC_DAYS => Hash
92
+ def make_chunks timespan, interval
93
+ hash = {}
94
+ interval.days.each do |day|
95
+ hash[day] = nil
96
+ end
97
+ hash
98
+ end
99
+
100
+ Contract Timespan::MONTH, Interval::DAY => Hash
101
+ def make_chunks timespan, interval
102
+ hash = {}
103
+ start = timespan.start_date
104
+ (start...start.next_month).each do |date|
105
+ hash[date.to_s] = nil
106
+ end
107
+ hash
108
+ end
109
+
110
+ Contract Timespan::MONTH, Interval::WEEKDAY => Hash
111
+ def make_chunks timespan, interval
112
+ hash = make_chunks(timespan, Interval::DAY)
113
+ # delete sundays and saturdays
114
+ hash.delete_if do |key, _|
115
+ [0, 6].include?(Date.parse(key).wday)
116
+ end
117
+ end
118
+
119
+ Contract Timespan::MONTH, Interval::SPECIFIC_DAYS => Hash
120
+ def make_chunks timespan, interval
121
+ hash = make_chunks(timespan, Interval::DAY)
122
+ hash.delete_if do |key, _|
123
+ !interval.days.include?(Date.parse(key).strftime("%A").downcase)
124
+ end
125
+ end
126
+
127
+ Contract Any, Any => Any
128
+ def make_chunks timespan, interval
129
+ fail "don't know how to make timespan with timespan type #{timespan} and interval type #{interval}"
130
+ end
131
+
132
+ def create
133
+ i = 0
134
+ _people = people.dup.shuffle
135
+ set_each do
136
+ workers = []
137
+ workers_per_shift.times do
138
+ if i >= _people.size
139
+ i = 0
140
+ _people.shuffle!
141
+ end
142
+ workers << _people[i]
143
+ i += 1
144
+ end
145
+ workers
146
+ end
147
+ end
148
+
149
+ def to_hash
150
+ {
151
+ "people" => people,
152
+ "timespan" => timespan,
153
+ "interval" => interval,
154
+ "workers_per_shift" => workers_per_shift,
155
+ "chunks" => chunks
156
+ }
157
+ end
158
+
159
+ def self.from_hash hash
160
+ cw = ChoreWheel.new(hash["people"], hash["timespan"], hash["interval"], {:workers_per_shift => hash["workers_per_shift"]})
161
+ cw.chunks = hash["chunks"]
162
+ cw
163
+ end
164
+
165
+ def ==(other)
166
+ to_hash == other.to_hash
167
+ end
168
+ end
@@ -0,0 +1,22 @@
1
+ require "contracts"
2
+ include Contracts
3
+
4
+ class Interval
5
+ DAY = :day
6
+ WEEKDAY = :weekday
7
+ WEEK = :week
8
+ MONTH = :month
9
+ YEAR = :year
10
+
11
+ class SPECIFIC_DAYS
12
+ attr_accessor :days
13
+
14
+ Contract ArrayOf[String] => Any
15
+ def initialize days
16
+ @days = days
17
+ end
18
+ def inspect
19
+ days.inspect
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ class Person
2
+ def initialize name
3
+ @name = name
4
+ end
5
+ end
@@ -0,0 +1,21 @@
1
+ # Essentially an ordered hash.
2
+ # Ruby 1.9 hashes are all ordered.
3
+ require "util"
4
+ require "interval"
5
+ require "contracts"
6
+ require "date"
7
+ include Contracts
8
+
9
+ class Timespan
10
+ WEEK = :week
11
+ YEAR = :year
12
+
13
+ class MONTH
14
+ attr_accessor :start_date
15
+
16
+ Contract Date => Any
17
+ def initialize start_date
18
+ @start_date = start_date
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ def weekdays
2
+ ["monday", "tuesday", "wednesday", "thursday", "friday"]
3
+ end
4
+
5
+ def days
6
+ ["sunday"] + weekdays + ["saturday"]
7
+ end
8
+
9
+ def make_hash keys
10
+ hash = {}
11
+ keys.each do |key|
12
+ hash[key] = nil
13
+ end
14
+ hash
15
+ end
16
+
17
+ # infinitely keep yielding
18
+ # elements of the array, starting
19
+ # from the beginning when you are at the end
20
+ def cycle arr
21
+ while true
22
+ arr.each do |elem|
23
+ yield elem
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,145 @@
1
+ require "date"
2
+
3
+ RSpec.describe "ChoreWheel" do
4
+ describe "chunks" do
5
+ it "should make chunks for week/day" do
6
+ t = ChoreWheel.new(:adit, Timespan::WEEK, Interval::DAY)
7
+ expect(t.shifts).to eq(days)
8
+ end
9
+
10
+ it "should make chunks for week/weekday" do
11
+ t = ChoreWheel.new(:adit, Timespan::WEEK, Interval::WEEKDAY)
12
+ expect(t.shifts).to eq(weekdays)
13
+ end
14
+
15
+ it "should make chunks for week/specific_days" do
16
+ t = ChoreWheel.new(:adit, Timespan::WEEK, Interval::SPECIFIC_DAYS.new(["tuesday", "thursday", "friday"]))
17
+ expect(t.shifts).to eq(["tuesday", "thursday", "friday"])
18
+ end
19
+
20
+ describe "chunks for months" do
21
+ before :each do
22
+ @month = Timespan::MONTH.new(Date.strptime("2015-09-01", "%Y-%m-%d"))
23
+ end
24
+
25
+ it "should make chunks for month/days" do
26
+ t = ChoreWheel.new(:adit, @month, Interval::DAY)
27
+ expect(t.shifts).to eq(["2015-09-01", "2015-09-02", "2015-09-03", "2015-09-04", "2015-09-05", "2015-09-06", "2015-09-07", "2015-09-08", "2015-09-09", "2015-09-10", "2015-09-11", "2015-09-12", "2015-09-13", "2015-09-14", "2015-09-15", "2015-09-16", "2015-09-17", "2015-09-18", "2015-09-19", "2015-09-20", "2015-09-21", "2015-09-22", "2015-09-23", "2015-09-24", "2015-09-25", "2015-09-26", "2015-09-27", "2015-09-28", "2015-09-29", "2015-09-30"])
28
+ end
29
+
30
+ it "should make chunks for month/weekdays" do
31
+ t = ChoreWheel.new(:adit, @month, Interval::WEEKDAY)
32
+ expect(t.shifts).to eq(["2015-09-01", "2015-09-02", "2015-09-03", "2015-09-04", "2015-09-07", "2015-09-08", "2015-09-09", "2015-09-10", "2015-09-11", "2015-09-14", "2015-09-15", "2015-09-16", "2015-09-17", "2015-09-18", "2015-09-21", "2015-09-22", "2015-09-23", "2015-09-24", "2015-09-25", "2015-09-28", "2015-09-29", "2015-09-30"])
33
+ end
34
+
35
+ it "should make chunks for month/specific days" do
36
+ t = ChoreWheel.new(:adit, @month, Interval::SPECIFIC_DAYS.new(["tuesday", "thursday", "friday"]))
37
+ expect(t.shifts).to eq(["2015-09-01", "2015-09-03", "2015-09-04", "2015-09-08", "2015-09-10", "2015-09-11", "2015-09-15", "2015-09-17", "2015-09-18", "2015-09-22", "2015-09-24", "2015-09-25", "2015-09-29"])
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "interface" do
43
+ before :each do
44
+ @t = ChoreWheel.new(:adit, Timespan::WEEK, Interval::WEEKDAY)
45
+ end
46
+
47
+ it "to_a" do
48
+ expect(@t.to_a).to eq([["monday", [:adit]], ["tuesday", [:adit]], ["wednesday", [:adit]], ["thursday", [:adit]], ["friday", [:adit]]])
49
+ end
50
+
51
+ it "shifts" do
52
+ expect(@t.shifts).to eq(weekdays)
53
+ end
54
+
55
+ it "workers" do
56
+ expect(@t.workers).to eq([[:adit], [:adit], [:adit], [:adit], [:adit]])
57
+ end
58
+ end
59
+
60
+ describe "create" do
61
+ people = [
62
+ [:adit],
63
+ [:adit, :maggie]
64
+ ]
65
+
66
+ specific_days = Interval::SPECIFIC_DAYS.new(["tuesday", "thursday", "friday"])
67
+
68
+ create_args = [
69
+ [Timespan::WEEK, Interval::DAY],
70
+ [Timespan::WEEK, Interval::WEEKDAY],
71
+ [Timespan::WEEK, specific_days]
72
+ ]
73
+
74
+ expected_shifts = {
75
+ [Timespan::WEEK, Interval::DAY] => ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"],
76
+ [Timespan::WEEK, Interval::WEEKDAY] => ["monday", "tuesday", "wednesday", "thursday", "friday"],
77
+ [Timespan::WEEK, specific_days] => ["tuesday", "thursday", "friday"]
78
+ }
79
+
80
+ people.each do |persons|
81
+ create_args.each do |args|
82
+ it "should create timespan for #{args} and #{persons}" do
83
+ cw = ChoreWheel.new(persons, *args)
84
+ expect(cw.shifts).to eq(expected_shifts[args])
85
+
86
+ check_even_distribution(cw)
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "workers_per_shift" do
93
+ before :each do
94
+ @cw = ChoreWheel.new([:adit, :maggie], Timespan::WEEK, Interval::WEEKDAY, {:workers_per_shift => 2})
95
+ end
96
+ it "should assign 2 workers per shift" do
97
+ @cw.workers.each do |arr|
98
+ expect(arr.size).to eq(2)
99
+ end
100
+ end
101
+
102
+ it "should assign the shifts evenly" do
103
+ check_even_distribution(@cw)
104
+ end
105
+ end
106
+
107
+ describe "hash" do
108
+ it "should convert to json correctly" do
109
+ cw = ChoreWheel.new([:adit, :maggie], Timespan::WEEK, Interval::DAY, {:workers_per_shift => 2})
110
+ chunks = cw.chunks
111
+
112
+ expected = {
113
+ "people" => [:adit, :maggie],
114
+ "timespan" => Timespan::WEEK,
115
+ "interval" => Interval::DAY,
116
+ "workers_per_shift" => 2,
117
+ "chunks" => chunks
118
+ }
119
+
120
+ expect(cw.to_hash).to eq(expected)
121
+ end
122
+
123
+ it "should convert from json correctly" do
124
+ cw = ChoreWheel.new([:adit, :maggie], Timespan::WEEK, Interval::DAY, {:workers_per_shift => 2})
125
+ chunks = cw.chunks
126
+
127
+ hash = cw.to_hash
128
+
129
+ cw2 = ChoreWheel.from_hash hash
130
+
131
+ expect(cw2.people).to eq([:adit, :maggie])
132
+ expect(cw2.timespan).to eq(Timespan::WEEK)
133
+ expect(cw2.interval).to eq(Interval::DAY)
134
+ expect(cw2.workers_per_shift).to eq(2)
135
+ expect(cw2.chunks).to eq(chunks)
136
+ end
137
+
138
+ it "should convert back and forth correctly" do
139
+ cw = ChoreWheel.new([:adit, :maggie], Timespan::WEEK, Interval::DAY, {:workers_per_shift => 2})
140
+ hash = cw.to_hash
141
+ cw2 = ChoreWheel.from_hash hash
142
+ expect(cw).to eq(cw2)
143
+ end
144
+ end
145
+ end
File without changes
@@ -0,0 +1,122 @@
1
+ require "timespan"
2
+ require "interval"
3
+ require "chorewheel"
4
+ require File.expand_path(File.join(__FILE__, "../support"))
5
+ require File.expand_path(File.join(__FILE__, "../fixtures/fixtures"))
6
+
7
+ # This file was generated by the `rspec --init` command. Conventionally, all
8
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
9
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
10
+ # file to always be loaded, without a need to explicitly require it in any files.
11
+ #
12
+ # Given that it is always loaded, you are encouraged to keep this file as
13
+ # light-weight as possible. Requiring heavyweight dependencies from this file
14
+ # will add to the boot time of your test suite on EVERY test run, even for an
15
+ # individual file that may not need all of that loaded. Instead, consider making
16
+ # a separate helper file that requires the additional dependencies and performs
17
+ # the additional setup, and require it from the spec files that actually need it.
18
+ #
19
+ # The `.rspec` file also contains a few flags that are not defaults but that
20
+ # users commonly want.
21
+ #
22
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
23
+ RSpec.configure do |config|
24
+ config.pattern = "*.rb"
25
+
26
+ # Only load tests who's syntax is valid in the current Ruby
27
+ [1.9, 2.0, 2.1].each do |ver|
28
+ config.pattern << ",ruby_version_specific/*#{ver}.rb" if ruby_version >= ver
29
+ end
30
+
31
+ # rspec-expectations config goes here. You can use an alternate
32
+ # assertion/expectation library such as wrong or the stdlib/minitest
33
+ # assertions if you prefer.
34
+ config.expect_with :rspec do |expectations|
35
+ # This option will default to `true` in RSpec 4. It makes the `description`
36
+ # and `failure_message` of custom matchers include text for helper methods
37
+ # defined using `chain`, e.g.:
38
+ # be_bigger_than(2).and_smaller_than(4).description
39
+ # # => "be bigger than 2 and smaller than 4"
40
+ # ...rather than:
41
+ # # => "be bigger than 2"
42
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
43
+ end
44
+
45
+ # rspec-mocks config goes here. You can use an alternate test double
46
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
47
+ config.mock_with :rspec do |mocks|
48
+ # Prevents you from mocking or stubbing a method that does not exist on
49
+ # a real object. This is generally recommended, and will default to
50
+ # `true` in RSpec 4.
51
+ mocks.verify_partial_doubles = true
52
+ end
53
+
54
+ # These two settings work together to allow you to limit a spec run
55
+ # to individual examples or groups you care about by tagging them with
56
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
57
+ # get run.
58
+ config.filter_run :focus
59
+ config.run_all_when_everything_filtered = true
60
+
61
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
62
+ # For more details, see:
63
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
64
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
65
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
66
+ config.disable_monkey_patching!
67
+
68
+ # This setting enables warnings. It's recommended, but in some cases may
69
+ # be too noisy due to issues in dependencies.
70
+ # config.warnings = true
71
+
72
+ # Many RSpec users commonly either run the entire suite or an individual
73
+ # file, and it's useful to allow more verbose output when running an
74
+ # individual spec file.
75
+ if config.files_to_run.one?
76
+ # Use the documentation formatter for detailed output,
77
+ # unless a formatter has already been configured
78
+ # (e.g. via a command-line flag).
79
+ config.default_formatter = "doc"
80
+ end
81
+
82
+ # Print the 10 slowest examples and example groups at the
83
+ # end of the spec run, to help surface which specs are running
84
+ # particularly slow.
85
+ config.profile_examples = 10
86
+
87
+ # Run specs in random order to surface order dependencies. If you find an
88
+ # order dependency and want to debug it, you can fix the order by providing
89
+ # the seed, which is printed after each run.
90
+ # --seed 1234
91
+ # Unable to use it now
92
+ config.order = :random
93
+
94
+ # Seed global randomization in this process using the `--seed` CLI option.
95
+ # Setting this allows you to use `--seed` to deterministically reproduce
96
+ # test failures related to randomization by passing the same `--seed` value
97
+ # as the one that triggered the failure.
98
+ Kernel.srand config.seed
99
+
100
+ # Callbacks
101
+ config.after :each do
102
+ ::Contract.restore_failure_callback
103
+ end
104
+ end
105
+
106
+ def check_even_distribution cw
107
+ # get the number of shifts for each person
108
+ shifts = cw.people.map do |name|
109
+ cw.count do |shift, workers|
110
+ workers.include?(name)
111
+ end
112
+ end
113
+
114
+ # each person should have not more than 1 away from the avg number of shifts
115
+ avg = shifts.inject(:+) / shifts.size.to_f
116
+
117
+ cw.people.zip(shifts).each do |name, shift|
118
+ if (shift - avg).abs > 1
119
+ raise "Person #{name} is doing #{shift} shifts, but the average is #{avg}."
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,3 @@
1
+ def ruby_version
2
+ RUBY_VERSION.match(/\d+\.\d+/)[0].to_f
3
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chorewheel
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Aditya Bhargava
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: contracts
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0.11'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '0.11'
27
+ description: Make a chore wheel, with options for specifying multiple people, vacation
28
+ days, etc.
29
+ email: bluemangroupie@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - .gitignore
35
+ - .rspec
36
+ - .rubocop.yml
37
+ - .travis.yml
38
+ - CHANGELOG.markdown
39
+ - Gemfile
40
+ - LICENSE
41
+ - README.md
42
+ - Rakefile
43
+ - TODO.markdown
44
+ - chorewheel.gemspec
45
+ - lib/chorewheel.rb
46
+ - lib/interval.rb
47
+ - lib/person.rb
48
+ - lib/timespan.rb
49
+ - lib/util.rb
50
+ - spec/chorewheel_spec.rb
51
+ - spec/fixtures/fixtures.rb
52
+ - spec/spec_helper.rb
53
+ - spec/support.rb
54
+ homepage: http://github.com/egonSchiele/chorewheel
55
+ licenses: []
56
+ metadata: {}
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubyforge_project:
73
+ rubygems_version: 2.4.8
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: Simple chore scheduler in Ruby.
77
+ test_files: []