bandido 0.0.6

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.
Files changed (57) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +674 -0
  4. data/README.rdoc +77 -0
  5. data/Rakefile +34 -0
  6. data/bandit.gemspec +22 -0
  7. data/lib/bandit/config.rb +33 -0
  8. data/lib/bandit/date_hour.rb +82 -0
  9. data/lib/bandit/exceptions.rb +10 -0
  10. data/lib/bandit/experiment.rb +63 -0
  11. data/lib/bandit/extensions/array.rb +3 -0
  12. data/lib/bandit/extensions/controller_concerns.rb +33 -0
  13. data/lib/bandit/extensions/string.rb +5 -0
  14. data/lib/bandit/extensions/time.rb +5 -0
  15. data/lib/bandit/extensions/view_concerns.rb +40 -0
  16. data/lib/bandit/memoizable.rb +32 -0
  17. data/lib/bandit/players/base.rb +37 -0
  18. data/lib/bandit/players/epsilon_greedy.rb +32 -0
  19. data/lib/bandit/players/round_robin.rb +7 -0
  20. data/lib/bandit/storage/base.rb +134 -0
  21. data/lib/bandit/storage/memcache.rb +44 -0
  22. data/lib/bandit/storage/memory.rb +31 -0
  23. data/lib/bandit/storage/redis.rb +47 -0
  24. data/lib/bandit/version.rb +3 -0
  25. data/lib/bandit.rb +69 -0
  26. data/lib/generators/bandit/USAGE +3 -0
  27. data/lib/generators/bandit/dashboard_generator.rb +31 -0
  28. data/lib/generators/bandit/install_generator.rb +22 -0
  29. data/lib/generators/bandit/templates/bandit.rake +20 -0
  30. data/lib/generators/bandit/templates/bandit.rb +18 -0
  31. data/lib/generators/bandit/templates/bandit.yml +16 -0
  32. data/lib/generators/bandit/templates/bandit_controller.rb +30 -0
  33. data/lib/generators/bandit/templates/dashboard/bandit.html.erb +43 -0
  34. data/lib/generators/bandit/templates/dashboard/css/application.css +7 -0
  35. data/lib/generators/bandit/templates/dashboard/css/base.css +28 -0
  36. data/lib/generators/bandit/templates/dashboard/css/toupee/buttons.css +101 -0
  37. data/lib/generators/bandit/templates/dashboard/css/toupee/forms.css +89 -0
  38. data/lib/generators/bandit/templates/dashboard/css/toupee/modules.css +30 -0
  39. data/lib/generators/bandit/templates/dashboard/css/toupee/reset.css +42 -0
  40. data/lib/generators/bandit/templates/dashboard/css/toupee/structure.css +124 -0
  41. data/lib/generators/bandit/templates/dashboard/css/toupee/typography.css +103 -0
  42. data/lib/generators/bandit/templates/dashboard/helpers/bandit_helper.rb +23 -0
  43. data/lib/generators/bandit/templates/dashboard/js/bandit.js +51 -0
  44. data/lib/generators/bandit/templates/dashboard/js/highstock.js +215 -0
  45. data/lib/generators/bandit/templates/dashboard/js/jquery.min.js +154 -0
  46. data/lib/generators/bandit/templates/dashboard/view/_experiment_table.html.erb +19 -0
  47. data/lib/generators/bandit/templates/dashboard/view/index.html.erb +14 -0
  48. data/lib/generators/bandit/templates/dashboard/view/show.html.erb +19 -0
  49. data/players.rdoc +21 -0
  50. data/test/config.yml +7 -0
  51. data/test/helper.rb +18 -0
  52. data/test/memcache_storage_test.rb +17 -0
  53. data/test/memory_storage_test.rb +16 -0
  54. data/test/redis_storage_test.rb +17 -0
  55. data/test/storage_test_base.rb +54 -0
  56. data/whybandit.rdoc +31 -0
  57. metadata +166 -0
@@ -0,0 +1,42 @@
1
+ /* --------------------------------------------------------------
2
+ RESET // Resets default browser CSS.
3
+ -------------------------------------------------------------- */
4
+
5
+ html, body, div, span, object, iframe,
6
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
7
+ a, abbr, acronym, address, code,
8
+ del, dfn, em, img, q, dl, dt, dd, ol, ul, li,
9
+ fieldset, form, label, legend,
10
+ table, caption, tbody, tfoot, thead, tr, th, td,
11
+ article, aside, dialog, figure, footer, header,
12
+ hgroup, nav, section {
13
+ margin: 0;
14
+ padding: 0;
15
+ border: 0;
16
+ font-weight: inherit;
17
+ font-style: inherit;
18
+ font-size: 100%;
19
+ font-family: inherit;
20
+ vertical-align: baseline;
21
+ }
22
+
23
+ article, aside, dialog, figure, footer, header,
24
+ hgroup, nav, section {
25
+ display:block;
26
+ }
27
+
28
+ body {
29
+ line-height: 1.5;
30
+ }
31
+
32
+ /* Tables still need 'cellspacing="0"' in the markup. */
33
+ table { border-collapse: separate; border-spacing: 0; }
34
+ caption, th, td { text-align: left; font-weight: normal; }
35
+ table, td, th { vertical-align: middle; }
36
+
37
+ /* Remove possible quote marks (") from <q>, <blockquote>. */
38
+ blockquote:before, blockquote:after, q:before, q:after { content: ""; }
39
+ blockquote, q { quotes: "" ""; }
40
+
41
+ /* Remove annoying border on linked images. */
42
+ a img { border: none; }
@@ -0,0 +1,124 @@
1
+ /* A container should group all your columns. */
2
+ .container { width: 950px; margin: 0 auto; }
3
+
4
+ /* Columns
5
+ -------------------------------------------------------------- */
6
+ /* Sets up basic grid floating and margin. */
7
+ .span-1, .span-2, .span-3, .span-4, .span-5, .span-6, .span-7, .span-8, .span-9, .span-10, .span-11, .span-12, .span-13, .span-14, .span-15, .span-16, .span-17, .span-18, .span-19, .span-20, .span-21, .span-22, .span-23, .span-24 {
8
+ float: left;
9
+ margin-right: 10px;
10
+ }
11
+
12
+ /* The last column in a row needs this class. */
13
+ .last { margin-right: 0; }
14
+
15
+ /* Use these classes to set the width of a column. */
16
+ .span-1 {width: 30px;}
17
+ .span-2 {width: 70px;}
18
+ .span-3 {width: 110px;}
19
+ .span-4 {width: 150px;}
20
+ .span-5 {width: 190px;}
21
+ .span-6 {width: 230px;}
22
+ .span-7 {width: 270px;}
23
+ .span-8 {width: 310px;}
24
+ .span-9 {width: 350px;}
25
+ .span-10 {width: 390px;}
26
+ .span-11 {width: 430px;}
27
+ .span-12 {width: 470px;}
28
+ .span-13 {width: 510px;}
29
+ .span-14 {width: 550px;}
30
+ .span-15 {width: 590px;}
31
+ .span-16 {width: 630px;}
32
+ .span-17 {width: 670px;}
33
+ .span-18 {width: 710px;}
34
+ .span-19 {width: 750px;}
35
+ .span-20 {width: 790px;}
36
+ .span-21 {width: 830px;}
37
+ .span-22 {width: 870px;}
38
+ .span-23 {width: 910px;}
39
+ .span-24 {width:950px; margin-right:0;}
40
+
41
+ /* Add these to a column to append empty cols. */
42
+ .append-1 { padding-right: 40px;}
43
+ .append-2 { padding-right: 80px;}
44
+ .append-3 { padding-right: 120px;}
45
+ .append-4 { padding-right: 160px;}
46
+ .append-5 { padding-right: 200px;}
47
+ .append-6 { padding-right: 240px;}
48
+ .append-7 { padding-right: 280px;}
49
+ .append-8 { padding-right: 320px;}
50
+ .append-9 { padding-right: 360px;}
51
+ .append-10 { padding-right: 400px;}
52
+ .append-11 { padding-right: 440px;}
53
+ .append-12 { padding-right: 480px;}
54
+ .append-13 { padding-right: 520px;}
55
+ .append-14 { padding-right: 560px;}
56
+ .append-15 { padding-right: 600px;}
57
+ .append-16 { padding-right: 640px;}
58
+ .append-17 { padding-right: 680px;}
59
+ .append-18 { padding-right: 720px;}
60
+ .append-19 { padding-right: 760px;}
61
+ .append-20 { padding-right: 800px;}
62
+ .append-21 { padding-right: 840px;}
63
+ .append-22 { padding-right: 880px;}
64
+ .append-23 { padding-right: 920px;}
65
+
66
+ /* Add these to a column to prepend empty cols. */
67
+ .prepend-1 { padding-left: 40px;}
68
+ .prepend-2 { padding-left: 80px;}
69
+ .prepend-3 { padding-left: 120px;}
70
+ .prepend-4 { padding-left: 160px;}
71
+ .prepend-5 { padding-left: 200px;}
72
+ .prepend-6 { padding-left: 240px;}
73
+ .prepend-7 { padding-left: 280px;}
74
+ .prepend-8 { padding-left: 320px;}
75
+ .prepend-9 { padding-left: 360px;}
76
+ .prepend-10 { padding-left: 400px;}
77
+ .prepend-11 { padding-left: 440px;}
78
+ .prepend-12 { padding-left: 480px;}
79
+ .prepend-13 { padding-left: 520px;}
80
+ .prepend-14 { padding-left: 560px;}
81
+ .prepend-15 { padding-left: 600px;}
82
+ .prepend-16 { padding-left: 640px;}
83
+ .prepend-17 { padding-left: 680px;}
84
+ .prepend-18 { padding-left: 720px;}
85
+ .prepend-19 { padding-left: 760px;}
86
+ .prepend-20 { padding-left: 800px;}
87
+ .prepend-21 { padding-left: 840px;}
88
+ .prepend-22 { padding-left: 880px;}
89
+ .prepend-23 { padding-left: 920px;}
90
+
91
+ /* Border on right hand side of a column. */
92
+ .border { padding-right: 4px; margin-right: 5px; border-right: 1px solid #eee; }
93
+
94
+ /* Border with more whitespace, spans one column. */
95
+ .colborder { padding-right: 24px; margin-right: 25px; border-right: 1px solid #eee; }
96
+
97
+ /* Use this to create a horizontal ruler across a column. */
98
+ hr {
99
+ background: #ddd;
100
+ color: #ddd;
101
+ clear: both;
102
+ float: none;
103
+ width: 100%;
104
+ height: .1em;
105
+ margin: 0 0 1.45em;
106
+ border: none;
107
+ }
108
+
109
+ /* Clearing floats without extra markup
110
+ Based on How To Clear Floats Without Structural Markup by PiE
111
+ [http://www.positioniseverything.net/easyclearing.html] */
112
+
113
+ .clearfix:after, .container:after {
114
+ content: "\0020";
115
+ display: block;
116
+ height: 0;
117
+ clear: both;
118
+ visibility: hidden;
119
+ overflow:hidden;
120
+ }
121
+ .clearfix, .container {display: block;}
122
+
123
+ .clear { clear:both; }
124
+
@@ -0,0 +1,103 @@
1
+ /* --------------------------------------------------------------
2
+
3
+ typography.css
4
+ * Sets Up A Default Typography.
5
+
6
+ -------------------------------------------------------------- */
7
+
8
+ html { font-size:100.01%; -webkit-font-smoothing: antialiased; }
9
+ body {
10
+ font-size: 75%;
11
+ color: #222;
12
+ background: #fff;
13
+ font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
14
+ }
15
+
16
+ /* HEADINGS
17
+ ========================= */
18
+
19
+ h1,h2,h3,h4,h5,h6 { font-weight: normal; color: #333; word-spacing:-1px; font-family: "Lucida Grande","Lucida Sans Unicode", Arial,Verdana,sans-serif; }
20
+
21
+ h1 { font-size: 2.5em; font-weight: bold; line-height: 1.2em; margin-bottom: 0.5em; }
22
+ h2 { font-size: 2em; margin-bottom: 0.75em; }
23
+ h3 { font-size: 1.5em; line-height: 1; margin-bottom: .5em; }
24
+ h4 { font-size: 1.2em; line-height: 1.25; margin-bottom: 1.25em; }
25
+ h5 { font-size: 1em; font-weight: bold; margin-bottom: 1.5em; }
26
+ h6 { font-size: 1em; font-weight: bold; }
27
+
28
+
29
+ /* TEXT ELEMENTS
30
+ ========================= */
31
+
32
+ p { margin: 0 0 1em; }
33
+
34
+ a:focus,
35
+ a:hover { color: #000; }
36
+ a { color: #2e71b3; text-decoration: underline; outline-style: none; }
37
+
38
+ blockquote { margin: 1.5em; color: #666; font-style: italic; }
39
+ strong { font-weight: bold; }
40
+ em,dfn { font-style: italic; }
41
+ dfn { font-weight: bold; }
42
+ sup, sub { line-height: 0; }
43
+
44
+ abbr,
45
+ acronym { border-bottom: 1px dotted #666; }
46
+ address { margin: 0 0 1.5em; font-style: italic; }
47
+ del { color:#666; }
48
+
49
+ pre { margin: 1.5em 0; white-space: pre; }
50
+ pre,code,tt { font: 1em 'andale mono', 'lucida console', monospace; line-height: 1.5; }
51
+
52
+
53
+ /* LISTS
54
+ ========================= */
55
+
56
+ li ul,
57
+ li ol { margin: 0; }
58
+ ul, ol { margin: 0 1.5em 1.5em 0; padding-left: 1.333em; }
59
+
60
+ ul { list-style:square outside none; }
61
+ ol { list-style-type: decimal; }
62
+
63
+ dl { margin: 0 0 1.5em 0; }
64
+ dl dt { font-weight: bold; }
65
+ dd { margin-left: 1.5em;}
66
+
67
+
68
+ /* TABLES
69
+ ========================= */
70
+
71
+ table { width: 100%; background: #fff; }
72
+ table caption { margin: 0; padding: 8px 10px; text-align: left; border: 1px solid #000; border-bottom: none; background: #fff; }
73
+ table th, table td { margin: 0; padding: 8px 10px; text-align: center; border-bottom: 1px solid #e1e1e1; }
74
+ table th { font-size: 14px; font-weight: bold; }
75
+ table th.left { -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; border-top-left-radius: 3px; }
76
+ table th.right { -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; border-top-right-radius: 3px; }
77
+ table .name { text-align: left; }
78
+ table tr { background-color: #fff; }
79
+ table tr.last td { border-bottom: none; }
80
+ table tr.alt { background-color: #e5ecf9; }
81
+ table td a,
82
+ table td a:hover { font-weight: bold; border: none; }
83
+
84
+
85
+ /* Misc classes
86
+ -------------------------------------------------------------- */
87
+ .reset { margin: 0; padding:0; }
88
+ .right { float: right; }
89
+ .left { float: left; }
90
+ .reset { margin: 0; padding: 0; }
91
+ .small { font-size: 10px; }
92
+ .large { font-size: 16px; }
93
+ .hide { display: none; }
94
+ .quiet { color: #bbb; }
95
+ .loud { color: #000; font-weight: bold; }
96
+ .required { color: #ff0000; }
97
+ .highlight { background-color:#ff0; padding: 2px 6px; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; }
98
+ .success { background-color:#060; color: #fff; padding: 2px 6px; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px;}
99
+ .error { background-color:#fcc; border: 1px solid #f00; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px }
100
+ .pending { background-color:#ffc; border: 1px solid yellow; padding: 2px 6px; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; }
101
+ .removed { background-color:#900; color: #fff; padding: 2px 6px; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; }
102
+
103
+
@@ -0,0 +1,23 @@
1
+ module BanditHelper
2
+ def storage_name
3
+ Bandit.config.storage.titleize
4
+ end
5
+
6
+ def round_percent(percent)
7
+ (percent * 100).round / 100.0
8
+ end
9
+
10
+ def player_name
11
+ Bandit.config.player.titleize
12
+ end
13
+
14
+ def storage_config
15
+ c = Bandit.config.storage_config.map { |k,v| "#{k}: #{v}" }.join(", ")
16
+ c.blank? ? "" : "(#{c})"
17
+ end
18
+
19
+ def player_config
20
+ c = Bandit.config.player_config.map { |k,v| "#{k}: #{v}" }.join(", ")
21
+ c.blank? ? "" : "(#{c})"
22
+ end
23
+ end
@@ -0,0 +1,51 @@
1
+ function show_chart(title, url) {
2
+ $.get(url, function(data) { show_chart_data(title, data) });
3
+ }
4
+
5
+ function show_chart_data(title, data) {
6
+ var options = {
7
+ chart: { renderTo: 'totals_gcontainer' },
8
+ title: { text: title },
9
+ rangeSelector: { selected: 1 },
10
+ subtitle: { text: "participant / conversion totals" },
11
+ yAxis: { title: { text: "people" } },
12
+ series: []
13
+ };
14
+
15
+ var percent_options = {
16
+ chart: { renderTo: 'percents_gcontainer' },
17
+ title: { text: title },
18
+ rangeSelector: { selected: 1 },
19
+ subtitle: { text: "conversion percents" },
20
+ yAxis: { title: { text: "% converted" } },
21
+ series: []
22
+ };
23
+
24
+ var series_c = null;
25
+ var series_p = null;
26
+ var series_percent = null;
27
+ $.each(data.split('\n'), function(lineNo, line) {
28
+ var items = line.split("\t");
29
+ var ctitle = items[0] + " conversions";
30
+ var ptitle = items[0] + " participants";
31
+ var percent_title = items[0] + " conversion %";
32
+ if(series_c == null || series_c.name != ctitle) {
33
+ if(series_c != null) { options.series.push(series_p); options.series.push(series_c); percent_options.series.push(series_percent); }
34
+ series_c = { data: [], name: ctitle };
35
+ series_p = { data: [], name: ptitle };
36
+ series_percent = { data: [], name: percent_title, yDecimals: 2 };
37
+ }
38
+ var date = Date.UTC(parseInt(items[1]), parseInt(items[2]), parseInt(items[3]));
39
+ var participants = parseFloat(items[4]);
40
+ var conversions = parseFloat(items[5]);
41
+ var conversion_percent = Math.round((conversions / participants) * 100) / 100;
42
+ series_p.data.push([date, participants]);
43
+ series_c.data.push([date, conversions]);
44
+ series_percent.data.push([date, conversion_percent]);
45
+ });
46
+ options.series.push(series_p);
47
+ options.series.push(series_c);
48
+ percent_options.series.push(series_percent);
49
+ var chart = new Highcharts.StockChart(options);
50
+ var charttwo = new Highcharts.StockChart(percent_options);
51
+ }