From d7d4e54b4a444230a9c0d098a399ca88fa5a9400 Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 15 Jan 2015 14:59:09 -0800 Subject: [PATCH 01/15] Update assignment01.rb --- assignments/assignment01.rb | 47 ++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/assignments/assignment01.rb b/assignments/assignment01.rb index c88806d..4f8c84f 100644 --- a/assignments/assignment01.rb +++ b/assignments/assignment01.rb @@ -10,7 +10,7 @@ def number_to_string(n, lang) digit_strings = lang_digit_strings[lang] return "no such language" if digit_strings.nil? - + s = n.to_s string_digits = s.split "" @@ -38,13 +38,17 @@ def number_to_string(n, lang) # it accepts a string # and returns the same string with each word capitalized. def titleize(s) - # your implementation here + a = s.split(" ") + b = a.map {|x| x.upcase[0]+x[1..-1].downcase} + puts b.join(" ") end # Your method should generate the following results: -titleize "hEllo WORLD" #=> "Hello World" +titleize("hEllo WORLD") #=> "Hello World" -titleize "gooDbye CRUel wORLD" #=> "Goodbye Cruel World" +titleize("gooDbye CRUel wORLD") #=> "Goodbye Cruel World" +puts "---END OF PROBLEM 1---" +puts "" # ======================================================================================== @@ -53,14 +57,22 @@ def titleize(s) # Write your own implementation of `reverse` called `my_reverse` # You may *not* use the built-in `reverse` method def my_reverse(s) - # your implementation here + index = s.length + array = [] + s.length.times do index -= 1 + array << s[index] + if array.length == s.length + puts array.join + end + end end # Your method should generate the following results: -my_reverse "Hello World" #=> "dlroW olleH" - -my_reverse "Goodbye Cruel World" #=> "dlroW leurC eybdooG" +my_reverse("Hello World") #=> "dlroW olleH" +my_reverse("Goodbye Cruel World") #=> "dlroW leurC eybdooG" +puts "---END OF PROBLEM 2---" +puts "" # ======================================================================================== # Problem 3 - `palindrome?` @@ -68,13 +80,20 @@ def my_reverse(s) # Write a method `palindrome?` # that determines whether a string is a palindrome def palindrome?(s) - # your implementation here + g = s.gsub(/\W+/, "") + f = g.downcase + if f.reverse == f + puts "true" + else + puts "false" + end end # Your method should generate the following results: -palindrome? "abba" #=> true -palindrome? "aBbA" #=> true -palindrome? "abb" #=> false +palindrome?("abba") #=> true +palindrome?("aBbA") #=> true +palindrome?("abb") #=> false -palindrome? "Able was I ere I saw elba" #=> true -palindrome? "A man, a plan, a canal, Panama" #=> true +palindrome?("Able was I ere I saw elba") #=> true +palindrome?("A man, a plan, a canal, Panama") #=> true +puts "---END OF PROBLEM 3---" From 44ed057df4781be75a2e1244e9d212ed328f1260 Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 22 Jan 2015 17:37:17 -0800 Subject: [PATCH 02/15] Combined assignments 1 & 2 Added assignment #2. Simply appended the problems to the end of the file. --- assignments/assignment01.rb | 148 ++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/assignments/assignment01.rb b/assignments/assignment01.rb index 4f8c84f..d8cb398 100644 --- a/assignments/assignment01.rb +++ b/assignments/assignment01.rb @@ -97,3 +97,151 @@ def palindrome?(s) palindrome?("Able was I ere I saw elba") #=> true palindrome?("A man, a plan, a canal, Panama") #=> true puts "---END OF PROBLEM 3---" + +#---------------------------------------------------------------- + +puts "---START OF HOMEWORK 2---" +puts "" + +def to_sentence(array) + if array.length == 1 + puts array + elsif array.length > 1 + last_element = [] + last_element << array.pop + p = array.flatten.join(", ") + puts p+" and "+last_element[0].to_s + end +end + +to_sentence([]) +to_sentence(["john"]) +to_sentence(["john", "paul"]) +to_sentence([1, "paul", 3, "ringo"]) +puts "---END OF PROBLEM 1---" + +def mean(array) + sum = 0 + array.each {|i| sum += i} + the_mean = sum/array.length.to_i + puts the_mean.to_f +end + +def median(array) + ordered_array = array.sort + number_of_elements = array.length + if array.length % 2 != 0 + median_pos = number_of_elements.to_i/2 + puts ordered_array[median_pos].to_f + else array.length % 2 == 0 + median1 = ordered_array[array.length.to_i/2] + median2 = ordered_array[array.length.to_i/2-1] + puts (median1.to_f+median2.to_f)/2 + end +end + +mean([1, 2, 3]) +mean([1, 1, 4]) +puts "" + +median([1, 2, 3]) +median([1, 1, 4]) +puts "---END OF PROBLEM 2---" + +def pluck(hash, target) + number = 0 + if target == :name + number = 0 + elsif target == :instrument + number = 1 + end + hash.each do |i| + vals = i.values[number] + output = [] + output< + + #{render_head title} + #{render_body title, records[1..-1]} #omit first line of transaction_records, which is {date: 'date', payee: 'payee'..etc.} + + HTML +end + +def render_head(title) + < + #{title} + + HEAD +end + +def render_body(title, records) + < +

#{title}

+ #{render_records records} + + BODY +end + +def render_records(records) + < + #{render_table_header} + #{records.map {|r| render_record r}.join "\n"} + + RECORDS +end + +def render_table_header + < + DATE + Payee + Amount + Type + + TABLE_HEADER +end + +def render_record(r) + < + #{r[:date]} + #{r[:payee]} + #{r[:amount]} + #{r[:type]} + + RECORD +end From 69c64d389da4a009340f55519f2067cb0bab3c5c Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 29 Jan 2015 16:41:39 -0800 Subject: [PATCH 03/15] Update assignment01.rb --- assignments/assignment01.rb | 79 +++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/assignments/assignment01.rb b/assignments/assignment01.rb index d8cb398..3d31711 100644 --- a/assignments/assignment01.rb +++ b/assignments/assignment01.rb @@ -245,3 +245,82 @@ def render_record(r) RECORD end + + + + +#----------------- BEGINNING OF ASSIGNMENT 3 + +class String + def titleize + new_string = self.split(/\W+/) + new_string.map {|i| i.capitalize}.join(" ") + end +end + +"hEllo WORld".titleize +"gooDbye CRuel wORLD".titleize + +class String + def palindrome? + letters_only = self.gsub(/\W+/, "") + letters_only_downcase = letters_only.downcase + if letters_only_downcase == letters_only_downcase.reverse + return "true" + else + return "false" + end + end +end + +"abba".palindrome? +"aBbA".palindrome? +"A man, a plan, a canal, Panama".palindrome? +"abb".palindrome? +"Able was I ere I saw elba".palindrome? +"A man, a plan, a canal, Panama".palindrome? + +class Array + def mean + sum = 0 + self.each {|n| sum += n} + the_mean = sum/self.length.to_f + return the_mean.to_f + end + + def median + ordered_array = self.sort + number_of_elements = self.length + if number_of_elements % 2 != 0 + median_position = number_of_elements.to_i/2 + return ordered_array[median_position].to_f + else number_of_elements % 2 == 0 + median1 = ordered_array[self.length.to_i/2] + median2 = ordered_array[self.length.to_i/2-1] + return (median1.to_f+median2.to_f)/2 + end + end +end + +[1,2,5,6].mean +[1,1,4].mean +[1,2,3].median +[1,1,4].median + +class Array + def to_sentence + if self.length == 1 + return self + elsif self.length > 1 + last_element = [] + last_element << self.pop + join_elements = self.flatten.join(", ") + return join_elements+" and "+last_element[0].to_s + end + end +end + +[].to_sentence +["john"].to_sentence +["john", "paul"].to_sentence +[1, "paul", 3, "ringo"].to_sentence From 86ab62ec5bef16550b46b65e3c79f164fa9444b3 Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 29 Jan 2015 16:48:02 -0800 Subject: [PATCH 04/15] Update assignment01.rb --- assignments/assignment01.rb | 72 ++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/assignments/assignment01.rb b/assignments/assignment01.rb index 3d31711..d1fbda7 100644 --- a/assignments/assignment01.rb +++ b/assignments/assignment01.rb @@ -252,25 +252,25 @@ def render_record(r) #----------------- BEGINNING OF ASSIGNMENT 3 class String - def titleize - new_string = self.split(/\W+/) - new_string.map {|i| i.capitalize}.join(" ") - end + def titleize + new_string = self.split(/\W+/) + new_string.map {|i| i.capitalize}.join(" ") + end end "hEllo WORld".titleize "gooDbye CRuel wORLD".titleize class String - def palindrome? - letters_only = self.gsub(/\W+/, "") - letters_only_downcase = letters_only.downcase - if letters_only_downcase == letters_only_downcase.reverse - return "true" - else - return "false" - end - end + def palindrome? + letters_only = self.gsub(/\W+/, "") + letters_only_downcase = letters_only.downcase + if letters_only_downcase == letters_only_downcase.reverse + return "true" + else + return "false" + end + end end "abba".palindrome? @@ -281,25 +281,25 @@ def palindrome? "A man, a plan, a canal, Panama".palindrome? class Array - def mean + def mean sum = 0 self.each {|n| sum += n} the_mean = sum/self.length.to_f return the_mean.to_f - end - - def median - ordered_array = self.sort - number_of_elements = self.length - if number_of_elements % 2 != 0 - median_position = number_of_elements.to_i/2 - return ordered_array[median_position].to_f - else number_of_elements % 2 == 0 - median1 = ordered_array[self.length.to_i/2] - median2 = ordered_array[self.length.to_i/2-1] - return (median1.to_f+median2.to_f)/2 - end - end + end + + def median + ordered_array = self.sort + number_of_elements = self.length + if number_of_elements % 2 != 0 + median_position = number_of_elements.to_i/2 + return ordered_array[median_position].to_f + else number_of_elements % 2 == 0 + median1 = ordered_array[self.length.to_i/2] + median2 = ordered_array[self.length.to_i/2-1] + return (median1.to_f+median2.to_f)/2 + end + end end [1,2,5,6].mean @@ -309,14 +309,14 @@ def median class Array def to_sentence - if self.length == 1 - return self - elsif self.length > 1 - last_element = [] - last_element << self.pop - join_elements = self.flatten.join(", ") - return join_elements+" and "+last_element[0].to_s - end + if self.length == 1 + return self + elsif self.length > 1 + last_element = [] + last_element << self.pop + join_elements = self.flatten.join(", ") + return join_elements+" and "+last_element[0].to_s + end end end From 5e6863845382b7d9c5645dc7684891293cfc07ca Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 29 Jan 2015 17:12:59 -0800 Subject: [PATCH 05/15] Update assignment01.rb --- assignments/assignment01.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/assignments/assignment01.rb b/assignments/assignment01.rb index d1fbda7..ec32e7f 100644 --- a/assignments/assignment01.rb +++ b/assignments/assignment01.rb @@ -324,3 +324,19 @@ def to_sentence ["john"].to_sentence ["john", "paul"].to_sentence [1, "paul", 3, "ringo"].to_sentence + +#------START OF BANK ACCOUNT STATEMENT + +class BankAccount + attr_accessor :starting_balance +end + +class Transaction +end + +class DepositTransaction << Transaction +end + +class WithdrawalTransaction << Transaction +end + From c94873c81c35ce9dfc3fef97ab2c00eb1cac4be4 Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 5 Feb 2015 17:25:38 -0800 Subject: [PATCH 06/15] Added assignment 4 to the end of assignment 3 Added assignment 4 to the end of assignment 3 --- assignments/assignment01.rb | 198 ++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/assignments/assignment01.rb b/assignments/assignment01.rb index ec32e7f..cc64594 100644 --- a/assignments/assignment01.rb +++ b/assignments/assignment01.rb @@ -340,3 +340,201 @@ class DepositTransaction << Transaction class WithdrawalTransaction << Transaction end + +#----------------------------------------------------- START OF ASSIGNMENT #4 + +#UW Ruby Assignment #4 + + +#-------------------------------------------------------- Problem 1 + +def fibonacci(n) + if n < 0 + return "Can not calculate the Fibonacci sequence of a negative number." + elsif n == 0 || n == 1 + return 1 + else + fibonacci(n-1) + fibonacci(n-2) + end +end + +fibonacci(-2) +fibonacci(0) +fibonacci(1) +fibonacci(5) +fibonacci(4) +fibonacci(12) + +#-------------------------------------------------------- Problem 2 + +class Queue + class Node + attr_accessor :item, :link + def initialize(item, link) + @item = item + @link = link + end + end + + def initialize + @nodes = nil + end + + def enqueue(item) + node = @nodes + if node + while node.link + node = node.link + end + + node.link = Node.new(item, nil) + else + @nodes = Node.new(item, nil) + end + end + + def dequeue + node = @nodes + if node.nil? + @nodes = nil + else + @nodes = node.link + node.item + end + end + + def empty? + @nodes.nil? + end + + def peek + if @nodes.nil? + nil + else + @nodes.item + end + end + + def length + node = @nodes + i = 0 + while node + node = node.link + i += 1 + end + end +end + +q = Queue.new +q.empty? +q.enqueue "first" +q.empty? +q.enqueue "second" +q.dequeue +q.dequeue +q.dequeue + + +#------------------------------------------------------- Problem 3 + +class LinkedList + + class Node + attr_accessor :item, :link + def initialize(item, link) + @item = item + @link = link + end + end + + def initialize + @initialize = nil + @end = @initialize + end + + def empty? + @initialize.nil? + end + + def length + new_length = 0 + node = @initialize + while node + new_length += 1 + node = node.link + end + new_length + end + + def <<(item) + if @initialize.nil? + @initialize = Node.new(item, nil) + @end = @initialize + else + node_finish = @end + node_finish.link = Node.new(item, nil) + @end = node_finish.link + end + end + + def delete(item) + initial = nil + node = @initialize + + if @initialize.item == item + @initialize = @initialize.link + else + while node != item and node.item != item + initial = node + node = node.link + end + + if node == item and @end.item == item + @end = initial + @end.link = nil + elsif node + initial.link = node.link + else + nil + end + end + end + + def first + @initialize.item + end + + def last + @end.item + end + + def each(&block) + node = @initialize + while node do + block.call node.item + node = node.link + end + end +end + +ll = LinkedList.new +ll.empty? +ll << "first" +ll.empty? +ll.length +ll.first +ll.last + +ll << "second" +ll.length +ll.first +ll.last + +ll << "third" +ll.each {|x| puts x} + +ll.delete "second" +ll.length +ll.each {|x| puts x} + + From 206f7cb967afa471d5c6340e31af0c83d9813571 Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Wed, 11 Feb 2015 16:31:31 -0800 Subject: [PATCH 07/15] Revised and completed the csv to html problem Revised and completed the csv to html problem of assignment #2 --- assignments/assignment01.rb | 224 +++++++++++++++++++++++++++--------- 1 file changed, 168 insertions(+), 56 deletions(-) diff --git a/assignments/assignment01.rb b/assignments/assignment01.rb index cc64594..4488588 100644 --- a/assignments/assignment01.rb +++ b/assignments/assignment01.rb @@ -173,82 +173,194 @@ def pluck(hash, target) pluck(records, :instrument) puts "---END OF PROBLEM 3---" -def create_transaction(date, payee, amount, type) - {date: date, payee: payee, amount: amount, type: type} +def starting_balance_method + starting_balance = 0.00 end -transaction_records = {} -file_path = "/Users/hotero001/Documents/UW_ROR/assignment02-input.csv" -File.open(file_path) do |input| - records = input.readlines.map do |line| - fields = line.split(",") - transaction = create_transaction(fields[0], fields[1], fields[2], fields[3]) +def withdrawal_transactions + File.open("csv.csv") do |file| + lines = file.readlines + separation_processes = lines.shift.chomp.split(",") + withdrawals = [] + lines.each do |i| + if i.include?("withdrawal") + withdrawals << i + end + end + return withdrawals end - transaction_records = records - input.close end -def render_html(title, records) - < - - #{render_head title} - #{render_body title, records[1..-1]} #omit first line of transaction_records, which is {date: 'date', payee: 'payee'..etc.} - - HTML +def deposit_transactions + File.open("csv.csv") do |file| + lines = file.readlines + separation_processes = lines.shift.chomp.split(",") + deposits = [] + lines.each do |i| + if i.include?("deposit") + deposits << i + end + end + return deposits + end end -def render_head(title) - < - #{title} - - HEAD +def calculate_final_balance_after_all_transactions + File.open("csv.csv") do |file| + lines = file.readlines + separation_processes = lines.shift.chomp.split(",") + withdrawals = [] + deposits = [] + lines.each do |i| + if i.include?("withdrawal") + withdrawals << i + else + deposits << i + end + end + deposit_manip = deposits.map {|i| i.split(",")}.flatten! + deposit_txs = deposit_manip.reject {|i| deposit_manip.index(i).odd?} + deposit_sum = deposit_txs.each_slice(2).inject(0) {|i, (j,k)| i += k.to_f} + + withdrawal_manip = withdrawals.map {|i| i.split(",")}.flatten! + withdrawal_txs = withdrawal_manip.reject {|i| withdrawal_manip.index(i).odd?} + withdrawal_sum = withdrawal_txs.each_slice(2).inject(0) {|i, (j,k)| i += k.to_f} + + final_balance = deposit_sum - withdrawal_sum + return "Your balance after all transactions is $#{final_balance.round(2)}" + end end -def render_body(title, records) - < -

#{title}

- #{render_records records} - - BODY +def date_to_julian(some_date) +#method that converts the date in the format (mm/dd/yyyy) into a julian date +#*DID NOT ACCOUNT FOR LEAP YEAR, SINCE 2014 IS NOT A LEAP YEAR* + date_array = some_date.split("/") + month = date_array[0].to_i + day = date_array[1].to_i + if month == 1 + julian_date = day + elsif month == 2 + julian_date = 31 + day + elsif month == 3 + julian_date = 59 + day + elsif month == 4 + julian_date = 90 + day + elsif month == 5 + julian_date = 120 + day + elsif month == 6 + julian_date = 151 + day + elsif month == 7 + julian_date = 181 + day + elsif month == 8 + julian_date = 212 + day + elsif month == 9 + julian_date = 243 + day + elsif month == 10 + julian_date = 273 + day + elsif month == 11 + julian_date = 304 + day + elsif month == 12 + julian_date = 334 + day + else + puts "You did not enter a valid date" + daily_balance_up_until_some_date + end + return julian_date end -def render_records(records) - < - #{render_table_header} - #{records.map {|r| render_record r}.join "\n"} - - RECORDS +def daily_balance_up_until_some_date + puts "Please enter a date for which you would like to calculate your balance + up until the end of that date, in the following format mm/dd/yyyy, or if the + month or date is in the single digit, enter it in the following format + m/d/yyyy and then hit ENTER: " + end_date = gets.chomp + date_to_julian(end_date) + File.open("csv.csv") do |file| + lines = file.readlines + separation_processes = lines.shift.chomp.split(",") + new_lines = lines.reject {|i| date_to_julian(i[0..9]) > date_to_julian(end_date)} + withdrawals = [] + deposits = [] + new_lines.each do |i| + if i.include?("withdrawal") + withdrawals << i + else + deposits << i + end + end + deposit_manip = deposits.map {|i| i.split(",")}.flatten! + deposit_txs = deposit_manip.reject {|i| deposit_manip.index(i).odd?} + deposit_sum = deposit_txs.each_slice(2).inject(0) {|i, (j,k)| i += k.to_f} + + withdrawal_manip = withdrawals.map {|i| i.split(",")}.flatten! + withdrawal_txs = withdrawal_manip.reject {|i| withdrawal_manip.index(i).odd?} + withdrawal_sum = withdrawal_txs.each_slice(2).inject(0) {|i, (j,k)| i += k.to_f} + + final_balance_after_some_date = deposit_sum - withdrawal_sum + return "Your balance after all transactions up to the end of the day on #{end_date} is $#{final_balance_after_some_date.round(2)}" + end end -def render_table_header - < - DATE - Payee - Amount - Type - - TABLE_HEADER +def deposit_total_amount(some_deposits) + deposit_manip = some_deposits.map {|i| i.split(",")}.flatten! + deposit_txs = deposit_manip.reject {|i| deposit_manip.index(i).odd?} + deposit_sum = deposit_txs.each_slice(2).inject(0) {|i, (j,k)| i += k.to_f} + return deposit_sum.round(2) end -def render_record(r) - < - #{r[:date]} - #{r[:payee]} - #{r[:amount]} - #{r[:type]} - - RECORD +def withdrawals_total_amount(some_withdrawals) + withdrawal_manip = some_withdrawals.map {|i| i.split(",")}.flatten! + withdrawal_txs = withdrawal_manip.reject {|i| withdrawal_manip.index(i).odd?} + withdrawal_sum = withdrawal_txs.each_slice(2).inject(0) {|i, (j,k)| i += k.to_f} + return withdrawal_sum.round(2) end +def render_html + <<-HTML + + + Bank Account Statement + + + +
List of Withdrawals
+ #{withdrawal_transactions} + +
List of Deposits
+ #{deposit_transactions} + +
Daily Balance
+ #{daily_balance_up_until_some_date} + +

Summary

+ +
Starting Balance
+ #{starting_balance_method} + +
Sum of Deposits
+ #{deposit_total_amount(deposit_transactions)} + +
Sum of Withdrawals
+ #{withdrawals_total_amount(withdrawal_transactions)} + +
Ending Balance
+ #{calculate_final_balance_after_all_transactions} + + + + HTML +end + +def create_html_file(some_file) + File.open("csv.csv", "w") do |file| + file.write some_file + end +end +create_html_file(render_html) +#----------------- END OF PROBLEM 4 & ASSINGMENT 2 #----------------- BEGINNING OF ASSIGNMENT 3 class String From 11f67e90f7a190cdcee46cdea66d2d8f5cdae1c1 Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 12 Feb 2015 16:51:55 -0800 Subject: [PATCH 08/15] Assignment 5 Assignment 5 --- assignments/Assignment5.rb | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 assignments/Assignment5.rb diff --git a/assignments/Assignment5.rb b/assignments/Assignment5.rb new file mode 100644 index 0000000..0cad996 --- /dev/null +++ b/assignments/Assignment5.rb @@ -0,0 +1,33 @@ +require 'minitest/autorun' + +class Class + def prop_reader(prop_name) + define_method(prop_name) do + instance_variable_get("@#{prop_name}") + end + end +end + +class PropReader + prop_reader(:flavor) + + def initialize(flavor) + @flavor = flavor + end +end + +class PropReaderTest < Minitest::Test + def setup + @prop_reader = PropReader.new("spicy") + end + + def test_hacker + assert @prop_reader.respond_to? :flavor + refute @prop_reader.respond_to? :"flavor=" + end +end + +obj = PropReader.new("spicy") +puts obj.respond_to? :flavor #=> true +puts obj.respond_to? :"flavor=" #=> false +puts obj.flavor #=> spicy From 62ee797a9ead4ce4277e6aac7697083caa648c34 Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 12 Feb 2015 16:52:54 -0800 Subject: [PATCH 09/15] Update Assignment5.rb --- assignments/Assignment5.rb | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/assignments/Assignment5.rb b/assignments/Assignment5.rb index 0cad996..7066bc4 100644 --- a/assignments/Assignment5.rb +++ b/assignments/Assignment5.rb @@ -1,30 +1,30 @@ require 'minitest/autorun' class Class - def prop_reader(prop_name) - define_method(prop_name) do - instance_variable_get("@#{prop_name}") - end - end + def prop_reader(prop_name) + define_method(prop_name) do + instance_variable_get("@#{prop_name}") + end + end end class PropReader - prop_reader(:flavor) + prop_reader(:flavor) - def initialize(flavor) - @flavor = flavor - end + def initialize(flavor) + @flavor = flavor + end end class PropReaderTest < Minitest::Test - def setup - @prop_reader = PropReader.new("spicy") - end + def setup + @prop_reader = PropReader.new("spicy") + end - def test_hacker - assert @prop_reader.respond_to? :flavor - refute @prop_reader.respond_to? :"flavor=" - end + def test_hacker + assert @prop_reader.respond_to? :flavor + refute @prop_reader.respond_to? :"flavor=" + end end obj = PropReader.new("spicy") From 0529859b9d545a2664398e682e7bee72a897c038 Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 12 Feb 2015 16:53:17 -0800 Subject: [PATCH 10/15] Update Assignment5.rb --- assignments/Assignment5.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assignments/Assignment5.rb b/assignments/Assignment5.rb index 7066bc4..0b255f9 100644 --- a/assignments/Assignment5.rb +++ b/assignments/Assignment5.rb @@ -28,6 +28,6 @@ def test_hacker end obj = PropReader.new("spicy") -puts obj.respond_to? :flavor #=> true -puts obj.respond_to? :"flavor=" #=> false -puts obj.flavor #=> spicy +obj.respond_to? :flavor #=> true +obj.respond_to? :"flavor=" #=> false +obj.flavor #=> spicy From 9925da34ab6ce4eba258ef9eedc7c5746e8fda48 Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 12 Feb 2015 16:55:58 -0800 Subject: [PATCH 11/15] Update Assignment5.rb --- assignments/Assignment5.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/assignments/Assignment5.rb b/assignments/Assignment5.rb index 0b255f9..10bb003 100644 --- a/assignments/Assignment5.rb +++ b/assignments/Assignment5.rb @@ -1,3 +1,4 @@ +#------ASSIGNMENT #5 require 'minitest/autorun' class Class From 2313d25baa5fb8ae64186234e604a2292aaa06ce Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 19 Feb 2015 15:41:49 -0800 Subject: [PATCH 12/15] Update assignment01.rb --- assignments/assignment01.rb | 268 ++++++++++++++++++------------------ 1 file changed, 134 insertions(+), 134 deletions(-) diff --git a/assignments/assignment01.rb b/assignments/assignment01.rb index 4488588..8bcb873 100644 --- a/assignments/assignment01.rb +++ b/assignments/assignment01.rb @@ -462,11 +462,11 @@ class WithdrawalTransaction << Transaction def fibonacci(n) if n < 0 - return "Can not calculate the Fibonacci sequence of a negative number." + return "Can not calculate the Fibonacci sequence of a negative number." elsif n == 0 || n == 1 - return 1 + return 1 else - fibonacci(n-1) + fibonacci(n-2) + fibonacci(n-1) + fibonacci(n-2) end end @@ -480,61 +480,61 @@ def fibonacci(n) #-------------------------------------------------------- Problem 2 class Queue - class Node - attr_accessor :item, :link - def initialize(item, link) - @item = item - @link = link - end - end - - def initialize - @nodes = nil - end - - def enqueue(item) - node = @nodes - if node - while node.link - node = node.link - end - - node.link = Node.new(item, nil) - else - @nodes = Node.new(item, nil) - end - end - - def dequeue - node = @nodes - if node.nil? - @nodes = nil - else - @nodes = node.link - node.item - end - end - - def empty? - @nodes.nil? - end - - def peek - if @nodes.nil? - nil - else - @nodes.item - end - end - - def length - node = @nodes - i = 0 - while node - node = node.link - i += 1 - end - end + class Node + attr_accessor :item, :link + def initialize(item, link) + @item = item + @link = link + end + end + + def initialize + @nodes = nil + end + + def enqueue(item) + node = @nodes + if node + while node.link + node = node.link + end + + node.link = Node.new(item, nil) + else + @nodes = Node.new(item, nil) + end + end + + def dequeue + node = @nodes + if node.nil? + @nodes = nil + else + @nodes = node.link + node.item + end + end + + def empty? + @nodes.nil? + end + + def peek + if @nodes.nil? + nil + else + @nodes.item + end + end + + def length + node = @nodes + i = 0 + while node + node = node.link + i += 1 + end + end end q = Queue.new @@ -551,82 +551,82 @@ def length class LinkedList - class Node - attr_accessor :item, :link - def initialize(item, link) - @item = item - @link = link - end - end - - def initialize - @initialize = nil - @end = @initialize - end - - def empty? - @initialize.nil? - end - - def length - new_length = 0 - node = @initialize - while node - new_length += 1 - node = node.link - end - new_length - end - - def <<(item) - if @initialize.nil? - @initialize = Node.new(item, nil) - @end = @initialize - else - node_finish = @end - node_finish.link = Node.new(item, nil) - @end = node_finish.link - end - end - - def delete(item) - initial = nil - node = @initialize - - if @initialize.item == item - @initialize = @initialize.link - else - while node != item and node.item != item - initial = node - node = node.link - end - - if node == item and @end.item == item - @end = initial - @end.link = nil - elsif node - initial.link = node.link - else - nil - end - end - end - - def first - @initialize.item - end - - def last - @end.item - end - - def each(&block) - node = @initialize - while node do - block.call node.item - node = node.link - end - end + class Node + attr_accessor :item, :link + def initialize(item, link) + @item = item + @link = link + end +end + +def initialize + @initialize = nil + @end = @initialize +end + +def empty? + @initialize.nil? +end + +def length + new_length = 0 + node = @initialize + while node + new_length += 1 + node = node.link + end + new_length +end + +def <<(item) + if @initialize.nil? + @initialize = Node.new(item, nil) + @end = @initialize + else + node_finish = @end + node_finish.link = Node.new(item, nil) + @end = node_finish.link + end +end + +def delete(item) + initial = nil + node = @initialize + + if @initialize.item == item + @initialize = @initialize.link + else + while node != item and node.item != item + initial = node + node = node.link + end + + if node == item and @end.item == item + @end = initial + @end.link = nil + elsif node + initial.link = node.link + else + nil + end +end +end + +def first + @initialize.item +end + +def last + @end.item +end + +def each(&block) + node = @initialize + while node do + block.call node.item + node = node.link + end + end end ll = LinkedList.new From 0961297860074e3caa64ccf126d7006334dc91a7 Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 12 Mar 2015 17:38:45 -0700 Subject: [PATCH 13/15] Create assignment3.rb --- assignments/assignment3.rb | 149 +++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 assignments/assignment3.rb diff --git a/assignments/assignment3.rb b/assignments/assignment3.rb new file mode 100644 index 0000000..9f64de8 --- /dev/null +++ b/assignments/assignment3.rb @@ -0,0 +1,149 @@ +#THIS IS JUST THE CSV TO HTML CLASSES VERSION + +#Bank Account class that initializes an account with its file source and starting balance +class BankAccount + + attr_accessor :starting_balance + + def initialize(account_file, starting_balance, withdrawal_or_deposit_side) + @starting_balance = starting_balance + if withdrawal_or_deposit_side == "withdrawal_side" + Transaction.new(account_file, @starting_balance, "withdrawal_side") + elsif withdrawal_or_deposit_side == "deposit_side" + Transaction.new(account_file, @starting_balance, "deposit_side") + end + end +end + +#Transaction Class that separates transactions by withdrawal or deposit +class Transaction + + attr_accessor :withdrawals, :deposits, :starting_balance + + def initialize(account_file, starting_balance, withdrawal_or_deposit_side) + @starting_balance = starting_balance + if withdrawal_or_deposit_side == "withdrawal_side" + File.open(account_file) do |file| + lines = file.readlines + separation_processes = lines.shift.chomp.split(",") + @withdrawals = [] + lines.each do |transaction| + if transaction.include?("withdrawal") + @withdrawals << transaction + end + end + end + WithdrawalTransaction.new(@withdrawals, @starting_balance).render_withdrawal_summary + elsif withdrawal_or_deposit_side == "deposit_side" + File.open(account_file) do |file| + lines = file.readlines + separation_processes = lines.shift.chomp.split(",") + @deposits = [] + lines.each do |transaction| + if transaction.include?("deposit") + @deposits << transaction + end + end + end + DepositTransaction.new(@deposits, @starting_balance).render_deposit_summary + end + end +end + +#Deposit Transaction Class that inherits from Transaction +class DepositTransaction < Transaction + + attr_accessor :starting_balance, :sum_of_deposits, :deposits + + def initialize(deposits, starting_balance) + @deposits = deposits + @starting_balance = starting_balance + array_of_deposits = @deposits.map {|i| i.split(",")}.flatten! + array_of_deposits.delete_if {|item| item.to_f == 0 || item.include?("/")} + array_of_deposit_floats = array_of_deposits.map {|i| i.to_f} + @sum_of_deposits = array_of_deposit_floats.inject(:+) + end + + def render_deposit_summary + @deposits + @sum_of_deposits + end +end + +#Withdrawal Transaction Class that inherits from Transaction +class WithdrawalTransaction < Transaction + + attr_accessor :starting_balance, :sum_of_withdrawals, :withdrawals + + def initialize(withdrawals, starting_balance) + @withdrawals = withdrawals + @starting_balance = starting_balance + @withdrawals + array_of_withdrawals = @withdrawals.map {|i| i.split(",")}.flatten! + array_of_withdrawals.delete_if {|item| item.to_f == 0 || item.include?("/")} + array_of_withdrawals_floats = array_of_withdrawals.map {|i| i.to_f} + @sum_of_withdrawals = array_of_withdrawals_floats.inject(:+) + end + + def render_withdrawal_summary + @withdrawals + @sum_of_withdrawals + end +end + +#Class that calculates the final balance after all transactions +class BankAccountBalance + attr_accessor :finito + + def initialize(starting_balance, deposits, withdrawals) + @final_bal = starting_balance+deposits-withdrawals + end +end + +#Class that renders HTML +class HtmlRender + + def render_html + <<-HTML + + + Bank Account Statement + + + + +
List of Withdrawals
+ #{Transaction.new("csv.csv", 0.0, "withdrawal_side").withdrawals} + +

Sum of Withdrawal Transactions, in USD($)

+ #{WithdrawalTransaction.new(Transaction.new("csv.csv", 0.0, "withdrawal_side").withdrawals, 0.0).sum_of_withdrawals.to_f} + +
List of Deposits
+ #{Transaction.new("csv.csv", 0.0, "deposit_side").deposits} + +

Sum of Deposit Transactions, in USD($)

+ #{DepositTransaction.new(Transaction.new("csv.csv", 0.0, "deposit_side").deposits, 0.0).sum_of_deposits.to_f} + +
Starting Balance, in USD($)
+ #{BankAccount.new("csv.csv", 0.0, "").starting_balance} + +
Ending Balance, in USD($)
+ #{BankAccountBalance.new(BankAccount.new("csv.csv", 0.0, "").starting_balance.to_f, + DepositTransaction.new(Transaction.new("csv.csv", 0.0, "deposit_side").deposits, 0.0).sum_of_deposits.to_f, + WithdrawalTransaction.new(Transaction.new("csv.csv", 0.0, "withdrawal_side").withdrawals, 0.0).sum_of_withdrawals.to_f).final_bal} + + + HTML + end +end + +#Method that Modifies the csv file and overwrites it as HTML +def create_html_file(some_file) + File.open("csv.csv", "w") do |file| + file.write some_file + end +end + +#Program execution +start = HtmlRender.new +#create_html_file(start.render_html) From 3c75c03285e4d8a1cfdc1c61fffab1999e659de6 Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 12 Mar 2015 17:44:00 -0700 Subject: [PATCH 14/15] assignment 6 --- assignments/Assignment6.rb | 140 +++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 assignments/Assignment6.rb diff --git a/assignments/Assignment6.rb b/assignments/Assignment6.rb new file mode 100644 index 0000000..1e5ca82 --- /dev/null +++ b/assignments/Assignment6.rb @@ -0,0 +1,140 @@ +#ASSIGNMENT 6 + +#========================================= ASSIGNMENT #6 #1 + +class PriorityQueue + def initialize + @high_hash = {} + @medium_hash = {} + @low_hash = {} + end + + def enqueue(item, priority=:medium) + if priority == :high + @high_hash[item] = priority + elsif priority == :medium + @medium_hash[item] = priority + elsif priority == :low + @low_hash[item] = priority + end + end + + def dequeue + if ! @high_hash.empty? + @high_hash.shift + elsif ! @medium_hash.empty? + @medium_hash.shift + elsif ! @low_hash.empty? + @low_hash.shift + end + end + + def empty? + if @high_hash.empty? and @medium_hash.empty? and @low_hash.empty? + return true + else + return false + end + end + + def peek + if ! @high_hash.empty? + @high_hash.keys[0] + elsif ! @medium_hash.empty? + @medium_hash.keys[0] + elsif ! @low_hash.empty? + @low_hash.keys[0] + end + end + + def length + @high_hash.count + @medium_hash.count + @low_hash.count + end +end + +class PriorityTest < Minitest::Test + + def test_hacker + pq = PriorityQueue.new + assert_empty pq + assert_equal pq.enqueue("first"), :medium + refute_empty pq + assert_equal pq.enqueue("top", :high), :high + assert_equal pq.enqueue("last", :low), :low + assert_equal pq.enqueue("second"), :medium + assert_equal pq.enqueue("another top", :high), :high + assert_equal pq.length, 5 + assert_equal pq.dequeue[0], "top" + assert_equal pq.dequeue[0], "another top" + assert_equal pq.dequeue[0], "first" + assert_equal pq.dequeue[0], "second" + assert_equal pq.dequeue[0], "last" + end +end + +#============================== RECIPE TO DSL, HW 6 PROBLEM 2 + +class Recipe + attr_accessor :steps, :ingredients, :name, :category, :prep_time, :rating + def initialize(name, ingredients, prep_time, category, rating, steps) + @name = name + @ingredients = ingredients + @prep_time = prep_time + @category = category + @rating = rating + @steps = steps + end + + def recipe_name + @name.map {|nam| "-#{nam}"} + end + + def recipe_ingredients + @ingredients.map {|ing| "- #{ing}"} + end + + def recipe_prep_time + @prep_time.map {|pt| "- #{pt}"} + end + + def recipe_category + @category.map {|cat| "-#{cat}"} + end + + def recipe_rating + @rating.map {|rate| "- #{rate}"} + end + + def recipe_steps + @steps.map {|stp| "- #{stp}"} + end + + def render_dsl + html do + head do + title Recipe + stylesheet_link_tag 'scaffold' + end + + body do + "#{recipe_name}" + "#{recipe_prep_time}" + "#{recipe_category}" + "#{recipe_rating}" + "#{recipe_ingredients}" + "#{recipe_steps}" + end + end + end +end + +ingred = ["tortilla", "ground beef", "guac", "cheese"] +nombr = ["The Texas Taco"] +categ = ["TexMex"] +prep_t = ["15 minutes"] +rated = ["8 out of 10"] +stepp = ["cook ground beef", "cut guac", "spread equal amounts of each #{ingred[1]}, +#{ingred[2]}, and #{ingred[3]} on a #{ingred[0]}"] + +new_recipe = Recipe.new(ingred, nombr, categ, prep_t, rated, stepp) +new_recipe.render_dsl From 165da3669868c2c0c6987f759ae04dfb5db7efde Mon Sep 17 00:00:00 2001 From: Hector Otero Date: Thu, 12 Mar 2015 17:57:05 -0700 Subject: [PATCH 15/15] Update assignment3.rb --- assignments/assignment3.rb | 461 +++++++++++++++++++++++++++++++++++++ 1 file changed, 461 insertions(+) diff --git a/assignments/assignment3.rb b/assignments/assignment3.rb index 9f64de8..a1e4579 100644 --- a/assignments/assignment3.rb +++ b/assignments/assignment3.rb @@ -147,3 +147,464 @@ def create_html_file(some_file) #Program execution start = HtmlRender.new #create_html_file(start.render_html) + +#========== ASSIGNMENT 6 + +class PriorityQueue + def initialize + @high_hash = {} + @medium_hash = {} + @low_hash = {} + end + + def enqueue(item, priority=:medium) + if priority == :high + @high_hash[item] = priority + elsif priority == :medium + @medium_hash[item] = priority + elsif priority == :low + @low_hash[item] = priority + end + end + + def dequeue + if ! @high_hash.empty? + @high_hash.shift + elsif ! @medium_hash.empty? + @medium_hash.shift + elsif ! @low_hash.empty? + @low_hash.shift + end + end + + def empty? + if @high_hash.empty? and @medium_hash.empty? and @low_hash.empty? + return true + else + return false + end + end + + def peek + if ! @high_hash.empty? + @high_hash.keys[0] + elsif ! @medium_hash.empty? + @medium_hash.keys[0] + elsif ! @low_hash.empty? + @low_hash.keys[0] + end + end + + def length + @high_hash.count + @medium_hash.count + @low_hash.count + end +end + +class PriorityTest < Minitest::Test + + def test_hacker + pq = PriorityQueue.new + assert_empty pq + assert_equal pq.enqueue("first"), :medium + refute_empty pq + assert_equal pq.enqueue("top", :high), :high + assert_equal pq.enqueue("last", :low), :low + assert_equal pq.enqueue("second"), :medium + assert_equal pq.enqueue("another top", :high), :high + assert_equal pq.length, 5 + assert_equal pq.dequeue[0], "top" + assert_equal pq.dequeue[0], "another top" + assert_equal pq.dequeue[0], "first" + assert_equal pq.dequeue[0], "second" + assert_equal pq.dequeue[0], "last" + end +end + +#============================== RECIPE TO DSL, HW 6 PROBLEM 2 + +class Recipe + attr_accessor :steps, :ingredients, :name, :category, :prep_time, :rating + def initialize(name, ingredients, prep_time, category, rating, steps) + @name = name + @ingredients = ingredients + @prep_time = prep_time + @category = category + @rating = rating + @steps = steps + end + + def recipe_name + @name.map {|nam| "-#{nam}"} + end + + def recipe_ingredients + @ingredients.map {|ing| "- #{ing}"} + end + + def recipe_prep_time + @prep_time.map {|pt| "- #{pt}"} + end + + def recipe_category + @category.map {|cat| "-#{cat}"} + end + + def recipe_rating + @rating.map {|rate| "- #{rate}"} + end + + def recipe_steps + @steps.map {|stp| "- #{stp}"} + end + + def render_dsl + html do + head do + title Recipe + stylesheet_link_tag 'scaffold' + end + + body do + "#{recipe_name}" + "#{recipe_prep_time}" + "#{recipe_category}" + "#{recipe_rating}" + "#{recipe_ingredients}" + "#{recipe_steps}" + end + end + end +end + +ingred = ["tortilla", "ground beef", "guac", "cheese"] +nombr = ["The Texas Taco"] +categ = ["TexMex"] +prep_t = ["15 minutes"] +rated = ["8 out of 10"] +stepp = ["cook ground beef", "cut guac", "spread equal amounts of each #{ingred[1]}, +#{ingred[2]}, and #{ingred[3]} on a #{ingred[0]}"] + +new_recipe = Recipe.new(ingred, nombr, categ, prep_t, rated, stepp) +new_recipe.render_dsl + +#======== ASSIGNMENT #7 + +#================================ #ASSIGNMENT 7 + +module Observable + + def add_observer(obj) + @observed_objects << obj if !@observed_objects.include?(obj) + end + + def delete_observer(obj) + @observed_objects.delete(obj) + end + + def delete_observers + @observed_objects.clear + end + + def count_observers + @observed_objects.count + end + + def changed(new_state=true) + @changed = new_state + end + + def changed? + if @changed.nil? + @changed = false + end + @changed + end + + def notify_observers(*args) + if changed? + @observed_objects.each {|observed_object| observed_object.update(*args)} + @changed = false + end + end +end + +class PressureTransducer + include Observable + + def initialize(initial_pressure_atm) + @pressure = initial_pressure_atm + @observed_objects = [] + #@change_status = false + #@observed_objects = [] + #@pressure = initial_pressure_atm + #add_observer(@pressure) + end + + def pressuring + last_pressure = nil + loop do + pressure = Pressure.fetch(@pressure) + if pressure != last_pressure + changed + last_pressure = pressure + notify_observers(Time.now, pressure) + end + sleep 1 + end + end + + def pressure_up + #changed + @pressure = @pressure + 1 + #changed + #notify_observers(@pressure) + end + + def pressure_down + @pressure = @pressure - 1 + #changed + #notify_observers(@pressure) + end +end + +class Pressure + def Pressure.fetch(press) + 12 + rand(1..10) + end +end + +class PressureWarningHigh + def initialize(pressure_transducer, limit) + @limit = limit + pressure_transducer.add_observer(self) + end + + def update(flow, pressure) + if pressure > @limit + puts "Pressure limit has been exceeded. She is going to blow, fellas! Run!" + end + end +end + +class ObservableTest < Minitest::Test + def test_hacker + pressure_transducer = PressureTransducer.new(12) + assert_equal pressure_transducer.count_observers, 0 + assert_equal pressure_transducer.pressure_up, 13 + assert_equal pressure_transducer.pressure_down, 12 + end +end + +#=============================================== ASSIGNMENT #8 +class RomanNumeral + def initialize(i) + @i = i + @roman_hash = {100=>"C", 90=>"XC",50=>"L",40=>"XL",10=>"X",9=>"IX", + 5=>"V",4=>"IV",1=>"I"} + @roman_num = "" + end + + def to_s + @roman_hash.keys.each do |n| + q,m = @i.divmod(n) + @roman_num << @roman_hash[n] * q + @i = m + end + @roman_num + end + + def to_i + #COMPLETE THIS SECTION IF TIME REMAINS + end + + def self.from_string + #COMPLETE THIS SECTION IF TIME REMAINS + end +end + +class RomanTest < MiniTest::Test + def test_hacker + assert_equal "I", RomanNumeral.new(1).to_s + assert_equal "II", RomanNumeral.new(2).to_s + assert_equal "III", RomanNumeral.new(3).to_s + assert_equal "IV", RomanNumeral.new(4).to_s + assert_equal "V", RomanNumeral.new(5).to_s + assert_equal "VI", RomanNumeral.new(6).to_s + assert_equal "IX", RomanNumeral.new(9).to_s + assert_equal "X", RomanNumeral.new(10).to_s + assert_equal "XIX", RomanNumeral.new(19).to_s + assert_equal "XXXII", RomanNumeral.new(32).to_s + assert_equal "LI", RomanNumeral.new(51).to_s + end +end + +#============================================= ASSIGNMENT #8, problem 2 + +def golden_ratio(precision) +=begin +I decided to use the mathematical definition of the golden +ratio, which is golden_ratio = .5*(1+sqrt(5)) +=end + square = Math.sqrt(5)+1 + golden_r = (square/2) + golden_r_prec = golden_r.round(precision) + return golden_r_prec +end + +class GoldenTest < MiniTest::Test + def test_hacker + assert_equal 1.62, golden_ratio(2) + assert_equal 1.61803, golden_ratio(5) + assert_equal 1.61803399, golden_ratio(8) + end +end + +#======================================== GAME OF LIFE + +class GameOfLife + + attr_reader :matrix + + #==========SET UP GAME MATRIX + def initialize(rows, columns, input) + @matrix = rows.times.map do |y| + columns.times.map do |x| + Cell.new(self, x, y, rand(input).to_i.even?) + end + end + end + + #==========GAME ENGINE ON INFINITE LOOP + def play + while(true) + system('clear') + render_board + board_update + sleep(5) + end + end + + #======= METHOD ONLY USED TO VALIDATE TESTS + def play_test + + cel = [cell_location(2, 2), cell_location(3, 2), cell_location(4, 2), + cell_location(2, 3 ), cell_location(4, 3 ), + cell_location(2, 4), cell_location(3, 4), cell_location(4, 4)] + #STILL NEED TO FINISH TESTING ENTIRELY + + puts cell_location(3, 3) + render_board + board_update + puts cell_location(3, 3) + end + + #============DISPLAYS BOARD RESULTS + def render_board + board_row = "%" * (matrix.first.size * 2 + 3) + [ + "\n"*4, + board_row, + matrix.map{|row| "% " + row.join(" ") + " %" }, + board_row, + ].flatten.each do |line| + puts line + end + end + + #================UPDATES BOARD RESULTS FOR NEXT ROUND + def board_update + matrix.each do |row| + row.each do |cell| + cell.board_updates + end + end + end + + #================CELL LOCATIONS + def cell_location(x, y) + matrix.fetch(y){[]}[x] + end +end + +class Cell + + attr_reader :x, :y, :game, :living, :neighbors + + #==================INITIALIZES STATES OF EACH CELL + def initialize(game, x, y, state) + @game = game + @x = x + @y = y + @living = state + end + + def dead + @living = false + end + + def rebirth + @living = true + end + + def is_cell_alive? + @living == true + end + + def dead? + !is_cell_alive? + end + + #================DEFINES NEIGHBORING CELLS + def neighbors + @neighbors ||= begin + [ + game.cell_location(x-1, y-1), game.cell_location(x, y-1), game.cell_location(x+1, y-1), + game.cell_location(x-1, y ), game.cell_location(x+1, y ), + game.cell_location(x-1, y+1), game.cell_location(x, y+1), game.cell_location(x+1, y+1) + ].compact + end + end + + def live_neighbors + neighbors.select(&:is_cell_alive?) + end + + def under_populated? + is_cell_alive? and live_neighbors.size < 2 + end + + def over_populated? + is_cell_alive? and live_neighbors.size > 3 + end + + def to_be_reproduced? + dead? and live_neighbors.size == 3 + end + + #===============UPDATES THE STATUS OF EACH CELL + def board_updates + if under_populated? + dead + elsif over_populated? + dead + elsif to_be_reproduced? + rebirth + end + end + + def to_s + is_cell_alive? ? "x" : " " + end +end + +#================INITIATE GAME PLAY(COMMENTED OUT TO ALLOW FOR TESTING) +#new_game = GameOfLife.new(10,10,Time.now.to_i) +#new_game.play +#new_game.play_test + +class GameOfLifeTesting < Minitest::Test + def test_hacker + new_game = GameOfLife.new(10,10,Time.now.to_i) + refute_empty new_game.matrix + end +end