learn_together_v2 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +253 -0
- data/Rakefile +6 -0
- data/bin/console +18 -0
- data/bin/seeds.rb +20 -0
- data/bin/setup +8 -0
- data/learn_together.gemspec +34 -0
- data/lib/learn_together/generator.rb +128 -0
- data/lib/learn_together/version.rb +3 -0
- data/lib/learn_together.rb +82 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8caab6125f60c2492ec64f919bcad8d402aeb94e
|
4
|
+
data.tar.gz: ff15a43489af58a30216be67f25e65f4674a35cf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 36ef4d9e9754937790c8abd7ca99cfc7253508ac7986dc42375c81c1bcb9ef5606c1697a3c3439edbd612a78553bf79adcf3ba2a7785e2128455c6c1c72ee2a6
|
7
|
+
data.tar.gz: b01108b137bd20dd87a32a9d777f1dfc5f3bedee4c09ca92837ab9e7faff07352743fc9520899580cc2c6b2a56beb37dd1a705387d30476bc81e4147d826b6fc
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 TODO: Write your name
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,253 @@
|
|
1
|
+
# LearnTogether
|
2
|
+
|
3
|
+
This gem is meant to be used to group Learn student batches into groups for tables, labs and projects.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'learn_together'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install learn_together
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
The Learn Together gem is meant to be used from within another project, like a Rails app. The gem can take in any collection of student-like objects, along with a few specifications, and generate groups of students accordingly.
|
24
|
+
|
25
|
+
#### What's a 'student-like object?'
|
26
|
+
|
27
|
+
The Learn Together gem can take in a collection of objects that respond to a `#completed_lesson_count_for_active_track` method *or* a collection of hashes, each of which has a key of `:completed_lesson_count_for_active_track`.
|
28
|
+
|
29
|
+
This is because the gem can generate groups based on similar progress. The gem uses the total number of completed lessons for a given student's active track as a metric with which to measure progress and thereby sort students.
|
30
|
+
|
31
|
+
#### These student-like objects sound great! Where can I get some?
|
32
|
+
|
33
|
+
You can hit this Learn API endpoint for your batch to retrieve a JSON payload describing Learn students.
|
34
|
+
|
35
|
+
```bash
|
36
|
+
GET http://leanr.co.api/batches/:batch_id/users
|
37
|
+
```
|
38
|
+
|
39
|
+
The payload for each student will include an attribute, `"completed_lesson_count_for_active_track"`. You can either use this data to instantiate `Student` objects of your own, OR, you can simply `JSON.parse` the payload, and pass student-like hashes to the gem.
|
40
|
+
|
41
|
+
*Important:* If you give the gem a collection of student objects, instantiated from student class you yourself defined, then the gem will return to you groups of these student objects. If you give the gem a collection of hashes, each of which describe a student, the gem will return to you groups of these student hashes, sorted/grouped accordingly.
|
42
|
+
|
43
|
+
#### Using the Gem
|
44
|
+
|
45
|
+
Once you have your student collection, you can call the gem with a number of different arguments.
|
46
|
+
|
47
|
+
**Student groups with n number of students, based on progress**
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
LearnTogether::GroupMaker.new.run(collection: <collection of student-like objects>, groups_of: some_number, sort_type: "progress")
|
51
|
+
```
|
52
|
+
|
53
|
+
For example:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
students = Student.all # assuming you have a database full of students with the necessary .completed_lesson_for_active_track attribute
|
57
|
+
|
58
|
+
LearnTogether::GroupMaker.new.run(collection: students, groups_of: 2, sort_type: "progress")
|
59
|
+
```
|
60
|
+
|
61
|
+
returns:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
[[#<Student:0x007fc0a1344450
|
65
|
+
@completed_lesson_count_for_active_track=1,
|
66
|
+
@first_name=nil,
|
67
|
+
@github_username="destany-wintheiser",
|
68
|
+
@last_name=nil>,
|
69
|
+
#<Student:0x007fc0a1344810
|
70
|
+
@completed_lesson_count_for_active_track=1,
|
71
|
+
@first_name=nil,
|
72
|
+
@github_username="rowena-larson",
|
73
|
+
@last_name=nil>],
|
74
|
+
[#<Student:0x007fc0a1344608
|
75
|
+
@completed_lesson_count_for_active_track=2,
|
76
|
+
@first_name=nil, @github_username="nakia", @last_name=nil>,
|
77
|
+
#<Student:0x007fc0a1344798
|
78
|
+
@completed_lesson_count_for_active_track=3,
|
79
|
+
@first_name=nil,
|
80
|
+
@github_username="fletcher-fisher",
|
81
|
+
@last_name=nil>],
|
82
|
+
[#<Student:0x007fc0a13446f8
|
83
|
+
@completed_lesson_count_for_active_track=3,
|
84
|
+
@first_name=nil,
|
85
|
+
@github_username="francesca-bashirian",
|
86
|
+
@last_name=nil>,
|
87
|
+
#<Student:0x007fc0a13448b0
|
88
|
+
@completed_lesson_count_for_active_track=3,
|
89
|
+
@first_name=nil,
|
90
|
+
@github_username="meaghan", @last_name=nil>],
|
91
|
+
[#<Student:0x007fc0a1344c20
|
92
|
+
@completed_lesson_count_for_active_track=4,
|
93
|
+
@first_name=nil, @github_username="keeley",
|
94
|
+
@last_name=nil>,
|
95
|
+
#<Student:0x007fc0a1344478
|
96
|
+
@completed_lesson_count_for_active_track=4,
|
97
|
+
@first_name=nil,
|
98
|
+
@github_username="german", @last_name=nil>],
|
99
|
+
[#<Student:0x007fc0a13447e8
|
100
|
+
@completed_lesson_count_for_active_track=4,
|
101
|
+
@first_name=nil,
|
102
|
+
@github_username="eleazar-beatty",
|
103
|
+
@last_name=nil>,
|
104
|
+
#<Student:0x007fc0a1344950
|
105
|
+
@completed_lesson_count_for_active_track=4,
|
106
|
+
@first_name=nil, @github_username="ivy", @last_name=nil>],
|
107
|
+
[#<Student:0x007fc0a13449f0
|
108
|
+
@completed_lesson_count_for_active_track=4,
|
109
|
+
@first_name=nil, @github_username="ernestina",
|
110
|
+
@last_name=nil>,
|
111
|
+
#<Student:0x007fc0a1344bf8
|
112
|
+
@completed_lesson_count_for_active_track=5,
|
113
|
+
@first_name=nil, @github_username="erling",
|
114
|
+
@last_name=nil>],
|
115
|
+
[#<Student:0x007fc0a1344a40
|
116
|
+
@completed_lesson_count_for_active_track=5,
|
117
|
+
@first_name=nil, @github_username="heloise-toy",
|
118
|
+
@last_name=nil>,
|
119
|
+
#<Student:0x007fc0a13449a0
|
120
|
+
@completed_lesson_count_for_active_track=5,
|
121
|
+
@first_name=nil,
|
122
|
+
@github_username="quinten-botsford",
|
123
|
+
@last_name=nil>],
|
124
|
+
[#<Student:0x007fc0a13444c8
|
125
|
+
@completed_lesson_count_for_active_track=6,
|
126
|
+
@first_name=nil,
|
127
|
+
@github_username="janick-feeney",
|
128
|
+
@last_name=nil>,
|
129
|
+
#<Student:0x007fc0a13446d0
|
130
|
+
@completed_lesson_count_for_active_track=6,
|
131
|
+
@first_name=nil,
|
132
|
+
@github_username="trevor-mcclure",
|
133
|
+
@last_name=nil>],
|
134
|
+
[#<Student:0x007fc0a1344748
|
135
|
+
@completed_lesson_count_for_active_track=7,
|
136
|
+
@first_name=nil, @github_username="maxie-price",
|
137
|
+
@last_name=nil>,
|
138
|
+
#<Student:0x007fc0a1344b30
|
139
|
+
@completed_lesson_count_for_active_track=7,
|
140
|
+
@first_name=nil,
|
141
|
+
@github_username="mable-luettgen",
|
142
|
+
@last_name=nil>],
|
143
|
+
[#<Student:0x007fc0a13449c8
|
144
|
+
@completed_lesson_count_for_active_track=7,
|
145
|
+
@first_name=nil,
|
146
|
+
@github_username="jailyn-okeefe",
|
147
|
+
@last_name=nil>,
|
148
|
+
#<Student:0x007fc0a1344978
|
149
|
+
@completed_lesson_count_for_active_track=7,
|
150
|
+
@first_name=nil, @github_username="yvonne",
|
151
|
+
@last_name=nil>],
|
152
|
+
[#<Student:0x007fc0a1344888
|
153
|
+
@completed_lesson_count_for_active_track=7,
|
154
|
+
@first_name=nil, @github_username="bobby",
|
155
|
+
@last_name=nil>,
|
156
|
+
#<Student:0x007fc0a13444f0
|
157
|
+
@completed_lesson_count_for_active_track=7,
|
158
|
+
@first_name=nil, @github_username="jerrold",
|
159
|
+
@last_name=nil>],
|
160
|
+
[#<Student:0x007fc0a1344590
|
161
|
+
@completed_lesson_count_for_active_track=7,
|
162
|
+
@first_name=nil, @github_username="vivianne",
|
163
|
+
@last_name=nil>,
|
164
|
+
#<Student:0x007fc0a1344428
|
165
|
+
@completed_lesson_count_for_active_track=8,
|
166
|
+
@first_name=nil,
|
167
|
+
@github_username="jaden-wintheiser",
|
168
|
+
@last_name=nil>],
|
169
|
+
[#<Student:0x007fc0a1344b80
|
170
|
+
@completed_lesson_count_for_active_track=8,
|
171
|
+
@first_name=nil, @github_username="obie", @last_name=nil>,
|
172
|
+
#<Student:0x007fc0a1344860
|
173
|
+
@completed_lesson_count_for_active_track=8,
|
174
|
+
@first_name=nil, @github_username="sydnie",
|
175
|
+
@last_name=nil>],
|
176
|
+
[#<Student:0x007fc0a1344770
|
177
|
+
@completed_lesson_count_for_active_track=8,
|
178
|
+
@first_name=nil,
|
179
|
+
@github_username="evelyn-corkery",
|
180
|
+
@last_name=nil>,
|
181
|
+
#<Student:0x007fc0a1344518
|
182
|
+
@completed_lesson_count_for_active_track=8,
|
183
|
+
@first_name=nil, @github_username="ashley",
|
184
|
+
@last_name=nil>],
|
185
|
+
[#<Student:0x007fc0a1344900
|
186
|
+
@completed_lesson_count_for_active_track=9,
|
187
|
+
@first_name=nil, @github_username="carey", @last_name=nil>,
|
188
|
+
#<Student:0x007fc0a1344838
|
189
|
+
@completed_lesson_count_for_active_track=9,
|
190
|
+
@first_name=nil,
|
191
|
+
@github_username="rosina-carter",
|
192
|
+
@last_name=nil>],
|
193
|
+
[#<Student:0x007fc0a1344a18
|
194
|
+
@completed_lesson_count_for_active_track=9,
|
195
|
+
@first_name=nil,
|
196
|
+
@github_username="mose-nikolaus",
|
197
|
+
@last_name=nil>,
|
198
|
+
#<Student:0x007fc0a1344720
|
199
|
+
@completed_lesson_count_for_active_track=10,
|
200
|
+
@first_name=nil,
|
201
|
+
@github_username="aurore-feeney",
|
202
|
+
@last_name=nil>],
|
203
|
+
[#<Student:0x007fc0a1344928
|
204
|
+
@completed_lesson_count_for_active_track=10,
|
205
|
+
@first_name=nil,
|
206
|
+
@github_username="maurice-collier",
|
207
|
+
@last_name=nil>,
|
208
|
+
#<Student:0x007fc0a1344b58
|
209
|
+
@completed_lesson_count_for_active_track=10,
|
210
|
+
@first_name=nil,
|
211
|
+
@github_username="valentin-langworth",
|
212
|
+
@last_name=nil>,
|
213
|
+
#<Student:0x007fc0a13445b8
|
214
|
+
@completed_lesson_count_for_active_track=10,
|
215
|
+
@first_name=nil, @github_username="andreanne",
|
216
|
+
@last_name=nil>]
|
217
|
+
]
|
218
|
+
```
|
219
|
+
|
220
|
+
We can see that the return of the `#run` method is an array of arrays, in which each child array represents one group of students and contains the list of the students in that group. In this case, we assume the original student collection contained 35 students. So, `#run` returned an array of 17 arrays, each of which contains two students, except for the last one, which contains 3 students.
|
221
|
+
|
222
|
+
**Student groups with n number of students, sorted randomly**
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
LearnTogether::GroupMaker.new.run(collection: <collection of student-like objects>, groups_of: some_number, sort_type: "random")
|
226
|
+
```
|
227
|
+
|
228
|
+
For example:
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
students = Student.all # assuming you have a database full of students with the necessary .completed_lesson_for_active_track attribute
|
232
|
+
|
233
|
+
LearnTogether::GroupMaker.new.run(collection: students, groups_of: 3, sort_type: "random")
|
234
|
+
```
|
235
|
+
|
236
|
+
**Students into n number of groups**
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
LearnTogether::GroupMaker.new.run(collection: <collection of student-like objects>, number_of_groups: 3)
|
240
|
+
```
|
241
|
+
|
242
|
+
This will return an array of three smaller arrays, each of which contains the appropriate number of students.
|
243
|
+
|
244
|
+
## Development
|
245
|
+
|
246
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
247
|
+
|
248
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
249
|
+
|
250
|
+
## License
|
251
|
+
|
252
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
253
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "learn_together"
|
5
|
+
require_relative "./seeds.rb"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
require "irb"
|
18
|
+
IRB.start
|
data/bin/seeds.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'faker'
|
2
|
+
class TestStudent
|
3
|
+
attr_accessor :first_name, :last_name, :github_username, :completed_lesson_count_for_active_track
|
4
|
+
|
5
|
+
def initialize(options)
|
6
|
+
@first_name = options["first_name"]
|
7
|
+
@last_name = options["last_name"]
|
8
|
+
@github_username = options["github_username"]
|
9
|
+
@completed_lesson_count_for_active_track = options["completed_lesson_count_for_active_track"]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.fetch_students(num)
|
13
|
+
student_array = []
|
14
|
+
num.times do
|
15
|
+
obj = {"first_name" => Faker::Name.first_name, "last_name" => Faker::Name.last_name, "github_username" => Faker::Name.last_name.downcase, "completed_lesson_count_for_active_track" => rand(1..10)}
|
16
|
+
student_array.push(TestStudent.new(obj))
|
17
|
+
end
|
18
|
+
student_array
|
19
|
+
end
|
20
|
+
end
|
data/bin/setup
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'learn_together/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "learn_together_v2"
|
8
|
+
spec.version = LearnTogether::VERSION
|
9
|
+
spec.authors = ["johann kerr", "sophie debenedetto"]
|
10
|
+
spec.email = ["johannkerr@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{tool for Flatiron School instructors to group students for projects}
|
13
|
+
spec.homepage = "https://github.com/flatiron-school/learn-together-gem"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
17
|
+
# delete this section to allow pushing this gem to any host.
|
18
|
+
if spec.respond_to?(:metadata)
|
19
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org/"
|
20
|
+
else
|
21
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
22
|
+
end
|
23
|
+
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
spec.bindir = "exe"
|
26
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ["lib"]
|
28
|
+
|
29
|
+
spec.add_development_dependency "bundler", "~> 1.11"
|
30
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
31
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
32
|
+
spec.add_development_dependency "pry", "~> 0.10"
|
33
|
+
spec.add_dependency 'activesupport', '~> 5.0'
|
34
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'pry'
|
2
|
+
class Generator
|
3
|
+
attr_accessor :students, :groups_of, :sort_type, :number_of_groups
|
4
|
+
|
5
|
+
def initialize(students:, groups_of: nil, sort_type:, number_of_groups: nil)
|
6
|
+
@students = students
|
7
|
+
@groups_of = groups_of
|
8
|
+
@number_of_groups = number_of_groups
|
9
|
+
@sort_type = sort_type
|
10
|
+
end
|
11
|
+
|
12
|
+
def make_groups
|
13
|
+
if groups_of_n_students?
|
14
|
+
GroupsOfNStudents.new(students: students, groups_of: groups_of, sort_type: sort_type).make_groups
|
15
|
+
elsif n_number_of_groups?
|
16
|
+
NNumberOfGroups.new(students: students, number_of_groups: number_of_groups).make_groups
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def groups_of_n_students?
|
21
|
+
!!groups_of
|
22
|
+
end
|
23
|
+
|
24
|
+
def n_number_of_groups?
|
25
|
+
!!number_of_groups
|
26
|
+
end
|
27
|
+
|
28
|
+
class GroupsOfNStudents
|
29
|
+
|
30
|
+
attr_accessor :groups_of, :sort_type, :students, :final_groups, :number_of_groups
|
31
|
+
|
32
|
+
def initialize(students:, groups_of:, sort_type:)
|
33
|
+
@students = students
|
34
|
+
@groups_of = groups_of
|
35
|
+
@sort_type = sort_type
|
36
|
+
@final_groups = []
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def make_groups
|
41
|
+
if sort_by_random?
|
42
|
+
form_random_groups
|
43
|
+
elsif sort_by_progress?
|
44
|
+
form_progress_based_groups
|
45
|
+
end
|
46
|
+
final_groups
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
def sort_by_random?
|
51
|
+
sort_type == "random"
|
52
|
+
end
|
53
|
+
|
54
|
+
def sort_by_progress?
|
55
|
+
sort_type == "progress"
|
56
|
+
end
|
57
|
+
|
58
|
+
def form_random_groups
|
59
|
+
students.shuffle.each_slice(groups_of.to_i) { |students| final_groups << students }
|
60
|
+
check_student_distribution
|
61
|
+
end
|
62
|
+
|
63
|
+
def form_progress_based_groups
|
64
|
+
students.sort_by {|s| s.completed_lesson_count_for_active_track}.each_slice(groups_of.to_i) { |students| final_groups << students }
|
65
|
+
check_student_distribution
|
66
|
+
end
|
67
|
+
|
68
|
+
def check_student_distribution
|
69
|
+
if leftover_students?
|
70
|
+
leftover_val = students.length % groups_of.to_i
|
71
|
+
if leftover_val == 1
|
72
|
+
student = final_groups.pop.first
|
73
|
+
final_groups.last << student
|
74
|
+
elsif leftover_val == groups_of.to_i / 2
|
75
|
+
final_groups.pop.each_with_index do |student, i|
|
76
|
+
final_groups["-#{i + 1}".to_i] << student
|
77
|
+
end
|
78
|
+
end
|
79
|
+
else
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def leftover_students?
|
84
|
+
students.length % groups_of.to_i > 0
|
85
|
+
end
|
86
|
+
|
87
|
+
def leftover_students
|
88
|
+
students.length % groups_of.to_i <= (groups_of.to_i - 2) || students.length % groups_of.to_i == 1
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class NNumberOfGroups
|
93
|
+
attr_accessor :students, :number_of_groups, :students_per_group, :final_groups
|
94
|
+
|
95
|
+
def initialize(students:, number_of_groups:)
|
96
|
+
@students = students
|
97
|
+
@number_of_groups = number_of_groups
|
98
|
+
@final_groups = []
|
99
|
+
end
|
100
|
+
|
101
|
+
def make_groups
|
102
|
+
make_initial_distribution
|
103
|
+
adjust_distribution
|
104
|
+
final_groups
|
105
|
+
end
|
106
|
+
|
107
|
+
def students_per_group
|
108
|
+
@students_per_group = students.length / number_of_groups
|
109
|
+
end
|
110
|
+
|
111
|
+
def make_initial_distribution
|
112
|
+
students.each_slice(students_per_group) do |slice|
|
113
|
+
final_groups << slice
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def adjust_distribution
|
118
|
+
if final_groups.last.size < students_per_group && final_groups.length > number_of_groups
|
119
|
+
final_groups.pop.each_with_index do |remaining_student, i|
|
120
|
+
final_groups[i] << remaining_student
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require "learn_together/version"
|
3
|
+
require 'learn_together/generator'
|
4
|
+
require 'active_support/core_ext/hash'
|
5
|
+
|
6
|
+
module LearnTogether
|
7
|
+
class GroupMaker
|
8
|
+
VALID_ARGS = {
|
9
|
+
valid_keys: ["groups_of", "collection", "sort_type", "number_of_groups"],
|
10
|
+
sort_type: ["random", "progress"]
|
11
|
+
}
|
12
|
+
|
13
|
+
attr_accessor :options
|
14
|
+
|
15
|
+
def run(options)
|
16
|
+
@options = ActiveSupport::HashWithIndifferentAccess.new(options)
|
17
|
+
validate_args
|
18
|
+
students = Student.new(options[:collection]).generate_batch_students
|
19
|
+
generator = Generator.new(students: students, groups_of: options[:groups_of], number_of_groups: options[:number_of_groups], sort_type: options[:sort_type])
|
20
|
+
generator.make_groups
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate_args
|
24
|
+
(has_valid_keys? && has_valid_values?) ? true : (raise GroupMakerArgError.new)
|
25
|
+
end
|
26
|
+
|
27
|
+
def has_valid_keys?
|
28
|
+
options.keys.all? {|key| VALID_ARGS[:valid_keys].include?(key)}
|
29
|
+
end
|
30
|
+
|
31
|
+
def has_valid_values?
|
32
|
+
if options["sort_type"]
|
33
|
+
if VALID_ARGS[:sort_type].include?(options["sort_type"])
|
34
|
+
true
|
35
|
+
else
|
36
|
+
false
|
37
|
+
end
|
38
|
+
else
|
39
|
+
true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class GroupMakerArgError < StandardError
|
45
|
+
def initialize(msg="must pass arguments of: student collection, groups_of (i.e. groups_of: 4), sort_type (i.e. sort_type: 'random') OR student collection and number of groups (i.e. number_of_groups: 3)")
|
46
|
+
super
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Student
|
51
|
+
attr_accessor :collection
|
52
|
+
|
53
|
+
def initialize(collection)
|
54
|
+
@collection = collection
|
55
|
+
end
|
56
|
+
|
57
|
+
def generate_batch_students
|
58
|
+
if student_hash_type
|
59
|
+
return collection.collect {|s| OpenStruct.new(s)}
|
60
|
+
elsif student_instance_object_type
|
61
|
+
return collection
|
62
|
+
else
|
63
|
+
raise StudentTypeError.new
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def student_hash_type
|
68
|
+
collection.first.is_a?(Hash) && (collection.first.keys.include?("completed_lesson_count_for_active_track" || :completed_lesson_count_for_active_track))
|
69
|
+
end
|
70
|
+
|
71
|
+
def student_instance_object_type
|
72
|
+
collection.first.respond_to?(:completed_lesson_count_for_active_track)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class StudentTypeError < StandardError
|
77
|
+
def initialize(msg="student collection must contain student objects that respond to a #completed_lesson_count_for_active_track method or have a key of :completed_lesson_count_for_active_track_count")
|
78
|
+
super
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: learn_together_v2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- johann kerr
|
8
|
+
- sophie debenedetto
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2018-02-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.11'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.11'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '10.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '10.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '3.0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '3.0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: pry
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0.10'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.10'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: activesupport
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '5.0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '5.0'
|
84
|
+
description:
|
85
|
+
email:
|
86
|
+
- johannkerr@gmail.com
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- ".rspec"
|
93
|
+
- ".travis.yml"
|
94
|
+
- Gemfile
|
95
|
+
- LICENSE.txt
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- bin/console
|
99
|
+
- bin/seeds.rb
|
100
|
+
- bin/setup
|
101
|
+
- learn_together.gemspec
|
102
|
+
- lib/learn_together.rb
|
103
|
+
- lib/learn_together/generator.rb
|
104
|
+
- lib/learn_together/version.rb
|
105
|
+
homepage: https://github.com/flatiron-school/learn-together-gem
|
106
|
+
licenses:
|
107
|
+
- MIT
|
108
|
+
metadata:
|
109
|
+
allowed_push_host: https://rubygems.org/
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.6.14
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: tool for Flatiron School instructors to group students for projects
|
130
|
+
test_files: []
|