hardbap (owner)

Forks

Revisions

gist: 168603 Download_button fork
public
Public Clone URL: git://gist.github.com/168603.git
Embed All Files: show embed
and the winners are... #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Gabe da Silveira has won $100-off coupon code for any public Purple Workshops workshop from Jeff Cohen
Brendan Schwartz has won Developing Facebook Platform Applications with Rails from Mike Mangino
Dmitry Ratnikov has won Rails Rescue Handbook from Mike Gunderloy
Hugo Peixoto has won Rails Freelancing Handbook from Mike Gunderloy
Jatinder Singh has won Copy #1: Rails Test Prescriptions from Noel Rappin
Nikolay Petrachkov has won Copy #2: Rails Test Prescriptions from Noel Rappin
Morgan Schweers has won Signed copy of Ruby in Practice from Jeremy McAnally
Adam Keys has won $100 credit at Prgmr (VPS hosting) from Luke Crawford
Jatinder Singh has won Copy #1: 1yr Lighthouse (bronze) from ENTP
Elise Huard has won Copy #2: 1yr Lighthouse (bronze) from ENTP
Rizwan Reza has won Copy #3: 1yr Lighthouse (bronze) from ENTP
Arthur Zapparoli has won Copy #1: 1yr Tender Support (plus) from ENTP
Cristi Balan has won Copy #2: 1yr Tender Support (plus) from ENTP
Jaime Bellmyer has won Copy #3: 1yr Tender Support (plus) from ENTP
Roy Nicholson has won 1 month (4 hours) of Developer Hotline support from ActionRails
Josh Nichols has won Copy #1: $200 VPS hosting credits from RimuHosting
Marshall Huss has won Copy #2: $200 VPS hosting credits from RimuHosting
Jordan Brough has won Copy #3: $200 VPS hosting credits from RimuHosting
Jaime Bellmyer has won 1-year Mini plan in the prize pool from Exceptional
Jeff Dean has won Copy #1: Beta invite from Devver
railsbob has won Copy #2: Beta invite from Devver
Hugo Peixoto has won Copy #3: Beta invite from Devver
Rizwan Reza has won $100 hosting credit from Slicehost
Leonardo Borges has won Copy #1: one-year Medium account from GitHub
bastilian has won Copy #2: one-year Medium account from GitHub
Dan Croak has won Copy #3: one-year Medium account from GitHub
Josh Sharpe has won Two months of gold service from Uservoice
Rob has won Ten hours of free design work on any project from Sterling Rose Design
 
bugmash_lottery.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# thanks to Eric Davis for the base lottery code http://gist.github.com/164109
require 'ostruct'
 
class BugMashLottery
  PRIZE_LIMIT = 2
 
  attr_accessor :tickets
 
  # http://wiki.railsbridge.org/projects/railsbridge/wiki/BugMash
  def prizes
    [
     OpenStruct.new(:sponsor => "Jeff Cohen", :prize => "$100-off coupon code for any public Purple Workshops workshop"),
     OpenStruct.new(:sponsor => "Mike Mangino", :prize => "Developing Facebook Platform Applications with Rails"),
     OpenStruct.new(:sponsor => "Mike Gunderloy", :prize => "Rails Rescue Handbook"),
     OpenStruct.new(:sponsor => "Mike Gunderloy", :prize => "Rails Freelancing Handbook"),
     OpenStruct.new(:sponsor => "Noel Rappin", :prize => "Copy #1: Rails Test Prescriptions"),
     OpenStruct.new(:sponsor => "Noel Rappin", :prize => "Copy #2: Rails Test Prescriptions"),
     OpenStruct.new(:sponsor => "Jeremy McAnally", :prize => "Signed copy of Ruby in Practice"),
     OpenStruct.new(:sponsor => "Luke Crawford", :prize => "$100 credit at Prgmr (VPS hosting)"),
     OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #1: 1yr Lighthouse (bronze)"),
     OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #2: 1yr Lighthouse (bronze)"),
     OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #3: 1yr Lighthouse (bronze)"),
     OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #1: 1yr Tender Support (plus)"),
     OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #2: 1yr Tender Support (plus)"),
     OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #3: 1yr Tender Support (plus)"),
     OpenStruct.new(:sponsor => "ActionRails", :prize => "1 month (4 hours) of Developer Hotline support"),
     OpenStruct.new(:sponsor => "RimuHosting", :prize => "Copy #1: $200 VPS hosting credits"),
     OpenStruct.new(:sponsor => "RimuHosting", :prize => "Copy #2: $200 VPS hosting credits"),
     OpenStruct.new(:sponsor => "RimuHosting", :prize => "Copy #3: $200 VPS hosting credits"),
     OpenStruct.new(:sponsor => "Exceptional", :prize => "1-year Mini plan in the prize pool"),
     OpenStruct.new(:sponsor => "Devver", :prize => "Copy #1: Beta invite"),
     OpenStruct.new(:sponsor => "Devver", :prize => "Copy #2: Beta invite"),
     OpenStruct.new(:sponsor => "Devver", :prize => "Copy #3: Beta invite"),
     OpenStruct.new(:sponsor => "Slicehost", :prize => "$100 hosting credit"),
     OpenStruct.new(:sponsor => "GitHub", :prize => "Copy #1: one-year Medium account"),
     OpenStruct.new(:sponsor => "GitHub", :prize => "Copy #2: one-year Medium account"),
     OpenStruct.new(:sponsor => "GitHub", :prize => "Copy #3: one-year Medium account"),
     OpenStruct.new(:sponsor => "Uservoice", :prize => "Two months of gold service"),
     OpenStruct.new(:sponsor => "Sterling Rose Design", :prize => "Ten hours of free design work on any project")
    ]
  end
 
  def bugmash_participants
    {
      'David Reese' => 50,
      'jonnii' => 50,
      'Yugui (Yuki Sonoda)' => 50,
      'blatyo (at gmail)' => 25,
      'Michael Siebert' => 1050,
      'Adrien Pestel' => 50,
      'Larry Sprock' => 50,
      'Rizwan Reza' => 9100,
      'Brendan Schwartz' => 1000,
      'anupom syam' => 25,
      'Wesley Moxam' => 100,
      'Dan Pickett' => 1575,
      'Ryan Bigg' => 175,
      'stevestmartin' => 3450,
      'Matt Duncan' => 5350,
      'Josh Sharpe' => 1175,
      'railsbob' => 2400,
      'wmoxam' => 1000,
      'Derander' => 1825,
      'pjammer' => 300,
      'qmx' => 75,
      'Nikolay Petrachkov ' => 1725,
      'Kieran P' => 525,
      'Cristi Balan' => 2150,
      'dira' => 400,
      'Nick Quaranto' => 2250,
      'gsterndale' => 575,
      'David Trasbo' => 650,
      'Bas Van Klinkenberg' => 1000,
      'Josh Nichols' => 6400,
      'Niklas Holmgren' => 1000,
      'jamesw' => 50,
      'John Trupiano' => 225,
      'Adam Keys' => 225,
      'Leandro Heuert' => 50,
      'Edd Morgan' => 75,
      'Sam Goldstein' => 25,
      'jzw' => 1000,
      'Dan Croak' => 4075,
      'chucknelson' => 25,
      'Rajesh' => 325,
      'Gabe da Silveira' => 4050,
      'Alexey Poimtsev' => 50,
      'Hugo Peixoto' => 7200,
      'Rebecca Frankel' => 225,
      'Arthur Zapparoli' => 2475,
      'Simon Jefford' => 325,
      'AmundS' => 25,
      'John Pignata' => 200,
      'Daniel Rice' => 50,
      'Dmitry Ratnikov' => 1125,
      'Tristan Dunn' => 4875,
      'Rob' => 1000,
      'Jon Wood' => 1000,
      'bastilian' => 1000,
      'Marc-Andre Lafortune' => 1000,
      'Peer Allan' => 175,
      'Jatinder Singh' => 2575,
      'Ed Ruder' => 125,
      'RomKo' => 75,
      'Rich Bradley' => 1000,
      'Geoff Jacobsen' => 100,
      'Elise Huard' => 1550,
      'Christian Seiler' => 50,
      'Felipe Talavera' => 1275,
      'Matt Conway' => 1000,
      'Marshall Huss' => 1025,
      'ThePhred' => 100,
      'Casper' => 50,
      'Nathan Humbert' => 25,
      'Roy Nicholson' => 1000,
      'David Burger' => 1000,
      'Erik' => 50,
      'feldercarb' => 50,
      'Adam Bair' => 225,
      'Jordan Brough' => 1000,
      'Vladimir Meremyanin' => 1000,
      'Grzegorz Forysinski' => 1000,
      'Max Lapshin' => 1000,
      'jeem' => 1000,
      'Erik Ostrom' => 1225,
      'Prem Sichanugrist' => 1000,
      'barunio' => 50,
      'Morgan Schweers' => 1000,
      'Jaime Bellmyer' => 1000,
      'Leonardo Borges' => 1000,
      'Daniel Sheppard' => 1000,
      'Jay Pignata' => 1000,
      'Fabien Jakimowicz' => 1000,
      'Jeff Dean' => 1000,
      'Steve H' => 50,
      'Tim Peters' => 1000,
      'Kamal Fariz Mahyuddin' => 1000,
      'codeape' => 1000,
      'Casey Rosenthal' => 175
    }
  end
 
  def generate_tickets(participants)
    tickets = []
    participants.each do |participant, points|
      number_of_tickets = (points.to_f / 100.0).ceil
 
      (1..number_of_tickets).each do
        tickets << participant
      end
    end
    @tickets = tickets.sort_by {rand}
  end
 
  def pull_winners(participants=nil)
    participants ||= bugmash_participants
    generate_tickets(participants)
    winners = []
    prizes.each do |prize|
      lucky_winner = @tickets.pop
      while has_already_won_prize_from_sponsor?(lucky_winner, prize, winners)
        put_ticket_back_in_lottery(lucky_winner)
        lucky_winner = @tickets.pop
      end
      winners << OpenStruct.new(:participant => lucky_winner, :prize => prize)
      remove_participant_from_lottery(lucky_winner) if has_reached_prize_limit?(lucky_winner, winners)
    end
    winners
  end
 
  def remove_participant_from_lottery(participant)
    @tickets = @tickets.reject {|p| p == participant}
  end
 
  def has_reached_prize_limit?(participant, winners)
    prize_count = winners.select {|winner| winner.participant == participant}
    prize_count.size == PRIZE_LIMIT
  end
 
  def has_already_won_prize_from_sponsor?(participant, prize, winners)
    winners.select {|winner| winner.participant == participant}.detect {|winner| winner.prize.sponsor == prize.sponsor}
  end
 
  def put_ticket_back_in_lottery(ticket)
    @tickets.insert(rand(@tickets.size - 1), ticket)
  end
 
  def run_lottery
    pull_winners.each do |winner|
      puts "#{winner.participant} has won #{winner.prize.prize} from #{winner.prize.sponsor}"
    end
  end
end
 
bugmash_lottery_test.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
require 'test/unit'
require 'ostruct'
require 'bugmash_lottery'
 
class BugMashLotteryTest < Test::Unit::TestCase
  def setup
    @lottery = BugMashLottery.new
    @prize_one = OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #1: 1yr Lighthouse (bronze)")
    @prize_two = OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #2: 1yr Lighthouse (bronze)")
    @prize_three = OpenStruct.new(:sponsor => "ActionRails", :prize => "1 month (4 hours) of Developer Hotline support")
  end
 
  def test_tickets_should_be_rounded_up_from_score
    tickets = @lottery.generate_tickets({'User A' => 175})
    assert_equal 2, @lottery.tickets.size
  end
 
  def test_should_only_win_single_prize_from_sponsor
    winners = [OpenStruct.new(:participant => 'Dave', :prize => @prize_one)]
 
    assert @lottery.has_already_won_prize_from_sponsor?('Dave', @prize_two, winners)
    assert ! @lottery.has_already_won_prize_from_sponsor?('Dave', @prize_three, winners)
  end
 
  def test_should_not_surpass_prize_limit
    dave = 'Dave'
    joe = 'Joe'
    winners = [
               OpenStruct.new(:participant => dave, :prize => @prize_one),
               OpenStruct.new(:participant => dave, :prize => @prize_three),
               OpenStruct.new(:participant => joe, :prize => @prize_two)
               ]
    prize = OpenStruct.new(:sponsor => "GitHub", :prize => "Copy #1: one-year Medium account")
    assert @lottery.has_reached_prize_limit?(dave, winners)
    assert ! @lottery.has_reached_prize_limit?(joe, winners)
  end
 
  def test_remove_tickets_from_lottery
    @lottery.generate_tickets({'Joe' => 1000, 'Dave' => 800})
    @lottery.remove_participant_from_lottery('Dave')
    assert_equal 10, @lottery.tickets.size
  end
 
  def test_put_ticket_back_in_lottery
    @lottery.generate_tickets({'Joe' => 100, 'Dave' => 100, 'Chuck' => 100})
    ticket = @lottery.tickets.pop
    assert ! @lottery.tickets.detect { |t| t == ticket }
    @lottery.put_ticket_back_in_lottery(ticket)
    assert_equal 3, @lottery.tickets.size
    assert @lottery.tickets.detect { |t| t == ticket }
  end
end
 
no prize for you! #
1
2
3
4
5
6
7
8
9
10
11
12
13
these participants were removed from the lottery:
 
'Dana Jones' => 1150
'Mike Gunderloy' => 350
'Elad Meidar' => 4825
'Jeremy Kemper' => 1500
'Pratik Naik' => 1000
'Yehuda Katz' => 1000
'José Valim' => 475
'Mike Breen' => 2675
'Eric Davis' => 1125
'Michael Koziarski' => 1150
'hardbap' => 0