flicks 0.0.1

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