diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..25e8cbb Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 18d7cf1..87673ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +./final *.gem *.rbc .bundle diff --git a/README.md b/README.md index fdcebc2..4795b4e 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,8 @@ Week 5 Week 6 * Mid-term due! * Projects intro -* Control -* Exceptions +* Gems +* CI Week 7 * Cucumber @@ -45,14 +45,14 @@ Week 7 * Refactoring Week 8 -* Gems -* CI - -Week 9 * Metaprogramming * Duck typing * Monkey patching +Week 9 +* Control +* Exceptions + Week 10 * Final due! * Project due! diff --git a/callchain.rb b/callchain.rb new file mode 100644 index 0000000..9be5e63 --- /dev/null +++ b/callchain.rb @@ -0,0 +1,33 @@ +Class Object + def call_chain + "object" + end +end + +Class Animal + def call_chain + "#{self}.#{super}" + end +end + +module NamedThing + def call_chain + "#{self}.#{super}" + end +end + +class Person < Animal + include NamedThing + def call_chain + "#{self}.#{super} + end +end + +class Renee < Person + def call_chain + "#{self}.#{super}" + end +end + + + \ No newline at end of file diff --git a/final/Screen Shot 2012-12-03 at 12.34.21 AM.png b/final/Screen Shot 2012-12-03 at 12.34.21 AM.png new file mode 100644 index 0000000..ff20659 Binary files /dev/null and b/final/Screen Shot 2012-12-03 at 12.34.21 AM.png differ diff --git a/final/musicscrape.rb b/final/musicscrape.rb new file mode 100644 index 0000000..d6204b6 --- /dev/null +++ b/final/musicscrape.rb @@ -0,0 +1,8 @@ +#require 'rubygems' +#require 'crack' +#require 'open-uri' +require 'rest-client' + +url='http://www.thestranger.com/seattle/Music' #The url for the web page we want + +puts (RestClient.get(url)) \ No newline at end of file diff --git a/final/musicscrape_spec.rb b/final/musicscrape_spec.rb new file mode 100644 index 0000000..5dc8a79 --- /dev/null +++ b/final/musicscrape_spec.rb @@ -0,0 +1,41 @@ +require "#{File.dirname(__FILE__)}/musicscrape" + +describe Scrape do + before do + @scrape = Scrape.new(:strangermusic) + @scrape.url = "http://www.thestranger.com/seattle/Music" + end + it "Should load the stranger music page" do + @scrape.load_page.should not eq "" #I mean the string shouldn't be empty + end + it "Should Identify the beginning of the recommended shows"do + end + it "Should Idenfify the end of the recommended shows" do + end + it "Should throw away the rest of the text" do + end +end + +describe Parse do + it "Should pick out all the event names" do + end + it "Should pick out all the event locations" do + end + it "Should pick out all the dates" do + end + it "Should pick out all the prices" do + end +end + +describe PushToGoogle do + it "Should send each event to your google calendar" do + end +end + + +describe GetUserInfo do + it "Should get your username" do + end + it "Should get your password" do + end +end \ No newline at end of file diff --git a/final/prep_notes.txt b/final/prep_notes.txt new file mode 100644 index 0000000..a0ca770 --- /dev/null +++ b/final/prep_notes.txt @@ -0,0 +1,48 @@ +this month's calendar +http://www.seattle.gov/UTIL/WARP/home/alp?openApp=CC&address=6408%2044TH%20AVE%20S + +Print next year's calendar +www.seattle.gov/UTIL/WARP/PrintCollectionCalendar/Index?Account=&WhichYear=Next&Address=6408~~44TH~AVE~S~~~100~6408%2044TH%20AVE%20S + +Recycling Icon +Garbage Icon +Recycle Icon + +require 'rubygems' +require 'crack' +require 'open-uri' +require 'rest-client' + +url='http://en.wikipedia.org/w/api.php?action=opensearch&search=At&namespace=0' + +puts Crack::JSON.parse(RestClient.get(url)) + +I don't really want to publish that gem on the web, and it's a little too ambitious. I'm going to practice my web scraping with something similar. + +http://www.thestranger.com/seattle/Music + +pull all the recommended events and push them to your google calendar. + +sudo gem install googlecalendar +Usage +Adding an Event +require 'googlecalendar' +g = GData.new +g.login('REPLACE_WITH_YOUR_MAIL@gmail.com', 'REPLACE_WITH_YOUR_PASSWORD') +event = { :title => 'title', + :content => 'content', + :author => 'pub.cog', + :email => 'pub.cog@gmail.com', + :where => 'Toulouse,France', + :startTime => '2007-06-06T15:00:00.000Z', + :endTime => '2007-06-06T17:00:00.000Z'} +g.new_event(event) + +require 'rubygems' +require 'crack' +require 'open-uri' +require 'rest-client' + +url='http://en.wikipedia.org/w/api.php?action=opensearch&search=At&namespace=0' + +puts Crack::JSON.parse(RestClient.get(url)) \ No newline at end of file diff --git a/mid_term/even_number.rb b/mid_term/even_number.rb new file mode 100644 index 0000000..fa9fc6e --- /dev/null +++ b/mid_term/even_number.rb @@ -0,0 +1,21 @@ +class EvenNumber + include Comparable + attr_reader :value + + def self.new(value) + return false if value.odd? + super + end + + def initialize(value) + @value = value + end + + def succ + EvenNumber.new(@value + 2) + end + + def <=> (other) + @value <=> other.value + end +end \ No newline at end of file diff --git a/mid_term/even_number_spec.rb b/mid_term/even_number_spec.rb new file mode 100644 index 0000000..3e254c2 --- /dev/null +++ b/mid_term/even_number_spec.rb @@ -0,0 +1,27 @@ + # - Write a passing rspec file called even_number_spec.rb that tests a class + # called EvenNumber. + # - The EvenNumber class should: + # - Only allow even numbers + # - Get the next even number + # - Compare even numbers + # - Generate a range of even numbers + +require './even_number.rb' + +describe EvenNumber do + it "should only allow even numbers" do + EvenNumber.new(5).should be_false + end + + it "should get the next even number" do + EvenNumber.new(2).succ.should == EvenNumber.new(4) + end + + it "should compare even numbers" do + (EvenNumber.new(2) < EvenNumber.new(4)).should be_true + end + + it "should generate a range of even numbers" do + (EvenNumber.new(2)..EvenNumber.new(8)).should be_a Range + end +end \ No newline at end of file diff --git a/mid_term/mid_term_spec.rb b/mid_term/mid_term_spec.rb index e8eed88..0556a97 100644 --- a/mid_term/mid_term_spec.rb +++ b/mid_term/mid_term_spec.rb @@ -1,73 +1,73 @@ require "#{File.dirname(__FILE__)}/turkey" describe Turkey do - + before do @turkey = Turkey.new(10) end - + it "should report the turkey weight" do @turkey.weight.should equal 10 end - + it "should be a kind of animal" do @turkey.kind_of?(Animal).should be_true end - + it "should gobble speak" do @turkey.gobble_speak("Hello I Am a Turkey. Please Don't Eat Me.").should eq "Gobble Gobble Gobble gobble Gobble. Gobble Gobb'le Gobble Gobble." end - + end require "#{File.dirname(__FILE__)}/thanksgiving_dinner" describe ThanksgivingDinner do - before do + before do @t_dinner = ThanksgivingDinner.new(:vegan) @t_dinner.guests = ["Aunt Petunia", "Uncle Vernon", "Aunt Marge", "Dudley", "Harry"] # I know I just made a British family celebrate Thanksgiving, but it could be worse: It could have been the 4th of July! :) end - + it "should be a kind of dinner" do @t_dinner.kind_of?(Dinner).should be_true end - + # Use inject here it "should sum the letters in each guest name for the seating chart size" do @t_dinner.seating_chart_size.should eq 45 end - + it "should provide a menu" do @t_dinner.respond_to?(:menu).should be_true end - + context "#menu" do - + it "should have a diet specified" do @t_dinner.menu[:diet].should eq :vegan end - + it "should have proteins" do @t_dinner.menu[:proteins].should eq ["Tofurkey", "Hummus"] end - + it "should have vegetables" do @t_dinner.menu[:veggies].should eq [:ginger_carrots , :potatoes, :yams] end - + # Dinners don't always have dessert, but ThanksgivingDinners always do! it "should have desserts" do @t_dinner.menu[:desserts].should eq({:pies => [:pumkin_pie], :other => ["Chocolate Moose"], :molds => [:cranberry, :mango, :cherry]}) end - + end - + # Use String interpolation, collection methods, and string methods for these two examples it "should return what is on the dinner menu" do @t_dinner.whats_for_dinner.should eq "Tonight we have proteins Tofurkey and Hummus, and veggies Ginger Carrots, Potatoes, and Yams." end - + it "should return what is on the dessert menu" do @t_dinner.whats_for_dessert.should eq "Tonight we have 5 delicious desserts: Pumkin Pie, Chocolate Moose, and 3 molds: Cranberry and Mango and Cherry." end diff --git a/mid_term/questions.txt b/mid_term/questions.txt index b0e27a8..0eba895 100644 --- a/mid_term/questions.txt +++ b/mid_term/questions.txt @@ -11,16 +11,33 @@ Instructions for Mid-Term submission and Git Review (10pts): Questions (20pts): - What are the three uses of the curly brackets {} in Ruby? + 1. String interpolation: "#{1+1}" + 2. Hash instantiation: {:key => "value"} + 3. Block/lambda notation: {puts "hello"} + - What is a regular expression and what is a common use for them? + A Regular expression is a pattern used to search text. A common use for them is for verifying the format of user input, like email addresses or phone numbers. + - What is the difference between how a String, a symbol, a FixNum, and a Float are stored in Ruby? +A String is stored as a collection of characters (bytes) and the value of a string instance can change. A Symbol is a fixed name in ruby and is stored as an integer, so it takes up much less space than a string. A FixNum is an integer in Ruby and does not change its value. It is stored the same way as a symbol (you can think of symbols as Fixed Strings). Floats can have their value change and are stored like a string: each byte of the float is stored and can change individually. + - Are these two statements equivalent? Why or Why Not? 1. x, y = "hello", "hello" 2. x = y = "hello" +No, in the first example x and y point to different objects, in the second they point to the same object. In # 2 if y changes x will change and vice versa. In # 1 if y changes x does not change and vice versa. + - What is the difference between a Range and an Array? +A Range is an object that denotes a sequence between two objects (lower/min and higher/max). It does not store every element of the sequence, only the min and max. An array is an ordered list of many objects. Each object in an array is stored and cannot necessarily be determined by the prior object in the array. + - Why would I use a Hash instead of an Array? +If I had data which I wanted to reference by meta-data instead of by order I would use a hash. For example, if I had a set of attributes common to a collection of things, I would use a hash so I could look across my data (or search) by the data's attribute dimensions. + - What is your favorite thing about Ruby so far? +.map + - What is your least favorite thing about Ruby so far? - +nil.object_id => 4 + Programming Problems (10pts each): - Write a passing rspec file called even_number_spec.rb that tests a class called EvenNumber. - The EvenNumber class should: diff --git a/mid_term/thanksgiving_dinner.rb b/mid_term/thanksgiving_dinner.rb new file mode 100644 index 0000000..20b03ec --- /dev/null +++ b/mid_term/thanksgiving_dinner.rb @@ -0,0 +1,78 @@ +class String + def titlecase + self.gsub(/\b\w/){|f| f.upcase} + end + + def humanize + self.gsub('_', ' ').titlecase + end +end + +module MenuFinder + MENUS = { + :vegan => { + :diet => :vegan, + :proteins => ["Tofurkey", "Hummus"], + :veggies => [:ginger_carrots , :potatoes, :yams] + } + } + def find_menu(kind) + MENUS[kind] + end + def find_dessert + @menu[:desserts] = {:pies => [:pumkin_pie], + :other => ["Chocolate Moose"], + :molds => [:cranberry, :mango, :cherry]} + end +end + +class Dinner + include MenuFinder + attr_accessor :menu, :guests, :kind + def initialize(kind) + @kind = kind + @menu = find_menu(kind) + end + def seating_chart_size + guests.inject(0){|sum,g| sum += g.size} + end + + def proteins + @menu[:proteins].map{|w| w.titlecase}.join(' and ') + end + + def veggies + @menu[:veggies].map{|w| w.to_s.humanize}.join(', ').gsub(/, \w*\z/){|w| w.gsub(',', ', and')} + end + + def whats_for_dinner + "Tonight we have proteins #{proteins}, and veggies #{veggies}." + end +end + +class ThanksgivingDinner < Dinner + def number_of_desserts + @menu[:desserts].map{|k,v| v}.flatten.count + end + + def pies + @menu[:desserts][:pies].map{|s| s.to_s.humanize}.join(',') + end + + def other + @menu[:desserts][:other].join(',') + end + + def number_of_molds + @menu[:desserts][:molds].count + end + + def molds + @menu[:desserts][:molds].map{|s| s.to_s.titlecase}.join(' and ') + end + + def whats_for_dessert + find_dessert + "Tonight we have #{number_of_desserts} delicious desserts: #{pies}, #{other}, and #{number_of_molds} molds: #{molds}." + end +end diff --git a/mid_term/turkey.rb b/mid_term/turkey.rb new file mode 100644 index 0000000..38498fb --- /dev/null +++ b/mid_term/turkey.rb @@ -0,0 +1,24 @@ +class Animal +end +class Turkey < Animal + attr_accessor :weight + def initialize(weight) + @weight = weight + end + + def gobble_speak(monkey_talk) + monkey_talk.gsub(/\b\w*/) do |w| + if w[0] =~ /[A-Z]/ + "Gobble" + elsif w[0] =~ /[a-z]/ + "gobble" + end + end.gsub(/\b\w*'\w*\b/) do |w| + if w[0]=='G' + "Gobb'le" + else + "gobb'le" + end + end + end +end diff --git a/mid_term/wish_list.rb b/mid_term/wish_list.rb new file mode 100644 index 0000000..0677f36 --- /dev/null +++ b/mid_term/wish_list.rb @@ -0,0 +1,9 @@ +class WishList + include Enumerable + attr_accessor :wishes + def each + @wishes.each_with_index do |w,i| + yield "#{i+1}. #{w}" + end + end +end \ No newline at end of file diff --git a/week1/.DS_Store b/week1/.DS_Store new file mode 100644 index 0000000..dc4dba2 Binary files /dev/null and b/week1/.DS_Store differ diff --git a/week1/exercises/lor b/week1/exercises/lor new file mode 100644 index 0000000..e69de29 diff --git a/week1/exercises/moon_spec.rb b/week1/exercises/moon_spec.rb new file mode 100644 index 0000000..21ba3e3 --- /dev/null +++ b/week1/exercises/moon_spec.rb @@ -0,0 +1,6 @@ +describe "MoonPlugin" do + context "When the moon is full" do + it "should tell us it's a Full Moon" do + "Bryan".should include("ee") + end +end \ No newline at end of file diff --git a/week1/exercises/rspec_spec.rb b/week1/exercises/rspec_spec.rb index f4c2f0b..46ac045 100644 --- a/week1/exercises/rspec_spec.rb +++ b/week1/exercises/rspec_spec.rb @@ -43,7 +43,7 @@ # When this example fails, # it will show "expected" as 2, and "actual" as 1 - 1.should eq 2 + 1.should eq 1 #changed "...eq 2" to "...eq 1" end @@ -77,6 +77,19 @@ # Fix the Failing Test # Order of Operations is Please Excuse My Dear Aunt Sally: # Parentheses, Exponents, Multiplication, Division, Addition, Subtraction +<<<<<<< HEAD + (1+2-5*6/2).should eq -12 # changed -10 to -12 -BW + end + it "should count the charaters in your name" do + "Bryan".should have(5).characters + end + it "should check basic math" do + 18.should eq 9*2 + end + it "should check basic spelling" do + "winning".should include("inni") + end +======= (1+2-5*6/2).should eq -12 end it "should count the charaters in your name" do @@ -90,6 +103,7 @@ it "should check basic spelling" do "Field".should include('ie') end +>>>>>>> 476e4b543ee68aad8bb809afdfe2207afd39e8e5 end end diff --git a/week1/homework/.DS_Store b/week1/homework/.DS_Store new file mode 100644 index 0000000..874c9d1 Binary files /dev/null and b/week1/homework/.DS_Store differ diff --git a/week1/homework/questions.txt b/week1/homework/questions.txt index 0adfd69..df0a7a4 100644 --- a/week1/homework/questions.txt +++ b/week1/homework/questions.txt @@ -3,6 +3,24 @@ Chapter 3 Classes, Objects, and Variables p.90-94 Strings 1. What is an object? +<<<<<<< HEAD +An object is an instance of a class. Each object has all the characteristics of the class but it's instance variables are allowed to have values that are specific to the object. In Ruby "everything" is an object, even what looks like a string variable is actually just a pointer to an object. + +2. What is a variable? +In Ruby a variable is a pointer to an object. The variable holds the memory address of the object. So if you do something like myobject = myclass.new and they you say yourobject = myobject you end up with one object and two references to it. + +3. What is the difference between an object and a class? +A class defines a data structure, but you can't actually do anything with it until you create an object as a new instance of the class. + +4. What is a String? +A String is an object of class String. It holds a sequence of characters + +5. What are three messages that I can send to a string object? Hint: think methods +split, chomp, squeeze! + +6. What are two ways of defining a String literal? Bonus: What is the difference between the two? +single quotes and double quotes. Single quotes only allow two escape sequences \', and \\. Double quotes allow you to put a bunch of whitespace characters in the quotes and embed variables in the quotes. +======= An object is a representation in memory of a specific concept or thing that the Ruby interpreter knows about. 2. What is a variable? @@ -22,3 +40,4 @@ split - returns an array of strings made up of the original string separated on 6. What are two ways of defining a String literal? Bonus: What is the difference between the two? Single quotes ex: '' and Double quotes ex: "". The single qoutes allow for 2 escape characters: \' and \\ . The double qouted string literal allows for many different escaped special characters (like \n is a line break) and allows for string interpolation, or the injection of evaluated Ruby code into the string ex: "Hello #{my_name}". The single qouted string takes up much less memory than a doulbe qouted string with interpolation. Without interpolation, both are about the same. +>>>>>>> 476e4b543ee68aad8bb809afdfe2207afd39e8e5 diff --git a/week1/homework/strings_and_rspec_spec.rb b/week1/homework/strings_and_rspec_spec.rb index 2f188f6..54ce997 100644 --- a/week1/homework/strings_and_rspec_spec.rb +++ b/week1/homework/strings_and_rspec_spec.rb @@ -12,15 +12,21 @@ before(:all) do @my_string = "Renée is a fun teacher. Ruby is a really cool programming language" end + it "should be able to count the charaters" do @my_string.should have(@my_string.size).characters end + it "should be able to split on the . charater" do + pending + result = @mystring.split(".") #do something with @my_string here result = @my_string.split('.') result.should have(2).items end + it "should be able to give the encoding of the string" do @my_string.encoding.should eq (Encoding.find("UTF-8")) end + end end diff --git a/week2/homework/questions.txt b/week2/homework/questions.txt index 4cfc0a3..72ff76f 100644 --- a/week2/homework/questions.txt +++ b/week2/homework/questions.txt @@ -3,6 +3,24 @@ Containers, Blocks, and Iterators Sharing Functionality: Inheritance, Modules, and Mixins 1. What is the difference between a Hash and an Array? +<<<<<<< HEAD +Both are collections of object references. But an array is indexed by integers while a hash is indexed by whatever kind of object you want to use. An index in a has is called a key. + +2. When would you use an Array over a Hash and vice versa? +You'd use an array if the data you're storing naturally comes with integer numbers attached to it, or if you need to iterate over the data using a for loop. I think of scientific data where you're taking a sample every .1 seconds and you need to store all the data points in order. + +A hash is better for a database type of application like when you need to put in a person's name and pull up all the information associated with the person. But I just learned that Ruby remembers the order in which you entered items into a hash so you can iterate over it just like you could an array. So it seems like in Ruby you could use a hash for pretty much everything. + +3. What is a module? Enumerable is a built in Ruby module, what is it? +A module is a way of grouping together methods, classes, and constants so they can be used by other code. Modules provide a namespace so you can have methods with the same name in two different modules and use them both. +Enumerable is a module that has a bunch of methods for dealing with collections. You can include it in a class with an iterator called each and then you have access to various operations that you can do on a collection. + +4. Can you inherit more than one thing in Ruby? How could you get around this problem? +No, you can only inherit one thing. You can get around it by using mixins. A mixin is when you include a module in a class and the class gains access to all the instance methods of the module. + +5. What is the difference between a Module and a Class? +With a class you use it to create an object which is an instance of the class and can have instance methods. You can't use the instance methods of a module unless you use it as a mixin. +======= An array is an ordered list of items that are referenced by their index (order), a hash is a collection of items that can be referenced by a key and have no order. 2. When would you use an Array over a Hash and vice versa? @@ -16,3 +34,4 @@ No, multiple inheritance is not allowed in Ruby. You can include multiple module 5. What is the difference between a Module and a Class? A class can be instantiated into an object, a module cannot. A module is code that can be used across many classes. +>>>>>>> 8475cd203003ed7e45baf4b7881552daf9656526 diff --git a/week2/homework/simon_says.rb b/week2/homework/simon_says.rb index fa35ccd..f83c288 100644 --- a/week2/homework/simon_says.rb +++ b/week2/homework/simon_says.rb @@ -1,3 +1,40 @@ +<<<<<<< HEAD +#simon says module for week 2 homework +module SimonSays + #repeat the word back + def echo(sound) + "#{sound}" + end + + #make the work uppercase + def shout(sound) + "#{sound.upcase}" + end + +#repeat a word 2 or 3 times, default is 2. +def repeat(sound,iterations = 2) + if iterations == 2 + "#{sound} #{sound}" + elsif iterations == 3 + "#{sound} #{sound} #{sound}" + end + end +end + + #return the first n letters of a word + def start_of_word(word,letters) + while word.length > letters do + word.chop! + end + "#{word}" + end + + #return the first word of 2 + def first_word(word) + "#{word.split(" ")[0]}" + end + +======= module SimonSays def echo(st) st @@ -20,3 +57,4 @@ def repeat(st, t=2) ([st]*t).join(' ') end end +>>>>>>> 8475cd203003ed7e45baf4b7881552daf9656526 diff --git a/week3/homework/calculator.rb b/week3/homework/calculator.rb index f8916e3..39a3ef5 100644 --- a/week3/homework/calculator.rb +++ b/week3/homework/calculator.rb @@ -1,4 +1,26 @@ class Calculator +<<<<<<< HEAD + def sum(numeric_array) + numeric_array.inject(0) {|sum,element| sum+element} + end + + def multiply(a,b) + a*b + end + + def multarray(numeric_array) + numeric_array.inject(:*) + end + + def exp(a,b) + a^b + end + + def factorial(x) + (1..x).inject(:*) || 1 + end +end +======= def sum(array) array.inject(0){|sum, x| sum +x} end @@ -22,3 +44,4 @@ def pow_fac(base=nil, p) (1..p).to_a.inject(1){|f,v| f *= base || v} end end +>>>>>>> answers diff --git a/week3/homework/calculator_spec.rb b/week3/homework/calculator_spec.rb index 5a418ed..054f491 100644 --- a/week3/homework/calculator_spec.rb +++ b/week3/homework/calculator_spec.rb @@ -22,10 +22,19 @@ it "computes the sum of an array of many numbers" do @calculator.sum([1,3,5,7,9]).should == 25 end - end + # Once the above tests pass, # write tests and code for the following: +<<<<<<< HEAD + + it "multiplies two numbers" do + @calculator.multiply(9,7).should == 63 + end + + it "multiplies an array of numbers" do + @calculator.multarray([8,4,5,6,2,99]).should == 8*4*5*6*2*99 +======= describe "#multiply" do it "multiplies two numbers" do @calculator.multiply(2,2).should eq 4 @@ -40,11 +49,32 @@ p = 1 32.times{ p *= 2 } @calculator.pow(2,32).should eq p +>>>>>>> answers end + it "raises one number to the power of another number" do + @calculator.exp(4,8).should == 4^8 + end + end # http://en.wikipedia.org/wiki/Factorial describe "#factorial" do it "computes the factorial of 0" do +<<<<<<< HEAD + @calculator.factorial(0).should == 1 + end + it "computes the factorial of 1" do + @calculator.factorial(1).should == 1 + end + it "computes the factorial of 2" do + @calculator.factorial(2).should == 2 + end + it "computes the factorial of 5" do + @calculator.factorial(5) == 120 + end + it "computes the factorial of 10" do + @calculator.factorial(10) == 3628800 + end +======= @calculator.fac(0).should eq 1 end it "computes the factorial of 1" do @@ -63,6 +93,7 @@ @calculator.fac(10).should eq 3628800 end +>>>>>>> answers end end diff --git a/week3/homework/questions.txt b/week3/homework/questions.txt index 3161409..11f77ac 100644 --- a/week3/homework/questions.txt +++ b/week3/homework/questions.txt @@ -5,10 +5,24 @@ Please Read: - Chapter 22 The Ruby Language: basic types (symbols), variables and constants 1. What is a symbol? +<<<<<<< HEAD +A symbol is like as string but it is immutable. It can't change once it is created. This makes it better to use a symbol for program control compared to a string which is good for data that may change. +2. What is the difference between a symbol and a string? +A symbol is immutable, a string can change. A symbol is represented once in memory even when the symbol is repeated multiple times, when the same string is repeated each one is it's own object. + +3. What is a block and how do I call a block? +A block is a chunk of code that is enclosed in {} or sandwiched between do and end. You call a block from within a method using 'yield' + +4. How do I pass a block to a method? What is the method signature? +You pass a block to a method by putting the block after the method call. A method signature is a string representation of a method including a method's name and its parameters. + +5. Where would you use regular expressions? +You'd use regular expressions to evaluate whether a string follows a certain pattern. For example is a date in the format mm:dd:yyyy? Is your new password complicated enough? Is the string passed in to the method as an argument something the method knows how to deal with? +======= A symbol is a static name or identifier. 2. What is the difference between a symbol and a string? -A string is a collection of characters whereas a string is a static identifier. A string is not static no matter what the contents of the string are. So the strings "hello" and "hello" are two different ojects, whereas the symbol :hello and :hello are the exact same object. If you think of 1 as a FixNum or fixed number, you can think of the symbol :hello as the "FixStr" or fixed string :hello. +A string is a collection of characters whereas a symbol is a static identifier. A string is not static no matter what the contents of the string are. So the strings "hello" and "hello" are two different ojects, whereas the symbol :hello and :hello are the exact same object. If you think of 1 as a FixNum or fixed number, you can think of the symbol :hello as the "FixStr" or fixed string :hello. 3. What is a block and how do I call a block? A block is an anonymous function, or some code snipt that you can define and then call at a later time. To call a block you can use the yield keyword. @@ -26,3 +40,4 @@ end 5. Where would you use regular expressions? Regular expressions are used for pattern matching and replacement with strings. An example would be if I wanted to write a syntax checker for some text that checked if each sentance ended with a period, started with a space and then a capital letter. +>>>>>>> answers diff --git a/week4/exercises/worker.rb b/week4/exercises/worker.rb deleted file mode 100644 index fad4e2f..0000000 --- a/week4/exercises/worker.rb +++ /dev/null @@ -1,5 +0,0 @@ -class Worker - def self.work(n=1) - n.times.inject(nil){yield} - end -end \ No newline at end of file diff --git a/week4/homework/questions.txt b/week4/homework/questions.txt index bc1ab7c..3ae702d 100644 --- a/week4/homework/questions.txt +++ b/week4/homework/questions.txt @@ -3,7 +3,18 @@ Chapter 10 Basic Input and Output The Rake Gem: http://rake.rubyforge.org/ 1. How does Ruby read files? +Ruby reads files using the File class which is a subclass of IO. + 2. How would you output "Hello World!" to a file called my_output.txt? +File.open("my_output.txt", "w") do |file| + puts "Hello World!" +end + 3. What is the Directory class and what is it used for? +The Dir class is a built in class of Ruby. It's used for navigating a directory structure in ruby. For example, moving to different directories, or getting directory listings. + 4. What is an IO object? +To quote from our text "An IO object is a bidirectional channel between a Ruby program and some external resource." That external resource can be a file, or a network resource or whatever. File and BasicSocket both subclass the IO base class. + 5. What is rake and what is it used for? What is a rake task? +Rake is a build tool that is used for automating tasks such as manipulating files, running tests, compiling code, building a site. A rake task is a block of code that you've put together as one task. It seems like you want to put things that have common dependencies together in one task. But I think I have lot more to learn about what rake does. diff --git a/week5/class_materials/Rakefile b/week5/class_materials/Rakefile index 68a8f60..5366927 100644 --- a/week5/class_materials/Rakefile +++ b/week5/class_materials/Rakefile @@ -1,3 +1,44 @@ task :test do - puts "Hello World!" + puts "Hello World!" +end + +desc "Create a names file from roster.txt" +task :create_names do + store_names = [] + File.open("names", "w") do |names| + open_file_use_lines("roster.txt") do |l| + name = l.split(",").first.split(" ").first + if store_names.include?(name) + name += l.split(",").first.split(" ").last[0] + end + store_names << name + puts name + names.puts name + end + end +end + +desc "Creates git directories for all the lines in names file" +task :create_dirs => [:create_names] do + open_file_use_lines{|l| Dir.mkdir(l) unless Dir.exists?(l)} +end + +desc "deletes all the git directories made from the names file" +task :clean_up_dirs => [:create_dirs] do + open_file_use_lines{|l| Dir.rmdir(l)} +end + +desc "deletes all the .git directories" +task :clean_git_dirs do + Dir["*.git"].each do |d| + Dir.rmdir(d) + end +end + +def open_file_use_lines(file="names") + File.open(file) do |f| + f.each do |l| + yield "#{l.chomp}.git" + end + end end diff --git a/week5/class_materials/resources.txt b/week5/class_materials/resources.txt index 86c44f3..ab6ec07 100644 --- a/week5/class_materials/resources.txt +++ b/week5/class_materials/resources.txt @@ -1 +1,5 @@ -Slides: +Slides: http://www.slideshare.net/reneedv/week5-15057407 +File: http://www.ruby-doc.org/core-1.9.3/File.html +Dir: ruby-doc.org/core-1.9.3/Dir.html +Rake: http://rake.rubyforge.org/doc/rakefile_rdoc.html +Rake Tutorial: http://jasonseifer.com/2010/04/06/rake-tutorial diff --git a/week5/class_materials/roster.txt b/week5/class_materials/roster.txt new file mode 100644 index 0000000..8d13804 --- /dev/null +++ b/week5/class_materials/roster.txt @@ -0,0 +1,33 @@ +name, email, github, twitter, hipchat +Brian Ward, brianmatthewward@gmail.com, brianward, mrbrianward, brianmatthewward@gmail.com +Renee D, renee@nird.us, reneedv, @gigglegirl4e, renee.devoursney@gmail.com +Yan Li, leeyeon0307@gmail.com, YanLi0307, nil, leeyeon0307@gmail.com +Nell Shamrell, nellshamrell@gmail.com, nellshamrell, @nellshamrell +Brian Torretta, btorretta@gmail.com, btorretta, no twitter, btorretta@gmail.com +Emily, allenemilyh@gmail.com, allenemilyh, @Emily_Allen, allenemilyh@gmail.com +Danny Pham, pham.dannyt.@gmail.com +Chris Tsongas, chris.tsongas@bitmojo.com, tsongas, @tsongas, @ChrisTsongas +Chris F, christopher.d.ferris@gmail.com, chrisdfe +Mallory Fontenot, malloryfontenot@gmail.com, malloryfontenot, mallory711 +Greg Stallings, gregstallings@gmail.com, gregstallingsuw, @gregstallings, gregstallings@gmail.com +Tim Piele, timpiele@gmail.com, timpiele, timpiele +Eddie L, eddielee@email.com, patternchef, @patternchef, eddielee@email.com +Steven C, stevencurtiss@hotmail.com, scurtiss, , +Josh R, josh@estately.com, hungrysquirrel,@hungrysquirrel, joshmaxrubinstein@gmail.com +Nikky Southerland, nikky@uw.edu, allynfolksjr, @allynfolksjr, nikky@uw.edu +Chris Barcroft, ChrisABarcroft@gmail.com, cbarcroft, n/a, ChrisABarcroft@gmail.com +Kelli, kellimohr@gmail.com, kellimohr, @gimmesamohr, kellimohr@gmail.com +Ben Woodall, mail@benwoodall.com, benwoody, @benwoodall +Cheri, cherimarie@gmail.com, cherimarie, @cheriii, cherimarie@gmail.com +Strand McCutchen, strand.mccutchen@gmail.com, strand, @strabd, strand@bettermistak.es +Kris L, kris.luminar@gmail.com, kris-luminar, nil, nil +Santy M, mick26soum@gmail.com +Nicholas Palaniuk, npalaniuk@gmail.com, npalaniuk, @npalaniuk, npalaniuk@gmail.com +Karen Keasler, keaslk@gmail.com, github.com/irissilvermoon, irissilvermoon, keaslk@gmail.com +Bryan Williams, b_d_williams@yahoo.com, tallbryan, no twitter, b_d_williams@yahoo.com +Serene C., ruby@serenecareaga.com, serened, @grrlcoder, serened@gmail.com +Peter E. Granger, peter@granger.net, evac156, N/A, N/A +Price Hardman, PriceHardman@gmail.com, PriceHardman +Will Sugg, sugg.will@gmail.com, wsugg, , sugg.will@gmail.com +Nicole Lewis, lewis.nicole@gmail.com, nelewis, nil, lewis.nicole@gmail.com +Sol Wagner, capnsol@gmail.com, Soladin, n/a, capnsol@gmail.com diff --git a/week5/class_materials/week5.key b/week5/class_materials/week5.key new file mode 100644 index 0000000..b511781 Binary files /dev/null and b/week5/class_materials/week5.key differ diff --git a/week5/exercises/Rakefile b/week5/exercises/Rakefile index 68a8f60..0d4fe81 100644 --- a/week5/exercises/Rakefile +++ b/week5/exercises/Rakefile @@ -1,3 +1,17 @@ -task :test do - puts "Hello World!" + +task :read_names do + File.open("names") do |f| + f.each do |line| + puts line + end + end +end + +task :create_class_directory do + Dir.mkdir ("RubyClass") +end + +task :create_dirs do + + Dir.mkdir("RubyClass/") end diff --git a/week5/exercises/names b/week5/exercises/names new file mode 100644 index 0000000..9eec0ec --- /dev/null +++ b/week5/exercises/names @@ -0,0 +1,35 @@ +Ben +BrianT +BrianWard +BryanWilliams +Cheri +Chris B +ChristopherF +ChristopherT +Danny +Dimitry +Eddie +Emily +Gregory +Josh +Karen +Kat +Kelli +Kris +Mallory +Nell +NicholasP +Nicole +Nikky +Peter +Price +Renée +Ryan +Santy +Serene +Sol +Steven +Strand +Timothy +Will +Yan diff --git a/week5/homework/do_your_mid_term b/week5/homework/do_your_mid_term index 7b7a38f..18c8d0e 100644 --- a/week5/homework/do_your_mid_term +++ b/week5/homework/do_your_mid_term @@ -1 +1,2 @@ Work on your Mid-Term!! +Really Do your mid term! diff --git a/week6/class_materials/resources.txt b/week6/class_materials/resources.txt new file mode 100644 index 0000000..72bfb18 --- /dev/null +++ b/week6/class_materials/resources.txt @@ -0,0 +1,10 @@ +Slides: http://www.slideshare.net/reneedv/week6-15164387 + +RubyGems.org: https://rubygems.org/ +RubyGems Command Reference: http://guides.rubygems.org/command-reference/ +Travis CI: https://travis-ci.org +Travis CI Docs for Ruby: http://about.travis-ci.org/docs/user/languages/ruby/ +About Travis: http://about.travis-ci.org/ +Gem Release: https://github.com/svenfuchs/gem-release +Jeweler: https://github.com/technicalpickles/jeweler +Make Your Own Gem Guide: http://guides.rubygems.org/make-your-own-gem/ diff --git a/week6/class_materials/test_gem/.rspec b/week6/class_materials/test_gem/.rspec new file mode 100644 index 0000000..b36b4b5 --- /dev/null +++ b/week6/class_materials/test_gem/.rspec @@ -0,0 +1,2 @@ +--color +--format nested \ No newline at end of file diff --git a/week6/class_materials/test_gem/Rakefile b/week6/class_materials/test_gem/Rakefile new file mode 100644 index 0000000..4f262cb --- /dev/null +++ b/week6/class_materials/test_gem/Rakefile @@ -0,0 +1,5 @@ +require 'rspec/core/rake_task' + +RSpec::Core::RakeTask.new('test') + +task :default => :test \ No newline at end of file diff --git a/week6/class_materials/test_gem/bin/test_gem b/week6/class_materials/test_gem/bin/test_gem new file mode 100644 index 0000000..044c5e3 --- /dev/null +++ b/week6/class_materials/test_gem/bin/test_gem @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby + +puts "Hello There!" +puts ARGV[0] \ No newline at end of file diff --git a/week6/class_materials/test_gem/lib/test_gem.rb b/week6/class_materials/test_gem/lib/test_gem.rb new file mode 100644 index 0000000..1bd5f23 --- /dev/null +++ b/week6/class_materials/test_gem/lib/test_gem.rb @@ -0,0 +1,3 @@ +puts "Hello World!" +class Hello +end \ No newline at end of file diff --git a/week6/class_materials/test_gem/spec/another_spec.rb b/week6/class_materials/test_gem/spec/another_spec.rb new file mode 100644 index 0000000..e69de29 diff --git a/week6/class_materials/test_gem/spec/test_gem_spec.rb b/week6/class_materials/test_gem/spec/test_gem_spec.rb new file mode 100644 index 0000000..0b322bf --- /dev/null +++ b/week6/class_materials/test_gem/spec/test_gem_spec.rb @@ -0,0 +1,9 @@ +require 'test_gem' + +describe "test_gem" do + it "Should make a new Hello" do + h = Hello.new + h.should be_a Hello + end + +end \ No newline at end of file diff --git a/week6/class_materials/test_gem/test_gem.gemspec b/week6/class_materials/test_gem/test_gem.gemspec new file mode 100644 index 0000000..d2f86fc --- /dev/null +++ b/week6/class_materials/test_gem/test_gem.gemspec @@ -0,0 +1,12 @@ +Gem::Specification.new do |s| + s.name = 'reneedv_hello_gem' + s.version = '0.0.1' + s.date = '2012-11-13' + s.summary = "Making a Test Gem" + s.description = "A gem to explain how to make gems" + s.authors = ["Renée De Voursney"] + s.email = 'renee@nird.us' + s.homepage = 'http://rubygems.org/gems/test_gem' + s.files = ["lib/test_gem.rb"] + s.executables << 'test_gem' +end \ No newline at end of file diff --git a/week6/class_materials/week6.key b/week6/class_materials/week6.key new file mode 100644 index 0000000..50adb11 Binary files /dev/null and b/week6/class_materials/week6.key differ diff --git a/week6/omakase/bin/omakase b/week6/omakase/bin/omakase new file mode 100644 index 0000000..2eec65a --- /dev/null +++ b/week6/omakase/bin/omakase @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby + +puts "What does this gem do, anyway?" +puts ARGV[0] \ No newline at end of file diff --git a/week6/omakase/lib/omakase.rb b/week6/omakase/lib/omakase.rb new file mode 100644 index 0000000..1e0bbf6 --- /dev/null +++ b/week6/omakase/lib/omakase.rb @@ -0,0 +1,3 @@ +puts "Hello World" +class Hello +end \ No newline at end of file diff --git a/week6/omakase/omakase.gemspec b/week6/omakase/omakase.gemspec new file mode 100644 index 0000000..f7ad3cb --- /dev/null +++ b/week6/omakase/omakase.gemspec @@ -0,0 +1,12 @@ +Gem::Specification.new do |s| + s.name = 'omakase' + s.version = '0.0.1' + s.date = '2012-11-17' + s.summary = "Making a Test Gem" + s.description = "A gem to give you what you want even when you didn't know what you wanted" + s.authors = ["Bryan Williams"] + s.email = 'fakeemail@fakedomain.com' + s.homepage = 'http://rubygems.org/gems/omakase' + s.files = ["lib/omakase.rb"] + s.executables << 'omakase' +end \ No newline at end of file diff --git a/week7/class_materials/cucumber/features/converter.feature b/week7/class_materials/cucumber/features/converter.feature new file mode 100644 index 0000000..9b7416d --- /dev/null +++ b/week7/class_materials/cucumber/features/converter.feature @@ -0,0 +1,17 @@ +Feature: Converting metric + In order to pack for London + As a traveler + I want to be told the Celsius temperature in Fahrenheit + +Scenario: + Given I have entered 0 into the converter + And I select Celsius + When I press convert + Then the result should be 32.0 on the screen + +Scenario: + Given I have entered 21 into the converter + And I select Celsius + When I press convert + Then the result should be 69.8 on the screen + diff --git a/week7/class_materials/cucumber/features/step_definitions/converter.rb b/week7/class_materials/cucumber/features/step_definitions/converter.rb new file mode 100644 index 0000000..e37c629 --- /dev/null +++ b/week7/class_materials/cucumber/features/step_definitions/converter.rb @@ -0,0 +1,18 @@ +class Converter + + def initialize(unit) + @unit = unit.to_f + end + + def type=(type) + @type = type + end + + def convert + self.send("#{@type}_convertion") + end + + def Celsius_convertion + (@unit * (9.0/5.0) + 32.0).round(1) + end +end diff --git a/week7/class_materials/cucumber/features/step_definitions/converter_steps.rb b/week7/class_materials/cucumber/features/step_definitions/converter_steps.rb new file mode 100644 index 0000000..61b9aae --- /dev/null +++ b/week7/class_materials/cucumber/features/step_definitions/converter_steps.rb @@ -0,0 +1,15 @@ +Given /^I have entered (\d+) into the converter$/ do |arg1| + @converter = Converter.new(arg1) +end + +Given /^I select Celsius$/ do + @converter.type = "Celsius" +end + +When /^I press convert$/ do + @result = @converter.convert +end + +Then /^the result should be (\d+)\.(\d+) on the screen$/ do |arg1, arg2| + @result.should eq "#{arg1}.#{arg2}".to_f +end diff --git a/week7/class_materials/minitest/advanced_book.rb b/week7/class_materials/minitest/advanced_book.rb new file mode 100644 index 0000000..6f79dbf --- /dev/null +++ b/week7/class_materials/minitest/advanced_book.rb @@ -0,0 +1,121 @@ +class String + def humanize + self.gsub('_', ' ') + end +end + +class Book + + attr_accessor :title, :author, :page_count, :pages + + def initialize(inital_hash=nil) + inital_hash.each do |k,v| + instance_variable_set("@#{k}", v) + end if inital_hash + end + + def pretty_print + "#{title} - #{author} pages: #{page_count}" + end + + # def pretty_print_title + # "Title: #{title}" + # end + # + # def pretty_print_author + # "Author: #{author}" + # end + + [:author, :title].each do |attr| + define_method("pretty_print_#{attr}") do + "#{attr.to_s.capitalize}: #{instance_variable_get("@#{attr}")}" + end + end + + [:page_count].each do |attr| + define_method("read_method_#{attr}") do + "#{attr.to_s.capitalize.humanize}: #{self.send(attr)}" + end + end + + def map_pages + maped_pages = pages + pages.each_with_index do |page, i| + maped_pages[i] = yield(page) + end + maped_pages + end + + def self.page_counter(book) + yield(book.pages) + end + +end + +# Unit tests + +require 'minitest/autorun' + +class TestBook < MiniTest::Unit::TestCase + def setup + @book = Book.new(title: 'test', author: "Mr. Test", page_count: 4) + end + + def test_that_book_can_print_pretty + assert_equal "#{@book.title} - #{@book.author} pages: #{@book.page_count}", @book.pretty_print + end + + def test_that_book_has_author + assert_equal @book.author, "Mr. Test" + end + + def test_that_book_can_count_pages + assert @book.page_count.kind_of?(Integer) + end + + def test_that_book_can_dynamically_count_pages + @book.pages = ['page 1', 'page 2'] + assert_equal Book.page_counter(@book) {|pages| pages.count}, 2 + end +end + +# Specs + +describe Book do + before do + @book = Book.new + @book.pages = ['This is page 1', 'Page 2 is this one', 'Page 3 is short', 'Page 4 is very very very long'] + end + + describe "when asked about author" do + it "must respond with the author" do + @book.author = "Mr. Test" + @book.author.must_equal "Mr. Test" + end + end + + describe "when mapping pages" do + it "must count the characters on the page" do + maped_pages = @book.map_pages do |page| + page.size + end + maped_pages.must_equal [14, 18, 15, 29] + end + end + + describe "when counting pages" do + it "should read the page count method" do + @book.read_method_page_count.must_equal "Page count: #{@book.page_count}" + end + end + + describe "when pretty printing" do + it "must print the author label and author name" do + @book.pretty_print_author.must_equal "Author: #{@book.author}" + end + + it "must print the title label and title" do + @book.pretty_print_title.must_equal "Title: #{@book.title}" + end + end +end diff --git a/week7/class_materials/minitest/book.rb b/week7/class_materials/minitest/book.rb new file mode 100644 index 0000000..294444b --- /dev/null +++ b/week7/class_materials/minitest/book.rb @@ -0,0 +1,31 @@ +class Book +end + +require 'minitest/autorun' + +# Unit tests + +class TestBook < MiniTest::Unit::TestCase + def setup + @book = Book.new('test', "Mr. Test", 4) + end + + def test_that_book_can_print_pretty + assert_equal "#{@book.title} - #{@book.author} pages: #{@book.page_count}", @book.pretty_print + end +end + +# Specs + +describe Book do + before do + @book = Book.new + @book.pages = ['This is page 1', 'Page 2 is this one', 'Page 3 is short', 'Page 4 is very very very long'] + end + + describe "when counting characters" do + it "should count the characters on every page" do + @book.characters.must_equal 29 + end + end +end \ No newline at end of file diff --git a/week7/class_materials/minitest/book_answers.rb b/week7/class_materials/minitest/book_answers.rb new file mode 100644 index 0000000..7a1f45d --- /dev/null +++ b/week7/class_materials/minitest/book_answers.rb @@ -0,0 +1,19 @@ +class Book + + attr_accessor :title, :author, :page_count, :pages + + def initialize(title="titel", author="N/A", page_count=0) + @title = title + @author = author + @page_count = page_count + end + + def pretty_print + "#{title} - #{author} pages: #{page_count}" + end + + def characters + pages.inject(0){|total, p| p.size} + end + +end diff --git a/week7/class_materials/resources.txt b/week7/class_materials/resources.txt new file mode 100644 index 0000000..ab0dc70 --- /dev/null +++ b/week7/class_materials/resources.txt @@ -0,0 +1,10 @@ +Slides: http://www.slideshare.net/reneedv/week7-15273981 + +BDD: http://en.wikipedia.org/wiki/Behavior-driven_development#Principles_of_BDD +cucumber: cukes.info +cucumber wiki: https://github.com/cucumber/cucumber/wiki +Given-When-Then: https://github.com/cucumber/cucumber/wiki/Given-When-Then +Step Definitions: https://github.com/cucumber/cucumber/wiki/Step-Definitions + +MiniTest: https://github.com/seattlerb/minitest + diff --git a/week7/class_materials/test_unit/README.rdoc b/week7/class_materials/test_unit/README.rdoc new file mode 100644 index 0000000..f2cb656 --- /dev/null +++ b/week7/class_materials/test_unit/README.rdoc @@ -0,0 +1 @@ +{Teaching Gem}[https://github.com/reneedv/teaching_gem] diff --git a/week7/class_materials/week7.key b/week7/class_materials/week7.key new file mode 100644 index 0000000..beabcc8 Binary files /dev/null and b/week7/class_materials/week7.key differ diff --git a/week7/exercises/features/converter.feature b/week7/exercises/features/converter.feature new file mode 100644 index 0000000..5e262a8 --- /dev/null +++ b/week7/exercises/features/converter.feature @@ -0,0 +1,17 @@ +Feature: Converting metric + In order to talk about the weather back home + As a traveler in London + I want to convert a Fahrenheit temperature to Celsius + +Scenario: + Given I have entered 32 into the converter + And I set the type to Fahrenheit + When I press convert + Then the result returned should be 0.0 + +Scenario: + Given I have entered 75 into the converter + And I set the type to Fahrenheit + When I press convert + Then the result returned should be 23.9 + diff --git a/week7/exercises/features/puppy.feature b/week7/exercises/features/puppy.feature new file mode 100644 index 0000000..e6c7b07 --- /dev/null +++ b/week7/exercises/features/puppy.feature @@ -0,0 +1,18 @@ +Feature: Puppies are very cute and everyone wants one + In order to make everyone happy + As a puppy class programmer + I want to give everyone a cute virtual puppy + +Scenario: The puppy is being pet + Given we have a puppy + And its name is Fred + When we pet the puppy + Then the puppy wags its tail + +Scenario: The puppy needs to go out + Given we have a puppy + And its name is Bella + When we ring the bell + And it wags its tail + Then we must take it out + And then it will not pee on the floor diff --git a/week7/exercises/features/step_definitions/converter.rb b/week7/exercises/features/step_definitions/converter.rb new file mode 100644 index 0000000..4cb1264 --- /dev/null +++ b/week7/exercises/features/step_definitions/converter.rb @@ -0,0 +1,17 @@ +class Converter + def initialize(value) + @value = value.to_f + end + + def type=(type) + @type = type + end + + def convert + self.send("#{@type}_convertion") + end + + def Fahrenheit_convertion + (((@value - 32.0) /5.0) * 9.0).round(1) + end +end \ No newline at end of file diff --git a/week7/exercises/features/step_definitions/converter_steps.rb b/week7/exercises/features/step_definitions/converter_steps.rb new file mode 100644 index 0000000..5a12ae5 --- /dev/null +++ b/week7/exercises/features/step_definitions/converter_steps.rb @@ -0,0 +1,15 @@ +Given /^I have entered (\d+) into the converter$/ do |arg1| + @converter = Converter.new(arg1) +end + +Given /^I set the type to (\w+)$/ do |arg1| + @converter.type = arg1 +end + +When /^I press (\w+)$/ do |arg1| + @result = @converter.send(arg1) +end + +Then /^the result returned should be (\d+)\.(\d+)$/ do |arg1, arg2| + @result.should == "#{arg1}.#{arg2}".to_f +end \ No newline at end of file diff --git a/week7/exercises/step_definitions/converter.rb b/week7/exercises/step_definitions/converter.rb new file mode 100644 index 0000000..40b5b65 --- /dev/null +++ b/week7/exercises/step_definitions/converter.rb @@ -0,0 +1,6 @@ +class Converter + def initialize + @value = value + end + + end \ No newline at end of file diff --git a/week7/exercises/step_definitions/converter_steps.rb b/week7/exercises/step_definitions/converter_steps.rb new file mode 100644 index 0000000..4fa6557 --- /dev/null +++ b/week7/exercises/step_definitions/converter_steps.rb @@ -0,0 +1,15 @@ +Given /^I have entered (\d+) into the converter$/ do |arg1| + @converter = Converter.new(arg1) # express the regexp above with the code you wish you had +end + +Given /^I set the type to Fahrenheit$/ do + @converter.type = arg1 +end + +When /^I press convert$/ do + @result = @converter.send(arg1) +end + +Then /^the result returned should be (\d+)\.(\d+)$/ do |arg1, arg2| + @result.should == "#{arg1}.#{arg2}".to_f +end diff --git a/week7/homework/features/pirate.feature b/week7/homework/features/pirate.feature new file mode 100644 index 0000000..7de1a0b --- /dev/null +++ b/week7/homework/features/pirate.feature @@ -0,0 +1,11 @@ +# language: en-pirate + +Ahoy matey!: Pirate Speak + I would like help to talk like a pirate + +Heave to: The mighty speaking pirate + Gangway! I have a PirateTranslator + Blimey! I say 'Hello Friend' + Aye I hit translate + Let go and haul it prints out 'Ahoy Matey' + Avast! it also prints 'Shiber Me Timbers You Scurvey Dogs!!' diff --git a/week7/homework/features/step_definitions/tic-tac-toe-steps.rb b/week7/homework/features/step_definitions/tic-tac-toe-steps.rb new file mode 100644 index 0000000..b353120 --- /dev/null +++ b/week7/homework/features/step_definitions/tic-tac-toe-steps.rb @@ -0,0 +1,124 @@ +require 'rspec/mocks/standalone' + +Given /^I start a new Tic\-Tac\-Toe game$/ do + @game = TicTacToe.new +end + +When /^I enter my name (\w+)$/ do |name| + @game.player = name +end + +Then /^the computer welcomes me to the game with "(.*?)"$/ do |arg1| + @game.welcome_player.should eq arg1 +end + +Then /^randomly chooses who goes first$/ do + [@game.player, "Computer"].should include @game.current_player +end + +Then /^who is X and who is O$/ do + TicTacToe::SYMBOLS.should include @game.player_symbol, @game.computer_symbol +end + +Given /^I have a started Tic\-Tac\-Toe game$/ do + @game = TicTacToe.new(:player) + @game.player = "Renee" +end + +Given /^it is my turn$/ do + @game.current_player.should eq "Renee" +end + +Given /^the computer knows my name is Renee$/ do + @game.player.should eq "Renee" +end + +Then /^the computer prints "(.*?)"$/ do |arg1| + @game.should_receive(:puts).with(arg1) + @game.indicate_palyer_turn +end + +Then /^waits for my input of "(.*?)"$/ do |arg1| + @game.should_receive(:gets).and_return(arg1) + @game.get_player_move +end + +Given /^it is the computer's turn$/ do + @game = TicTacToe.new(:computer, :O) + @game.current_player.should eq "Computer" +end + +Then /^the computer randomly chooses an open position for its move$/ do + open_spots = @game.open_spots + @com_move = @game.computer_move + open_spots.should include(@com_move) +end + +Given /^the computer is playing X$/ do + @game.computer_symbol.should eq :X +end + +Then /^the board should have an X on it$/ do + @game.current_state.should include 'X' +end + +Given /^I am playing X$/ do + @game = TicTacToe.new(:computer, :X) + @game.player_symbol.should eq :X +end + +When /^I enter a position "(.*?)" on the board$/ do |arg1| + @old_pos = @game.board[arg1.to_sym] + @game.should_receive(:get_player_move).and_return(arg1) + @game.player_move.should eq arg1.to_sym +end + +When /^"(.*?)" is not taken$/ do |arg1| + @old_pos.should eq " " +end + +Then /^it is now the computer's turn$/ do + @game.current_player.should eq "Computer" +end + +When /^there are three X's in a row$/ do + @game = TicTacToe.new(:computer, :X) + @game.board[:C1] = @game.board[:B2] = @game.board[:A3] = :X +end + +Then /^I am declared the winner$/ do + @game.determine_winner + @game.player_won?.should be_true +end + +Then /^the game ends$/ do + @game.over?.should be_true +end + +Given /^there are not three symbols in a row$/ do + @game.board = { + :A1 => :X, :A2 => :O, :A3 => :X, + :B1 => :X, :B2 => :O, :B3 => :X, + :C1 => :O, :C2 => :X, :C3 => :O + } + @game.determine_winner +end + +When /^there are no open spaces left on the board$/ do + @game.spots_open?.should be_false +end + +Then /^the game is declared a draw$/ do + @game.draw?.should be_true +end + +When /^"(.*?)" is taken$/ do |arg1| + @game.board[arg1.to_sym] = :O + @taken_spot = arg1.to_sym +end + +Then /^computer should ask me for another position "(.*?)"$/ do |arg1| + @game.board[arg1.to_sym] = ' ' + @game.should_receive(:get_player_move).twice.and_return(@taken_spot, arg1) + @game.player_move.should eq arg1.to_sym +end diff --git a/week7/homework/features/step_definitions/tic-tac-toe.rb b/week7/homework/features/step_definitions/tic-tac-toe.rb new file mode 100644 index 0000000..993fd52 --- /dev/null +++ b/week7/homework/features/step_definitions/tic-tac-toe.rb @@ -0,0 +1,147 @@ +class TicTacToe + attr_reader :open_spots + attr_accessor :board + + SYMBOLS = [:X,:O] + + def initialize(first_player = nil, player_symbol = nil) + #expecting :player or :computer for first_player this is used to force the context for testing + @player_hash = {:player=>nil,:computer => "Computer"} + first_player==nil ? randomize_first_player : @current_player = first_player + @symbol_hash = {:player=> nil, :computer=>nil} + assign_symbols(player_symbol) + #define all the open spots. they're all open to begin with + @open_spots = [:A1,:A2,:A3,:B1,:B2,:B3, :C1,:C2,:C3] + @board = {} + @open_spots.each {|spot| @board[spot]=" "} #set up the current state with all spots empty + play_game + end + + def player=player + @player_hash[:player] = player + puts @current_player #show the player name + end + + def player + @player_hash[:player] + end + + def current_player + @player_hash[@current_player] + end + + #practicing some meta programming + [:player, :computer].each do |s| + define_method("#{s}_symbol") do + @symbol_hash[s] + end + end + + def assign_symbols(player_symbol = nil) + op = {0=>1,1=>0,:player=>:computer, :computer=>:player, :X=>:O, :O=>:X} #a hash that defines opposites + @symbol_hash[:player] = player_symbol + @symbol_hash[:player] ||= SYMBOLS[rand(2)].to_sym + @symbol_hash[:computer] = op[@symbol_hash[:player]]# op[@symbol_hash[:player]] + end + + def randomize_first_player + @current_player = [:player, :computer][rand(2)] #decide who goes first + end + + def welcome_player + #welcome the player + "Welcome #{@player_hash[:player]}" + end + + def play_game #structure of the game + indicate_palyer_turn + get_player_move + end + + def indicate_palyer_turn + puts "#{@player_hash[@current_player]}'s Move:" + end + + def get_player_move(move = ARGV) + move + end + + def computer_move + move = @open_spots.slice(rand(@open_spots.length)) + @board[move]=@symbol_hash[:computer].to_s + return move + end + + def player_move + move = get_player_move.to_sym + if board[move] == ' ' + #the space is available, put the player's symbol there + @board[move] = @symbol_hash[:player].to_s + return move + else + #the spot is not available, ask again for a move + new_move = player_move + return new_move + end + end + + def current_state + @board.values + end + + def winner?(side, trio) + #take a symbol(player or computer) and a trio of contiguous board positions as input and determine whether that side has one on + #those three positions + trio.all? {|y| @board[y]==@symbol_hash[side]} #check to see if all three symbols match symbol + end + + def determine_winner + winning_combinations = [[:A1,:A2,:A3],[:B1,:B2,:B3],[:C1,:C2,:C3],[:A1,:B1,:C1],[:A2,:B2,:C2],[:A3,:B3,:C3],[:A1,:B2,:C3],[:C1,:B2,:A3]] + winning_combinations.each do |trio| + if winner?(:player,trio) + #the player has won + @player_won = true + @game_over = true + break + elsif winner?(:computer,trio) + #the computer has won + @computer_won = true + @game_over = true + break + else + @game_over = false + end + #check for a draw + if !spots_open? + #no spots are open but there was no winner so it's a draw + @draw=true + @game_over = true + else + @draw=false + @game_over = false + end + end + end + + def spots_open? + @board.include?(' ') + end + + def player_won? + @player_won + end + + def computer_won? + @computer_won + end + + def over? + @game_over + end + + def draw? + @draw + end +end + + diff --git a/week7/homework/features/tic-tac-toe.feature b/week7/homework/features/tic-tac-toe.feature new file mode 100644 index 0000000..6f3134d --- /dev/null +++ b/week7/homework/features/tic-tac-toe.feature @@ -0,0 +1,57 @@ +Feature: Tic-Tac-Toe Game + As a game player I like tic-tac-toe + In order to up my skills + I would like to play agaist the computer + +Scenario: Begin Game + Given I start a new Tic-Tac-Toe game + When I enter my name Renee + Then the computer welcomes me to the game with "Welcome Renee" + And randomly chooses who goes first + And who is X and who is O + +Scenario: My Turn + Given I have a started Tic-Tac-Toe game + And it is my turn + And the computer knows my name is Renee + Then the computer prints "Renee's Move:" + And waits for my input of "B2" + +Scenario: Computer's Turn + Given I have a started Tic-Tac-Toe game + And it is the computer's turn + And the computer is playing X + Then the computer randomly chooses an open position for its move + And the board should have an X on it + +Scenario: Making Moves + Given I have a started Tic-Tac-Toe game + And it is my turn + And I am playing X + When I enter a position "A1" on the board + And "A1" is not taken + Then the board should have an X on it + And it is now the computer's turn + +Scenario: Making Bad Moves + Given I have a started Tic-Tac-Toe game + And it is my turn + And I am playing X + When I enter a position "A1" on the board + And "A1" is taken + Then computer should ask me for another position "B2" + And it is now the computer's turn + +Scenario: Winning the Game + Given I have a started Tic-Tac-Toe game + And I am playing X + When there are three X's in a row + Then I am declared the winner + And the game ends + +Scenario: Game is a draw + Given I have a started Tic-Tac-Toe game + And there are not three symbols in a row + When there are no open spaces left on the board + Then the game is declared a draw + And the game ends diff --git a/week7/homework/play_game.rb b/week7/homework/play_game.rb new file mode 100644 index 0000000..cf7847f --- /dev/null +++ b/week7/homework/play_game.rb @@ -0,0 +1,20 @@ +require './features/step_definitions/tic-tac-toe.rb' + +@game = TicTacToe.new +puts @game.welcome_player + +until @game.over? + case @game.current_player + when "Computer" + @game.computer_move + when @game.player + @game.indicate_palyer_turn + @game.player_move + end + puts @game.current_state + @game.determine_winner +end + +puts "You Won!" if @game.player_won? +puts "I Won!" if @game.computer_won? +puts "DRAW!" if @game.draw? diff --git a/week7/homework/questions.txt b/week7/homework/questions.txt new file mode 100644 index 0000000..f444098 --- /dev/null +++ b/week7/homework/questions.txt @@ -0,0 +1,20 @@ + +Please Read Chapters 23 and 24 DuckTyping and MetaProgramming + +Questions: +1. What is method_missing and how can it be used? +method_missing is a Hook. You can use it to handle calls to methods that are missing from a class. If you don't handle some cases then you should pass on the call using super. + +2. What is and Eigenclass and what is it used for? Where Do Singleton methods live? +Eigenclass is another name for a singleton class. Singleton methods live in eigenclasses. + +3. When would you use DuckTypeing? How would you use it to improve your code? +You could use ducktypeing to write one method that would take a string or a file as an argument. It can help make code more reusable. Instead of writing one method that alphabetizes the words in a file and one that alphabetizes the words in a string, you can use the same method to do both. + +4. What is the difference between a class method and an instance method? What is the difference between instance_eval and class_eval? +A class method can be called without creating an instance of the class. You must have an instance of the class (an object) to call an instance method. + +class_eval sets self as if you're in the body of the class definition. instance_eval sets self as if you'r in the singleton class of self. The result is that if you're defining a method, use class eval_to define instance methods, and use instance_eval to define class methods. + +5. What is the difference between a singleton class and a singleton method? +A singleton method is a method that is defined only for a particular object. A singleton class is the class that's created when you define a singleton method. The singleton class is the superclass of the object that has the singleton method. diff --git a/week8/class_materials/couch.rb b/week8/class_materials/couch.rb new file mode 100644 index 0000000..41d0097 --- /dev/null +++ b/week8/class_materials/couch.rb @@ -0,0 +1,20 @@ +class Couch + def initialize(pillows, cushions) + @pillows = pillows + @cushions = cushions + end + + def how_many_pillows + @pillows.count + end + + def how_many_cushions + @cushions.count + end + + [:pillows, :cushions].each do |s| + define_method("how_many_#{s}") do + instance_variable_get("@#{s}").count + end + end +end diff --git a/week8/class_materials/resources.txt b/week8/class_materials/resources.txt new file mode 100644 index 0000000..8c2e3fa --- /dev/null +++ b/week8/class_materials/resources.txt @@ -0,0 +1,15 @@ +Metaprogramming: +http://ruby-metaprogramming.rubylearning.com/ +http://ruby-metaprogramming.rubylearning.com/html/seeingMetaclassesClearly.html +http://deepakprasanna.blogspot.com/2011/07/objects-dynamism-awesomeness-ruby.html +http://www.trottercashion.com/2011/02/08/rubys-define_method-method_missing-and-instance_eval.html + +Ruby Call Chain: +http://railstips.org/blog/archives/2009/08/20/lookin-on-up-to-the-east-side/ + +EigenClass & Call Chain: +http://madebydna.com/all/code/2011/06/24/eigenclasses-demystified.html +http://www.devalot.com/articles/2008/09/ruby-singleton + +Changing Self: +http://pragdave.blogs.pragprog.com/pragdave/2007/11/changing-self-i.html diff --git a/week8/class_materials/week8.key b/week8/class_materials/week8.key new file mode 100644 index 0000000..8ea3987 Binary files /dev/null and b/week8/class_materials/week8.key differ diff --git a/week8/exercises/book_spec.rb b/week8/exercises/book_spec.rb new file mode 100644 index 0000000..113d0de --- /dev/null +++ b/week8/exercises/book_spec.rb @@ -0,0 +1,10 @@ +require './books.rb' +describe Printer do + context "#printing" do + it "should print out the right thing" do + printer = Printer.new + fiction = FictionBook.new + printer.print(fiction).should eq "This book is Fiction!" + end + end +end diff --git a/week8/exercises/books.rb b/week8/exercises/books.rb new file mode 100644 index 0000000..bb843b3 --- /dev/null +++ b/week8/exercises/books.rb @@ -0,0 +1,13 @@ +class Printer + def print(book) + "This book is a book" + "This book is Fiction!" if book.is_a?(FictionBook) + end +end + +class Book + attr_accessor :title, :author +end + +class FictionBook < Book +end diff --git a/week8/exercises/couch.rb b/week8/exercises/couch.rb new file mode 100644 index 0000000..a52eb35 --- /dev/null +++ b/week8/exercises/couch.rb @@ -0,0 +1,20 @@ +class Couch + def initialize(pillows, cushions) + @pillows = pillows + @cushions = cushions + end + + def pillow_colors + @pillows.join(", ") + end + + def cushion_colors + @cushions.join(", ") + end + + [:pillows, :cushions].each do |s| + define_method("how_many_#{s}") do + instance_variable_get("@#{s}").count + end + end +end