bandido 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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
+ }