flicks 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.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2012 The Pragmatic Studio
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ - You may not use this Software in other training contexts.
11
+
12
+ - The above copyright notice and this permission notice shall be
13
+ included in 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 ADDED
@@ -0,0 +1,6 @@
1
+ This is an example application used in The Pragmatic Studio's
2
+ Ruby Programming course, as described at
3
+
4
+ http://pragmaticstudio.com
5
+
6
+ This code is Copyright 2012 The Pragmatic Studio. See the LICENSE file.
data/bin/flicks ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/flicks/playlist'
4
+
5
+ playlist = Flicks::Playlist.new("Kermit")
6
+
7
+ playlist.load(ARGV.shift || File.join(File.dirname(__FILE__), 'movies.csv'))
8
+
9
+ loop do
10
+ puts "\nHow many viewings? ('quit' to exit)"
11
+ answer = gets.chomp.downcase
12
+ case answer
13
+ when /^\d+$/
14
+ playlist.play(answer.to_i)
15
+ when 'quit', 'exit'
16
+ playlist.print_stats
17
+ break
18
+ else
19
+ puts "Please enter a number or 'quit'"
20
+ end
21
+ end
22
+
23
+ playlist.save
data/bin/movies.csv ADDED
@@ -0,0 +1,3 @@
1
+ Goonies,10
2
+ Ghostbusters,9
3
+ Goldfinger,5
@@ -0,0 +1,44 @@
1
+ require_relative 'snack_bar'
2
+ require_relative 'rankable'
3
+
4
+ module Flicks
5
+ class Movie
6
+ include Rankable
7
+
8
+ attr_accessor :title, :rank
9
+
10
+ def initialize(title, rank=0)
11
+ @title = title.capitalize
12
+ @rank = rank
13
+ @snack_carbs = Hash.new(0)
14
+ end
15
+
16
+ def ate_snack(snack)
17
+ @snack_carbs[snack.name] += snack.carbs
18
+ puts "#{@title} led to #{snack.carbs} #{snack.name} carbs being consumed."
19
+ end
20
+
21
+ def carbs_consumed
22
+ @snack_carbs.values.reduce(0, :+)
23
+ end
24
+
25
+ def each_snack
26
+ @snack_carbs.each do |name, carbs|
27
+ yield Snack.new(name, carbs)
28
+ end
29
+ end
30
+
31
+ def to_s
32
+ "#{@title} has a rank of #{@rank} (#{status})"
33
+ end
34
+
35
+ def to_csv
36
+ "#{@title},#{@rank}"
37
+ end
38
+
39
+ def self.from_csv(string)
40
+ title, rank = string.split(',')
41
+ new(title, Integer(rank))
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'movie'
2
+
3
+ module Flicks
4
+ class Movie3D < Movie
5
+ attr_reader :wow_factor
6
+
7
+ def initialize(name, rank, wow_factor)
8
+ super(name, rank)
9
+ @wow_factor = wow_factor
10
+ end
11
+
12
+ def thumbs_up
13
+ @wow_factor.times { super }
14
+ end
15
+
16
+ def show_effect
17
+ puts "Wow! " * @wow_factor
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,78 @@
1
+ require_relative 'movie'
2
+ require_relative 'movie3d'
3
+ require_relative 'waldorf_and_statler'
4
+ require_relative 'snack_bar'
5
+
6
+ module Flicks
7
+ class Playlist
8
+ attr_reader :name
9
+
10
+ def initialize(name)
11
+ @name = name
12
+ @movies = []
13
+ end
14
+
15
+ def add_movie(a_movie)
16
+ @movies << a_movie
17
+ end
18
+
19
+ def play(viewings)
20
+ puts "#{@name}'s playlist:"
21
+
22
+ puts @movies.sort
23
+
24
+ snacks = SnackBar::SNACKS
25
+ puts "\nThere are #{snacks.size} snacks available in the snack bar:"
26
+ snacks.each do |snack|
27
+ puts "#{snack.name} has #{snack.carbs} carbs"
28
+ end
29
+
30
+ 1.upto(viewings) do |count|
31
+ puts "\nViewing #{count}:"
32
+ @movies.each do |movie|
33
+ WaldorfAndStatler.review(movie)
34
+ snack = SnackBar.random
35
+ movie.ate_snack(snack)
36
+ puts movie
37
+ end
38
+ end
39
+ end
40
+
41
+ def total_carbs_consumed
42
+ @movies.reduce(0) { |sum, movie| sum + movie.carbs_consumed }
43
+ end
44
+
45
+ def print_stats
46
+ puts "\n#{@name}'s Stats:"
47
+
48
+ hits, flops = @movies.partition {|movie| movie.hit? }
49
+
50
+ puts "\nHits:"
51
+ puts hits.sort
52
+
53
+ puts "\nFlops:"
54
+ puts flops.sort
55
+
56
+ puts "\n#{total_carbs_consumed} total carbs consumed"
57
+ @movies.sort.each do |movie|
58
+ puts "\n#{movie.title}'s snack totals:"
59
+ movie.each_snack do |snack|
60
+ puts "#{snack.carbs} total #{snack.name} carbs"
61
+ end
62
+ puts "#{movie.carbs_consumed} grand total carbs"
63
+ end
64
+ end
65
+
66
+ def load(from_file)
67
+ File.readlines(from_file).each do |line|
68
+ add_movie(Movie.from_csv(line))
69
+ end
70
+ end
71
+
72
+ def save(to_file="movie_rankings.csv")
73
+ File.open(to_file, "w") do |file|
74
+ file.puts @movies.sort.map { |movie| movie.to_csv }
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,23 @@
1
+ module Flicks
2
+ module Rankable
3
+ def thumbs_up
4
+ self.rank += 1
5
+ end
6
+
7
+ def thumbs_down
8
+ self.rank -= 1
9
+ end
10
+
11
+ def hit?
12
+ self.rank >= 10
13
+ end
14
+
15
+ def status
16
+ hit? ? "Hit": "Flop"
17
+ end
18
+
19
+ def <=>(other)
20
+ other.rank <=> self.rank
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ module Flicks
2
+ Snack = Struct.new(:name, :carbs)
3
+
4
+ module SnackBar
5
+ SNACKS = [
6
+ Snack.new(:nachos, 40),
7
+ Snack.new(:popcorn, 20),
8
+ Snack.new(:candy, 15),
9
+ Snack.new(:pretzel, 10),
10
+ Snack.new(:soda, 5)
11
+ ]
12
+
13
+ def self.random
14
+ SNACKS.sample
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ require_relative 'movie'
2
+
3
+ module Flicks
4
+ module WaldorfAndStatler
5
+ def self.roll_die
6
+ rand(1..6)
7
+ end
8
+
9
+ def self.review(movie)
10
+ case roll_die
11
+ when 1..2
12
+ movie.thumbs_down
13
+ puts "#{movie.title} got a thumbs down."
14
+ when 3..4
15
+ puts "#{movie.title} was skipped."
16
+ else
17
+ movie.thumbs_up
18
+ puts "#{movie.title} got a thumbs up!"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,35 @@
1
+ require 'flicks/movie3d'
2
+
3
+ module Flicks
4
+ describe Movie3D do
5
+ before do
6
+ @initial_rank = 10
7
+ @wow_factor = 5
8
+ @movie = Movie3D.new('Glee', @initial_rank, @wow_factor)
9
+ end
10
+
11
+ it "has a title" do
12
+ @movie.title.should == "Glee"
13
+ end
14
+
15
+ it "has a rank" do
16
+ @movie.rank.should == 10
17
+ end
18
+
19
+ it "has a wow factor" do
20
+ @movie.wow_factor.should == 5
21
+ end
22
+
23
+ it "increases rank by 1 times the wow factor when given a thumbs up" do
24
+ @movie.thumbs_up
25
+
26
+ @movie.rank.should == @initial_rank + (1 * @wow_factor)
27
+ end
28
+
29
+ it "decreases rank by 1 when given a thumbs down" do
30
+ @movie.thumbs_down
31
+
32
+ @movie.rank.should == @initial_rank - 1
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,124 @@
1
+ require 'flicks/movie'
2
+
3
+ module Flicks
4
+ describe Movie do
5
+ before do
6
+ @initial_rank = 10
7
+ @movie = Movie.new("goonies", @initial_rank)
8
+ end
9
+
10
+ it "has a capitalized title" do
11
+ @movie.title.should == "Goonies"
12
+ end
13
+
14
+ it "has an initial rank" do
15
+ @movie.rank.should == 10
16
+ end
17
+
18
+ it "has a string representation" do
19
+ @movie.to_s.should == "Goonies has a rank of 10 (Hit)"
20
+ end
21
+
22
+ it "increases rank by 1 when given a thumbs up" do
23
+ @movie.thumbs_up
24
+
25
+ @movie.rank.should == @initial_rank + 1
26
+ end
27
+
28
+ it "decreases rank by 1 when given a thumbs down" do
29
+ @movie.thumbs_down
30
+
31
+ @movie.rank.should == @initial_rank - 1
32
+ end
33
+
34
+ context "created with a default rank" do
35
+ before do
36
+ @movie = Movie.new("goonies")
37
+ end
38
+
39
+ it "has a rank of 0" do
40
+ @movie.rank.should == 0
41
+ end
42
+ end
43
+
44
+ context "with a rank of at least 10" do
45
+ before do
46
+ @movie = Movie.new("goonies", 10)
47
+ end
48
+
49
+ it "is a hit" do
50
+ @movie.should be_hit
51
+ end
52
+
53
+ it "has a hit status" do
54
+ @movie.status.should == "Hit"
55
+ end
56
+ end
57
+
58
+ context "with a rank less than 10" do
59
+ before do
60
+ @movie = Movie.new("goonies", 9)
61
+ end
62
+
63
+ it "is not a hit" do
64
+ @movie.should_not be_hit
65
+ end
66
+
67
+ it "has a flop status" do
68
+ @movie.status.should == "Flop"
69
+ end
70
+ end
71
+
72
+ it "is sorted by decreasing rank" do
73
+ movie1 = Movie.new("goonies", 100)
74
+ movie2 = Movie.new("ghostbusters", 200)
75
+ movie3 = Movie.new("goldfinger", 300)
76
+
77
+ movies = [movie1, movie2, movie3]
78
+
79
+ movies.sort.should == [movie3, movie2, movie1]
80
+ end
81
+
82
+ it "computes carbs consumed as the sum of all snack carbs consumed" do
83
+ @movie.carbs_consumed.should == 0
84
+
85
+ @movie.ate_snack(Snack.new(:popcorn, 10))
86
+
87
+ @movie.carbs_consumed.should == 10
88
+
89
+ @movie.ate_snack(Snack.new(:popcorn, 10))
90
+
91
+ @movie.carbs_consumed.should == 20
92
+
93
+ @movie.ate_snack(Snack.new(:soda, 5))
94
+
95
+ @movie.carbs_consumed.should == 25
96
+ end
97
+
98
+ it "yields each snack" do
99
+ @movie.ate_snack(Snack.new(:popcorn, 10))
100
+ @movie.ate_snack(Snack.new(:popcorn, 10))
101
+ @movie.ate_snack(Snack.new(:soda, 5))
102
+
103
+ yielded = []
104
+ @movie.each_snack do |snack|
105
+ yielded << snack
106
+ end
107
+
108
+ yielded.should == [Snack.new(:popcorn, 20), Snack.new(:soda, 5)]
109
+ end
110
+
111
+ it "can be instantiated from a CSV string" do
112
+ movie = Movie.from_csv("goonies,10")
113
+
114
+ movie.title.should == "Goonies"
115
+ movie.rank.should == 10
116
+ end
117
+
118
+ it "can be serialized to a CSV string" do
119
+ movie = Movie.new("Goonies", 10)
120
+
121
+ movie.to_csv.should == "Goonies,10"
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,82 @@
1
+ require 'flicks/playlist'
2
+
3
+ module Flicks
4
+ describe Playlist do
5
+ before do
6
+ @playlist = Playlist.new("Kermit")
7
+ end
8
+
9
+ it "has a name" do
10
+ @playlist.name.should == "Kermit"
11
+ end
12
+
13
+ context "being played with one movie" do
14
+ before do
15
+ @initial_rank = 10
16
+ @movie = Movie.new("Goonies", @initial_rank)
17
+
18
+ @playlist.add_movie(@movie)
19
+ end
20
+
21
+ it "gives the movie a thumbs up if a high number is rolled" do
22
+ WaldorfAndStatler.stub(:roll_die).and_return(6)
23
+
24
+ @playlist.play(2)
25
+
26
+ @movie.rank.should == @initial_rank + 2
27
+
28
+ WaldorfAndStatler.stub(:roll_die).and_return(5)
29
+
30
+ @playlist.play(2)
31
+
32
+ @movie.rank.should == @initial_rank + 4
33
+ end
34
+
35
+ it "skips the movie if a medium number is rolled" do
36
+ WaldorfAndStatler.stub(:roll_die).and_return(4)
37
+
38
+ @playlist.play(2)
39
+
40
+ @movie.rank.should == @initial_rank
41
+
42
+ WaldorfAndStatler.stub(:roll_die).and_return(3)
43
+
44
+ @playlist.play(2)
45
+
46
+ @movie.rank.should == @initial_rank
47
+ end
48
+
49
+ it "gives the movie a thumbs down if a low number is rolled" do
50
+ WaldorfAndStatler.stub(:roll_die).and_return(2)
51
+
52
+ @playlist.play(2)
53
+
54
+ @movie.rank.should == @initial_rank - 2
55
+
56
+ WaldorfAndStatler.stub(:roll_die).and_return(1)
57
+
58
+ @playlist.play(2)
59
+
60
+ @movie.rank.should == @initial_rank - 4
61
+ end
62
+ end
63
+
64
+ context "with movies that have caused snacks to be consumed" do
65
+ before do
66
+ movie1 = Movie.new("goonies")
67
+ movie2 = Movie.new("ghostbusters")
68
+
69
+ @playlist.add_movie(movie1)
70
+ @playlist.add_movie(movie2)
71
+
72
+ movie1.ate_snack(Snack.new(:popcorn, 10))
73
+ movie1.ate_snack(Snack.new(:popcorn, 10))
74
+ movie2.ate_snack(Snack.new(:soda, 5))
75
+ end
76
+
77
+ it "computes total carbs consumed as the sum of all movie carbs consumed" do
78
+ @playlist.total_carbs_consumed.should == 25
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,32 @@
1
+ require 'flicks/snack_bar'
2
+
3
+ module Flicks
4
+ describe Snack do
5
+ before do
6
+ @snack = Snack.new(:pretzel, 10)
7
+ end
8
+
9
+ it "has a name attribute" do
10
+ @snack.name.should == :pretzel
11
+ end
12
+
13
+ it "has a carbs attribute" do
14
+ @snack.carbs.should == 10
15
+ end
16
+
17
+ end
18
+ end
19
+
20
+ module Flicks
21
+ describe SnackBar do
22
+ it "has a trove of treasures" do
23
+ SnackBar::SNACKS.should_not be_empty
24
+ end
25
+
26
+ it "returns a random treasure" do
27
+ snack = SnackBar.random
28
+
29
+ SnackBar::SNACKS.should include(snack)
30
+ end
31
+ end
32
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flicks
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - The Pragmatic Studio
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70225081360240 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70225081360240
25
+ description: ! "This is an example application used in The Pragmatic Studio's \nRuby
26
+ Programming course, as described at\n\n http://pragmaticstudio.com\n\nThis code
27
+ is Copyright 2012 The Pragmatic Studio. See the LICENSE file."
28
+ email: support@pragmaticstudio.com
29
+ executables:
30
+ - flicks
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - bin/flicks
35
+ - bin/movies.csv
36
+ - lib/flicks/movie.rb
37
+ - lib/flicks/movie3d.rb
38
+ - lib/flicks/playlist.rb
39
+ - lib/flicks/rankable.rb
40
+ - lib/flicks/snack_bar.rb
41
+ - lib/flicks/waldorf_and_statler.rb
42
+ - spec/flicks/movie3d_spec.rb
43
+ - spec/flicks/movie_spec.rb
44
+ - spec/flicks/playlist_spec.rb
45
+ - spec/flicks/snack_bar_spec.rb
46
+ - LICENSE
47
+ - README
48
+ homepage: http://pragmaticstudio.com
49
+ licenses: []
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '1.9'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 1.8.10
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: Plays and reviews movies
72
+ test_files:
73
+ - spec/flicks/movie3d_spec.rb
74
+ - spec/flicks/movie_spec.rb
75
+ - spec/flicks/playlist_spec.rb
76
+ - spec/flicks/snack_bar_spec.rb