rms_flicks 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +21 -0
- data/README +6 -0
- data/bin/flicks +76 -0
- data/bin/movie_rankings.csv +4 -0
- data/bin/movies.csv +3 -0
- data/lib/movie.rb +165 -0
- data/lib/movie3d.rb +56 -0
- data/lib/playlist.rb +173 -0
- data/lib/rankable.rb +40 -0
- data/lib/snack_bar.rb +68 -0
- data/lib/waldorf_and_statler.rb +43 -0
- data/spec/movie3d_spec.rb +35 -0
- data/spec/movie_spec.rb +153 -0
- data/spec/playlist_spec.rb +64 -0
- data/spec/snack_bar_spec.rb +32 -0
- metadata +82 -0
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
data/bin/flicks
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# above says to find the ruby environment to get the ruby interpretor
|
4
|
+
# also we ran the following from reviewRuby: 'chmod +x bin/flicks'
|
5
|
+
# this makes it executable.
|
6
|
+
# so we can run it from reviewRuby with: 'bin/flicks'
|
7
|
+
# if installed as a gem, they said it would just run as flicks. - ??? we'll see!
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
# used to test code.
|
12
|
+
|
13
|
+
# this file is now in the bin directory
|
14
|
+
# we can run it from the terminal in the top directory ('reviewRuby') with 'ruby bin/flicks.rb'
|
15
|
+
# so the playlist is up one then back down to the lib directory
|
16
|
+
require_relative '../lib/playlist'
|
17
|
+
|
18
|
+
# ?? i think that since movie3d requires_relative movie - and it is relative to movie3d - this works
|
19
|
+
require_relative '../lib/movie3d'
|
20
|
+
|
21
|
+
# movie1 = Movie.new("goonies", 10)
|
22
|
+
# movie2 = Movie.new("ghostbusters", 9)
|
23
|
+
# movie3 = Movie.new("goldfinger")
|
24
|
+
|
25
|
+
playlist1 = Flicks::Playlist.new("Kermit")
|
26
|
+
|
27
|
+
|
28
|
+
# playlist1.add_movie(movie1)
|
29
|
+
# playlist1.add_movie(movie2)
|
30
|
+
# playlist1.add_movie(movie3)
|
31
|
+
# removed above and added below in files video - after changes (add load method) to playlist
|
32
|
+
|
33
|
+
# make movies.csv the default
|
34
|
+
# but allow user to enter file
|
35
|
+
# command line arguments are stored in a global varible called ARGV
|
36
|
+
# also we call shift which will remove the passed in varible and shift all other elements down one.
|
37
|
+
# the 'or' operator allows for a default.
|
38
|
+
|
39
|
+
|
40
|
+
# we need to do something about the directory for movies.csv
|
41
|
+
# we'll make a default file varible using the File class
|
42
|
+
# -> which will give it an 'absolute path'
|
43
|
+
default_movie_file =
|
44
|
+
File.join(File.dirname(__FILE__), 'movies.csv')
|
45
|
+
|
46
|
+
|
47
|
+
playlist1.load(ARGV.shift || default_movie_file)
|
48
|
+
|
49
|
+
# here we add some movie3d stuff to demonstrate polymorphism
|
50
|
+
# we are going to co-mingle movies and 3d movies in our playlist code
|
51
|
+
|
52
|
+
movie3d = Flicks::Movie3D.new('glee', 5, 20)
|
53
|
+
playlist1.add_movie(movie3d)
|
54
|
+
|
55
|
+
# without changing anything else - 'glee' will get added in to the playlist activities - yeah!
|
56
|
+
|
57
|
+
|
58
|
+
loop do
|
59
|
+
puts "How many viewings? 'quit' to exit"
|
60
|
+
answer = gets.chomp.downcase
|
61
|
+
case answer
|
62
|
+
when /^\d+$/ # 1 or more numbers and end with numbers???
|
63
|
+
playlist1.play(answer.to_i)
|
64
|
+
when 'quit', 'exit'
|
65
|
+
playlist1.print_stats
|
66
|
+
break
|
67
|
+
else
|
68
|
+
puts "Please enter a number or 'quit'."
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# the save methods runs after viewings and creates a file of the the lastest rankings
|
73
|
+
# movie_rankings.csv
|
74
|
+
|
75
|
+
playlist1.save
|
76
|
+
|
data/bin/movies.csv
ADDED
data/lib/movie.rb
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
require_relative 'rankable'
|
2
|
+
require_relative 'snack_bar'
|
3
|
+
|
4
|
+
module Flicks
|
5
|
+
class Movie
|
6
|
+
include Rankable
|
7
|
+
# changed :rank to an accessor in mixins
|
8
|
+
attr_accessor :rank
|
9
|
+
# attr_accessor does a reader and a writer as described below
|
10
|
+
attr_accessor :title
|
11
|
+
|
12
|
+
# attributes have the possiblility to expose date to the outside world
|
13
|
+
# having rank as only a reader means that it can only be changed by the
|
14
|
+
#=> outside world through behaviour methods such as thumbs_up thumbs_down
|
15
|
+
# on the other hand - we will allow someone to change attr_accessor varibles
|
16
|
+
|
17
|
+
# attr_reader :title, :rank
|
18
|
+
# the above line of code is a short cut for the code commented out below
|
19
|
+
|
20
|
+
# def title
|
21
|
+
# @title
|
22
|
+
# end
|
23
|
+
# in programming this is commonly know as a getter method - attr_reader is a short cut to that.
|
24
|
+
|
25
|
+
# attr_writer :title
|
26
|
+
#### does not do the capitalization
|
27
|
+
# the above line of code is a short cut for the code commented out below
|
28
|
+
|
29
|
+
# def title=(new_title)
|
30
|
+
# @title = new_title
|
31
|
+
# end
|
32
|
+
# in programming this is commonly know as a writer method - attr_writer is a short cut to that.
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
def initialize(title, rank=0)
|
38
|
+
# the new method expects there to be an initialize method
|
39
|
+
# this method accepts the passed in varibles
|
40
|
+
# if you want these varibles to be available you need make them instance varibles
|
41
|
+
# they don't have to be the same name as the parameters - but it often makes sense
|
42
|
+
# these instance varibles live for the life of the object and can be accessed.
|
43
|
+
@title = title.capitalize
|
44
|
+
@rank = rank
|
45
|
+
# added with Hashes
|
46
|
+
# there will of coursee be a set of these for every instance of movie.
|
47
|
+
@snack_carbs = Hash.new(0)
|
48
|
+
end
|
49
|
+
|
50
|
+
# added with input/output video
|
51
|
+
|
52
|
+
def self.from_csv(line) # we don't have a movie object to call here - s0 we call from self
|
53
|
+
title, rank = line.split(',')
|
54
|
+
# we changed this so it will raise an exception instead of bomb with an error - rank.to_i)
|
55
|
+
Movie.new(title, Integer(rank))
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_csv
|
59
|
+
"#{@title}, #{@rank}"
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
# added with iterators
|
65
|
+
def each_snack
|
66
|
+
# take the @snack_cards hash we added in hashes video
|
67
|
+
@snack_carbs.each do |name, carbs|
|
68
|
+
# create 'snack' object from our Struct with the name and carbs from each element
|
69
|
+
snack = Snack.new(name, carbs)
|
70
|
+
# then 'yield' that snack object over to block in playlist.print_status
|
71
|
+
yield snack
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
# added with Hashes
|
81
|
+
def carbs_consumed # total
|
82
|
+
@snack_carbs.values.reduce(0, :+)
|
83
|
+
end
|
84
|
+
|
85
|
+
def ate_snack(snack)
|
86
|
+
# we want to accumulate the carbs for each type snack consumed in this Hash instance for a movie.
|
87
|
+
@snack_carbs[snack.name] += snack.carbs
|
88
|
+
puts "#{@title} let to #{snack.carbs} #{snack.name} carbs being consumed."
|
89
|
+
puts "#{@title}'s snacks: #{@snack_carbs}" # just so we can see the accumulation.
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
# the initialize method has to do with state.
|
95
|
+
# below methods has to do with behaviour expressed as instance methods.
|
96
|
+
|
97
|
+
# below is a virtualized attribute - or attribute that is derived from instance varibles.
|
98
|
+
# can be called from within class
|
99
|
+
# when it's called from the class, the receiver object that's calling
|
100
|
+
# => turns out to be "self" which in the case below is movie3 object. that's why it's cool that
|
101
|
+
# "self", since the next time we call it may be from movie2 object.
|
102
|
+
# see the call below in the to_s method.
|
103
|
+
|
104
|
+
# in the mixin video, we removed methods below and put them in rankable.rb
|
105
|
+
# this encapsulates the notion of rankable and makes it geneic
|
106
|
+
|
107
|
+
# def hit?
|
108
|
+
# @rank >= 10
|
109
|
+
# end
|
110
|
+
|
111
|
+
# def status
|
112
|
+
# hit? ? "Hit" : "Flop"
|
113
|
+
|
114
|
+
# end
|
115
|
+
|
116
|
+
# def normalized_rank
|
117
|
+
# normalized_rank = @rank / 1.0
|
118
|
+
# end
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
# # below we are going to override the spaceship comparison method.
|
123
|
+
# def <=>(other_movie)
|
124
|
+
# # this will compare the passed in movie with the rank of the current movie.?? see sorting.rb
|
125
|
+
# other_movie.rank <=> @rank
|
126
|
+
# end
|
127
|
+
|
128
|
+
|
129
|
+
# what if i wanted to be able to run the listing method by just saying "puts movie3"
|
130
|
+
# well - with no method on call to the object, the default is to run
|
131
|
+
#=> the to_s method - which isn't particularly useful.
|
132
|
+
# so let's create another method called to_s which will override the default to_
|
133
|
+
#=> and make it do they same thing as our listing method.
|
134
|
+
# we could of course just get rid of the listing method - but lets leave it for now
|
135
|
+
#=> just to show the idea.
|
136
|
+
|
137
|
+
def listing
|
138
|
+
"#{@title} initialized with rank of #{@rank}."
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
def to_s
|
143
|
+
# - "Just to confirm, this is run when we call movies."
|
144
|
+
"#{@title} initialized with rank of #{normalized_rank} (#{status})."
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
# an old programming axiom is "Tell - Don't Ask"
|
150
|
+
# meaning - don't ask an object for it's state - rather just Tell it.
|
151
|
+
|
152
|
+
# removed these in mixin video to put in separate mixin module called 'rankable.rb'
|
153
|
+
# def thumbs_up
|
154
|
+
# @rank += 1
|
155
|
+
# end
|
156
|
+
|
157
|
+
# def thumbs_down
|
158
|
+
# @rank -= 1
|
159
|
+
# end
|
160
|
+
|
161
|
+
end # of Movie class
|
162
|
+
end # of Flicks module
|
163
|
+
|
164
|
+
|
165
|
+
|
data/lib/movie3d.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative 'movie'
|
2
|
+
|
3
|
+
module Flicks
|
4
|
+
|
5
|
+
class Movie3D < Movie
|
6
|
+
|
7
|
+
# this new initialize is necessary because we want to add wow_factor
|
8
|
+
# but we don't want to mess up title & rank
|
9
|
+
# therefore the line super(title, rank) which says - let movie handle setting up these instance vars.
|
10
|
+
# then we set up @wow_factor.
|
11
|
+
# now - initalizing a movie requires 3 parameters
|
12
|
+
|
13
|
+
|
14
|
+
# added this in after realizing movie3d_spec wasn't working - ?? see where i missed it
|
15
|
+
attr_reader :wow_factor
|
16
|
+
|
17
|
+
def initialize(title, rank, wow_factor)
|
18
|
+
super(title, rank)
|
19
|
+
@wow_factor = wow_factor
|
20
|
+
end
|
21
|
+
# specialized traits
|
22
|
+
def thumbs_up
|
23
|
+
# wow_factor = 10
|
24
|
+
|
25
|
+
# instead of doing the line below
|
26
|
+
# let's make so that it does whatever 'movie class' is doing times 10
|
27
|
+
# that way, if thumbs up in movie changes, the effect here will be more predictable
|
28
|
+
# @rank += ( 1 * @wow_factor)
|
29
|
+
@wow_factor.times { super }
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# new traits
|
35
|
+
def show_effect
|
36
|
+
# wow_factor = 10
|
37
|
+
puts "Wow!" * @wow_factor
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end # of Movie3d class
|
42
|
+
|
43
|
+
end # of Flicks module
|
44
|
+
|
45
|
+
if __FILE__ == $0
|
46
|
+
# the following can be run before anything is added. it behaves just like movie.rb class
|
47
|
+
|
48
|
+
movie3d = Flicks::Movie3D.new('glee', 5, 10)
|
49
|
+
puts movie3d.title
|
50
|
+
puts movie3d.rank
|
51
|
+
puts movie3d
|
52
|
+
movie3d.show_effect
|
53
|
+
movie3d.thumbs_up
|
54
|
+
puts movie3d
|
55
|
+
|
56
|
+
end
|
data/lib/playlist.rb
ADDED
@@ -0,0 +1,173 @@
|
|
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
|
+
|
9
|
+
# added this after seeing it in their code - don't know how i missed it ???
|
10
|
+
attr_reader :name
|
11
|
+
|
12
|
+
def initialize(name)
|
13
|
+
@name = name
|
14
|
+
@movies = [] # empty array
|
15
|
+
end
|
16
|
+
|
17
|
+
def load(from_file)
|
18
|
+
# copied from files.rb - changed to accept parameter
|
19
|
+
File.readlines(from_file).each do |line|
|
20
|
+
|
21
|
+
# removed to add better code
|
22
|
+
# title, rank = line.split(',')
|
23
|
+
# movie = Movie.new(title, rank.to_i)
|
24
|
+
# # removed after copy from files to add line below ->puts movie
|
25
|
+
# add_movie(movie)
|
26
|
+
add_movie(Movie.from_csv(line))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def save(to_file="movie_rankings.csv")
|
31
|
+
File.open(to_file, "w") do |file|
|
32
|
+
@movies.sort.each do |movie|
|
33
|
+
# removed & replace with csv method implemented in movie class
|
34
|
+
# -> file.puts "#{movie.title}, #{movie.rank}"
|
35
|
+
file.puts movie.to_csv
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_movie(movie)
|
41
|
+
@movies << movie # append the 'movie' passed to the method to array
|
42
|
+
end
|
43
|
+
|
44
|
+
# added parameter 'viewings' as example for blocks. viewings being the number of times to play.
|
45
|
+
def play(viewings)
|
46
|
+
puts "#{@name}'s playlist:"
|
47
|
+
# this sort will use our spaceship override method (<=>) in movie
|
48
|
+
puts @movies.sort
|
49
|
+
|
50
|
+
# the following added after the Symbols&Structs video - see snack_bar.rb
|
51
|
+
snacks = SnackBar::SNACKS
|
52
|
+
puts "\nThere are #{snacks.size} snacks available in the Snack Bar."
|
53
|
+
# now, iterate through the snacks array and print them out as a menu.
|
54
|
+
snacks.each do |snack|
|
55
|
+
puts "#{snack.name} has #{snack.carbs} carbs."
|
56
|
+
end
|
57
|
+
|
58
|
+
1.upto(viewings) do |count|
|
59
|
+
puts "\nViewing #{count}:"
|
60
|
+
@movies.each do |movie|
|
61
|
+
WaldorfAndStatler.review(movie)
|
62
|
+
# added after Symbols&Struts - get a random snace with a movie viewing.
|
63
|
+
snack = SnackBar.random
|
64
|
+
# added with Hashes
|
65
|
+
movie.ate_snack(snack)
|
66
|
+
|
67
|
+
|
68
|
+
# took out on Hashes ->puts "#{movie.title} led to #{snack.carbs} #{snack.name} carbs being consumed."
|
69
|
+
|
70
|
+
puts movie
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def total_carbs_consumed
|
76
|
+
|
77
|
+
@movies.reduce(0) do |sum, movie|
|
78
|
+
sum + movie.carbs_consumed
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
def print_stats
|
85
|
+
puts "\n#{@name}'s Stats:"
|
86
|
+
|
87
|
+
puts "#{total_carbs_consumed} total cards consumed."
|
88
|
+
|
89
|
+
@movies.sort.each do |movie|
|
90
|
+
puts "\n#{movie.title}'s snack totals:"
|
91
|
+
# added in iterators - add a method 'each_snack' in movie class
|
92
|
+
movie.each_snack do |snack|
|
93
|
+
puts "#{snack.carbs} total #{snack.name} carbs"
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
puts "#{movie.carbs_consumed} grand total carbs."
|
98
|
+
end
|
99
|
+
|
100
|
+
hits, flops = @movies.partition { |movie| movie.hit? }
|
101
|
+
|
102
|
+
puts "\nHits:"
|
103
|
+
puts hits.sort
|
104
|
+
|
105
|
+
# when we call puts on an array it will call to_s on each of those elements
|
106
|
+
# => so the to_s method in movie will be called.
|
107
|
+
|
108
|
+
puts "\nFlops:"
|
109
|
+
puts flops.sort
|
110
|
+
end
|
111
|
+
|
112
|
+
end # -> of playlist class
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
end # -> of Flicks module
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
# below is tester code for the Movie & Playlist class
|
124
|
+
# '__FILE__' is the varible that holds the file name for this file
|
125
|
+
# '$0' is the varible that holds the file that is running.
|
126
|
+
# so this code only gets run when we run this file
|
127
|
+
# if this class is getting called from another program - it does not run
|
128
|
+
|
129
|
+
if __FILE__ == $0
|
130
|
+
|
131
|
+
# the .new method expects there to be an initialize method
|
132
|
+
movie1 = Flicks::Movie.new("goonies",10)
|
133
|
+
movie1.thumbs_down
|
134
|
+
puts movie1.listing
|
135
|
+
movie2 = Flicks::Movie.new("ghostbusters",9)
|
136
|
+
puts movie2.listing
|
137
|
+
movie3 = Flicks::Movie.new("goldfinger",100)
|
138
|
+
# below runs method that affects behaviour
|
139
|
+
movie3.thumbs_up
|
140
|
+
# allows access to current state.
|
141
|
+
puts movie3
|
142
|
+
# below made possible by attr_reader
|
143
|
+
puts movie3.title
|
144
|
+
puts movie3.rank
|
145
|
+
movie3.title = ("goonies 2.0")
|
146
|
+
puts movie3.title
|
147
|
+
puts movie3.normalized_rank
|
148
|
+
|
149
|
+
|
150
|
+
puts "begin object_interact code"
|
151
|
+
playlist1 = Flicks::Playlist.new("Kermit")
|
152
|
+
playlist1.add_movie(movie1)
|
153
|
+
playlist1.add_movie(movie2)
|
154
|
+
playlist1.add_movie(movie3)
|
155
|
+
playlist1.play(1)
|
156
|
+
|
157
|
+
# add another playlist
|
158
|
+
playlist2 = Flicks::Playlist.new("Fozzie")
|
159
|
+
# put a movie in that playlist
|
160
|
+
playlist2.add_movie(movie3)
|
161
|
+
|
162
|
+
# add a new move using the Movie class
|
163
|
+
movie4 = Flicks::Movie.new("Gremlins", 15)
|
164
|
+
|
165
|
+
# now add that movie to playlist2
|
166
|
+
playlist2.add_movie(movie4)
|
167
|
+
|
168
|
+
# and now play - which actually just displays the playlist
|
169
|
+
playlist2.play(1)
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
|
data/lib/rankable.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Flicks
|
2
|
+
module Rankable
|
3
|
+
|
4
|
+
# changed all the '@rank' to rank
|
5
|
+
# it is considered better to depend
|
6
|
+
# => on a method or an attribute rather than an instance varible in the host class.
|
7
|
+
|
8
|
+
def thumbs_up
|
9
|
+
self.rank += 1
|
10
|
+
end
|
11
|
+
|
12
|
+
def thumbs_down
|
13
|
+
self.rank -= 1
|
14
|
+
end
|
15
|
+
def hit?
|
16
|
+
self.rank >= 10
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def status
|
21
|
+
hit? ? "Hit" : "Flop"
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
def normalized_rank
|
26
|
+
normalized_rank = self.rank / 1.0
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
# below we are going to override the spaceship comparison method.
|
32
|
+
# we changed the spaceship to just 'other' to make it more generic
|
33
|
+
def <=>(other)
|
34
|
+
# this will compare the passed in movie with the rank of the current movie.?? see sorting.rb
|
35
|
+
other.rank <=> self.rank
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
end # of module Rankable
|
40
|
+
end # of module Flicks
|
data/lib/snack_bar.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
# we could do the following class - but it may be overkill - we can just use a struct
|
3
|
+
|
4
|
+
# class Snack
|
5
|
+
# attr_reader :name, :carbs
|
6
|
+
|
7
|
+
# def initialize(name, carbs)
|
8
|
+
# @name = name
|
9
|
+
# @carbs = carbs
|
10
|
+
# end
|
11
|
+
|
12
|
+
# end
|
13
|
+
|
14
|
+
# the struct below will do the same thing
|
15
|
+
module Flicks
|
16
|
+
|
17
|
+
Snack = Struct.new(:name, :carbs)
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
# the Struct above could be in module but leave out for now
|
22
|
+
module SnackBar
|
23
|
+
|
24
|
+
# constant SNACKS array of Struct instances...
|
25
|
+
SNACKS = [
|
26
|
+
Snack.new(:popcorn, 20),
|
27
|
+
Snack.new(:candy, 15),
|
28
|
+
Snack.new(:nachos, 40),
|
29
|
+
Snack.new(:pretzel, 10),
|
30
|
+
Snack.new(:soda, 5)
|
31
|
+
]
|
32
|
+
|
33
|
+
# now we can add a method to our module that gets a random snack
|
34
|
+
# module methods start with self.
|
35
|
+
def self.random
|
36
|
+
|
37
|
+
# sample is a ruby method that gets a random element from an array.??? cool...
|
38
|
+
SNACKS.sample
|
39
|
+
end
|
40
|
+
|
41
|
+
end # of Snack Struct
|
42
|
+
end # of module Flicks
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
if __FILE__ == $0
|
50
|
+
|
51
|
+
|
52
|
+
# to get access, we use our module name, then the 'scope resolution operator' (::) then the constant.
|
53
|
+
|
54
|
+
popcorn = Snack.new('popcorn', 20)
|
55
|
+
puts popcorn.name
|
56
|
+
puts popcorn.carbs
|
57
|
+
|
58
|
+
candy = Snack.new('candy', 15)
|
59
|
+
puts candy.name
|
60
|
+
puts candy.carbs
|
61
|
+
|
62
|
+
puts SnackBar::SNACKS
|
63
|
+
|
64
|
+
snack = SnackBar.random
|
65
|
+
puts snack
|
66
|
+
puts "Enjoy your #{snack.name} (#{snack.carbs} carbs)."
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require_relative 'movie'
|
2
|
+
|
3
|
+
module Flicks
|
4
|
+
|
5
|
+
module WaldorfAndStatler
|
6
|
+
|
7
|
+
# use modules when you don't need objects or state but rather
|
8
|
+
# -> methods that takes parameters such as objects
|
9
|
+
# use as a bucket of related methods
|
10
|
+
# also use as mixins and namespaces
|
11
|
+
|
12
|
+
# you can't instanstiate a module
|
13
|
+
|
14
|
+
# a method can be called from a class as an instance of the class
|
15
|
+
# but in a module, we can instanctiate so we have to add "self" to the method to be to call it.
|
16
|
+
# the self allows us to call it directely as below.
|
17
|
+
|
18
|
+
def self.review(movie)
|
19
|
+
number_rolled = roll_die
|
20
|
+
# in the playlist_spec file, we'll stub the number_rolled for testing
|
21
|
+
case number_rolled
|
22
|
+
when 1..2
|
23
|
+
movie.thumbs_down
|
24
|
+
puts "#{movie.title} got a thumbs down for a low roll."
|
25
|
+
when 3..4
|
26
|
+
puts "#{movie.title} was skipped."
|
27
|
+
else
|
28
|
+
movie.thumbs_up # reward for rolling 5 or better
|
29
|
+
puts "#{movie.title} got a thumbs up for rolling 5 or better!"
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.roll_die
|
35
|
+
rand(1..6)
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
end # of module WaldorfAndStatler
|
40
|
+
end # of module Flicks
|
41
|
+
|
42
|
+
|
43
|
+
# WaldorfAndStatler.review
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require '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
|
data/spec/movie_spec.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
# rspec convenction is to test class with file called "ClassName_spec.rb"
|
2
|
+
|
3
|
+
|
4
|
+
# the following will run all files in the current directory with _spec from the command line
|
5
|
+
# rspec . --color --format doc
|
6
|
+
|
7
|
+
|
8
|
+
# first thing is to requre class
|
9
|
+
|
10
|
+
require 'movie'
|
11
|
+
|
12
|
+
module Flicks
|
13
|
+
|
14
|
+
describe Movie do
|
15
|
+
|
16
|
+
before do
|
17
|
+
|
18
|
+
# we add the '@' to these varibles makeing them instance varibles so we can call them in the code.
|
19
|
+
@initial_rank = 10
|
20
|
+
@movie = Movie.new("goonies", @initial_rank)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "has a capitalized title" do
|
24
|
+
|
25
|
+
@movie.title.should == "Goonies"
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
it "has a rank of 10" do
|
30
|
+
|
31
|
+
@movie.rank.should == @initial_rank
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
it "has a string representation" do
|
36
|
+
|
37
|
+
@movie.to_s.should == "Goonies initialized with rank of #{@initial_rank/1.0} (Hit)."
|
38
|
+
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
it "increased rank by 1 when given a thumbs up" do
|
45
|
+
|
46
|
+
@movie.thumbs_up
|
47
|
+
|
48
|
+
@movie.rank.should == @initial_rank + 1
|
49
|
+
end
|
50
|
+
|
51
|
+
it "decreased rank by 1 when given a thumbs down" do
|
52
|
+
|
53
|
+
@movie.thumbs_down
|
54
|
+
|
55
|
+
@movie.rank.should == @initial_rank - 1
|
56
|
+
end
|
57
|
+
|
58
|
+
context "created with a default rank" do
|
59
|
+
before do
|
60
|
+
@movie = Movie.new("goonies")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "has a rank of 0" do
|
64
|
+
@movie.rank.should == 0
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
context "with a rank of at least 10" do
|
70
|
+
before do
|
71
|
+
@movie = Movie.new("goonies", 10)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "is a hit" do
|
75
|
+
@movie.should be_hit # took out the .hit? - was be_true or == true
|
76
|
+
end
|
77
|
+
|
78
|
+
it "is a hit status" do
|
79
|
+
@movie.status.should == "Hit"
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
context "with a rank of less than 10" do
|
85
|
+
before do
|
86
|
+
@movie = Movie.new("goonies", 9)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "is NOT a hit" do
|
90
|
+
@movie.should_not be_hit # took out the .hit? without the _not - was be_false or == false
|
91
|
+
end
|
92
|
+
|
93
|
+
it "has a flop status" do
|
94
|
+
@movie.status.should == "Flop"
|
95
|
+
end
|
96
|
+
|
97
|
+
it "is sorted by decreasing rank" do
|
98
|
+
movie1 = Movie.new("goonies", 100)
|
99
|
+
movie2 = Movie.new("ghostbusters", 200)
|
100
|
+
movie3 = Movie.new("goldfinger", 300)
|
101
|
+
|
102
|
+
movies = [movie1, movie2, movie3]
|
103
|
+
|
104
|
+
movies.sort.should == [movie3, movie2, movie1]
|
105
|
+
end
|
106
|
+
|
107
|
+
it "computes carbs consumed as the sum of all snack carbs consumed" do
|
108
|
+
@movie.carbs_consumed.should == 0
|
109
|
+
|
110
|
+
@movie.ate_snack(Snack.new(:popcorn, 10))
|
111
|
+
|
112
|
+
@movie.carbs_consumed.should == 10
|
113
|
+
|
114
|
+
@movie.ate_snack(Snack.new(:popcorn, 10))
|
115
|
+
|
116
|
+
@movie.carbs_consumed.should == 20
|
117
|
+
|
118
|
+
@movie.ate_snack(Snack.new(:soda, 5))
|
119
|
+
|
120
|
+
@movie.carbs_consumed.should == 25
|
121
|
+
end
|
122
|
+
|
123
|
+
it "yields each snack" do
|
124
|
+
@movie.ate_snack(Snack.new(:popcorn, 10))
|
125
|
+
@movie.ate_snack(Snack.new(:popcorn, 10))
|
126
|
+
@movie.ate_snack(Snack.new(:soda, 5))
|
127
|
+
|
128
|
+
yielded = []
|
129
|
+
@movie.each_snack do |snack|
|
130
|
+
yielded << snack
|
131
|
+
end
|
132
|
+
|
133
|
+
yielded.should == [Snack.new(:popcorn, 20), Snack.new(:soda, 5)]
|
134
|
+
end
|
135
|
+
|
136
|
+
it "can be instantiated from a CSV string" do
|
137
|
+
movie = Movie.from_csv("goonies,10")
|
138
|
+
|
139
|
+
movie.title.should == "Goonies"
|
140
|
+
movie.rank.should == 10
|
141
|
+
end
|
142
|
+
|
143
|
+
it "can be serialized to a CSV string" do
|
144
|
+
movie = Movie.new("Goonies", 10)
|
145
|
+
|
146
|
+
movie.to_csv.should == "Goonies, 10"
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
end # of describe
|
152
|
+
|
153
|
+
end # of Flicks module
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'playlist'
|
2
|
+
|
3
|
+
module Flicks
|
4
|
+
|
5
|
+
# the following will run all files in the current directory with _spec from the command line
|
6
|
+
# rspec . --color --format doc
|
7
|
+
|
8
|
+
describe Playlist do
|
9
|
+
before do
|
10
|
+
@playlist = Playlist.new("Bobby")
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
it "has a name" do
|
15
|
+
@playlist.name.should == "Bobby"
|
16
|
+
end
|
17
|
+
|
18
|
+
context "being played with one movie" do
|
19
|
+
before do
|
20
|
+
@initial_rank = 10
|
21
|
+
@movie = Movie.new("goonies", @initial_rank)
|
22
|
+
@playlist.add_movie(@movie)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "gives the movie a thumbs up if a high number is rolled" do
|
26
|
+
# stub the roll_die method for testing since we don't want the random number for the test.
|
27
|
+
WaldorfAndStatler.stub(:roll_die).and_return(6)
|
28
|
+
|
29
|
+
@playlist.play(2)
|
30
|
+
|
31
|
+
@movie.rank.should == @initial_rank + 2
|
32
|
+
|
33
|
+
WaldorfAndStatler.stub(:roll_die).and_return(5)
|
34
|
+
@playlist.play(2)
|
35
|
+
@movie.rank.should == @initial_rank + 4
|
36
|
+
end
|
37
|
+
|
38
|
+
it "skips the movie if a medium number is rolled" do
|
39
|
+
WaldorfAndStatler.stub(:roll_die).and_return(4)
|
40
|
+
|
41
|
+
@playlist.play(2)
|
42
|
+
|
43
|
+
@movie.rank.should == @initial_rank
|
44
|
+
WaldorfAndStatler.stub(:roll_die).and_return(3)
|
45
|
+
@playlist.play(2)
|
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
|
+
@playlist.play(2)
|
52
|
+
@movie.rank.should == @initial_rank - 2
|
53
|
+
|
54
|
+
WaldorfAndStatler.stub(:roll_die).and_return(1)
|
55
|
+
@playlist.play(2)
|
56
|
+
@movie.rank.should == @initial_rank - 4
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
end # -> of Describe Playlist
|
63
|
+
|
64
|
+
end # -> of Flicks module
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require '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,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rms_flicks
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Pragmatic Studio student
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !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: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: ! "This is an example application used in The Pragmatic Studio's \nRuby
|
31
|
+
Programming course, as described at\n\n http://pragmaticstudio.com\n\nThis code
|
32
|
+
is Copyright 2012 The Pragmatic Studio. See the LICENSE file."
|
33
|
+
email: rmckinleys@gmail.com
|
34
|
+
executables:
|
35
|
+
- flicks
|
36
|
+
extensions: []
|
37
|
+
extra_rdoc_files: []
|
38
|
+
files:
|
39
|
+
- bin/flicks
|
40
|
+
- bin/movie_rankings.csv
|
41
|
+
- bin/movies.csv
|
42
|
+
- lib/movie.rb
|
43
|
+
- lib/movie3d.rb
|
44
|
+
- lib/playlist.rb
|
45
|
+
- lib/rankable.rb
|
46
|
+
- lib/snack_bar.rb
|
47
|
+
- lib/waldorf_and_statler.rb
|
48
|
+
- spec/movie3d_spec.rb
|
49
|
+
- spec/movie_spec.rb
|
50
|
+
- spec/playlist_spec.rb
|
51
|
+
- spec/snack_bar_spec.rb
|
52
|
+
- LICENSE
|
53
|
+
- README
|
54
|
+
homepage: http://pragmaticstudio.com
|
55
|
+
licenses: []
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '1.9'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 1.8.24
|
75
|
+
signing_key:
|
76
|
+
specification_version: 3
|
77
|
+
summary: Plays and reviews movies
|
78
|
+
test_files:
|
79
|
+
- spec/movie3d_spec.rb
|
80
|
+
- spec/movie_spec.rb
|
81
|
+
- spec/playlist_spec.rb
|
82
|
+
- spec/snack_bar_spec.rb
|