Why am I getting this undefined method error when the method is defined?
(I'm now going to wast some text so the dumb "your post is mostly code" warning goes away. Since a real developer spends most of their time reading code and this is a simple problem I don't need any more words)
Here is my error message:
$ ruby roman_numerals_test.rb
Run options: --seed 35835
# Running:
Run options: --seed 35835
# Running:
SSSSSSSSSSEE
Error:
RomanNumeralsTest#test_1:
NoMethodError: undefined method `to_roman' for 1:Integer
roman_numerals_test.rb:8:in `test_1'
bin/rails test roman_numerals_test.rb:7
Here is my test file:
gem 'minitest', '>= 5.0.0'
require 'minitest/autorun'
require_relative 'roman_numerals'
# Common test data version: 1.0.0 070e8d5
class RomanNumeralsTest < Minitest::Test
def test_1
assert_equal 'I', 1.to_roman
end
def test_2
assert_equal 'II', 2.to_roman
end
def test_3
skip
assert_equal 'III', 3.to_roman
end
def test_4
skip
assert_equal 'IV', 4.to_roman
end
def test_5
skip
assert_equal 'V', 5.to_roman
end
def test_6
skip
assert_equal 'VI', 6.to_roman
end
def test_9
skip
assert_equal 'IX', 9.to_roman
end
def test_27
skip
assert_equal 'XXVII', 27.to_roman
end
def test_48
skip
assert_equal 'XLVIII', 48.to_roman
end
def test_59
skip
assert_equal 'LIX', 59.to_roman
end
def test_93
skip
assert_equal 'XCIII', 93.to_roman
end
def test_141
skip
assert_equal 'CXLI', 141.to_roman
end
def test_163
skip
assert_equal 'CLXIII', 163.to_roman
end
def test_402
skip
assert_equal 'CDII', 402.to_roman
end
def test_575
skip
assert_equal 'DLXXV', 575.to_roman
end
def test_911
skip
assert_equal 'CMXI', 911.to_roman
end
def test_1024
skip
assert_equal 'MXXIV', 1024.to_roman
end
def test_3000
skip
assert_equal 'MMM', 3000.to_roman
end
def test_bookkeeping
assert_equal 2, BookKeeping::VERSION
end
end
And here is my code:
module BookKeeping
VERSION = 2
end
class Numeral
def initialize(number)
#number = number
end
def to_roman
roman_hash = {
1000 => 'M',
900 => 'CM',
500 => 'D',
400 => 'CD',
100 => 'C',
90 => 'XC',
50 => 'L',
40 => 'XL',
10 => 'X',
9 => 'IX',
5 => 'V',
4 => 'IV',
1 => 'I'
}
my_string = ""
roman_hash.each do |key, value|
(#number / key).times {my_string << value; #number = #number - key}
end
my_string
end
end
You're defining to_roman for Numeral objects but 1 is an Integer. Try
class Integer
or
class Numeric
(superclass of Integer)
Related
gem 'minitest', '~> 5.2'
# TDD
require 'minitest/autorun'
require 'minitest/pride'
require_relative 'kid'
class KidTest < Minitest::Test
def test_kid_has_not_eaten_sugar
kid = Kid.new
assert_equal 0, kid.grams_of_sugar_eaten
end
def test_kid_gets_5_grams_from_eating_candy
kid = Kid.new
kid.eat_candy
assert_equal 5, kid.grams_of_sugar_eaten
5.times { kid.eat_candy }
assert_equal 30, kid.grams_of_sugar_eaten
end
def test_kid_is_not_hyperactive
kid = Kid.new
refute kid.hyperactive?
end
def test_kid_is_hyperactive_after_60_grams_of_sugar
kid = Kid.new
11.times { kid.eat_candy }
refute kid.hyperactive?, "Not hyperactive yet..."
kid.eat_candy
assert kid.hyperactive?, "OK, now the kid is hyperactive."
end
end
# CODE
class Kid
attr_reader :grams_of_sugar_eaten
def initialize
#grams_of_sugar_eaten = 0
end
def eat_candy(grams = 5)
#grams_of_sugar_eaten += grams
end
def hyperactive?
false
end
end
Can anyone help direct me in the thinking that I should have as far as how to go about getting the 2nd test to pass and so on?
I'm not sure what to do make the test pass after the kid eats 5 grams of sugar and then after 5.times to have it pass after he eats 30 grams of sugar.
Appreciate any help
You've added eat_candy as an attr_reader, not a method. The initialize function here sets eat_candy to itself.
A possible fix:
class Kid
attr_reader :grams_of_sugar_eaten
def initialize
#grams_of_sugar_eaten = 0
end
def eat_candy(grams = 5)
#grams_of_sugar_eaten += grams
end
end
I am trying to get programm started where i cant read in a csv File an it prints the data out on a pdf-File. Now i have a problem.
Heres is my Code:
------------------------------------
require_relative 'friends'
class List
attr_accessor :list_name, :list
def initialize(list_name)
#list_name = list_name
#list = []
end
def list_name
#list_name
end
def liste
#list
end
def wert(place)
#list[place].to_s
end
def list_length
#list.length
end
def print_list
#list.each do |freunde|
"#{freunde.name},#{freunde.age}"
end
end
def add_friend(a_friend)
#list.push(a_friend)
end
def load_friend(from_file)
File.readlines(from_file).each do |line|
add_friend(Freunde.from_csv(line))
end
end
end
-------------------------------------------
require_relative 'list'
class Friends
attr_accessor :name,:age
def initialize(name, age)
#name = name
#age = age
end
def self.from_csv(string)
name, age = string.split(',')
Freunde.new(name,age)
end
def friends
#name
end
end
-------------------------------------------
require 'prawn'
require_relative 'list'
require_relative 'friends'
class Generating
include Prawn::View
def initialize
#document = Prawn::Document.new(:page_size => "A4")
#fontpath = File.expand_path("../data/fonts", __FILE__)
liste1 = Listen.new("Friendslist")
liste1.load_friend("test.csv")
print_list
save
end
def print_friends
font("#{#fontpath}/Arial.ttf") do
font_size 11
text_box("#{liste1.print_list}", :at => [15,405], :height => 50,
:width => 250)
end
end
def save
self.render_file "Hello.pdf"
end
end
---------------------------------------------
When i now create a new generating-Object:
gen = Generating.new
then it fails the whole programm because the error says method unknow (print_list). Am i submitting the wrong object for the method(print_list), or am using the text output methods of prawn wrong?
print_list is an instance method of List class, and you call it on self object, which is there an instance of Generating. It should be:
liste1 = Listen.new("Friendslist")
liste1.load_friend("test.csv")
#⇓⇓⇓⇓⇓⇓
liste1.print_list
I am having a little trouble getting my code to run and have been at it for at least 4 hours...I can't seem to figure it out. BTW I am a newb at programming.
This is the UML diagram for the card/deck
http://imgur.com/lBJw2z0
class Card
#Cards rank from lowest to highest
VALUE = %w(2 3 4 5 6 7 8 9 10 J Q K A)
SUITS = %w(C D H S)
#(Club Diamond Heart Spade)
def initialize(the_rank, the_suit)
[#rank = the_rank]
[#suit = the_suit]
[#symbols = [nil, nil, '2', '3', '4', '5', '6', '7',
'8', '9', '10', 'J', 'Q', 'K', 'A']
end
def rank
[return #symbols[#rank]]
end
def suit
return #suit
end
def to_s
"#{rank()}#{suit()}"
end
end
#double loop for Deck#initialize
#cards = [ ]
for rank in 2..14
for suit in ['C', 'D', 'H', 'S']
# create a new card with the specified rank
# and suit and append it to the array.
end
end
suits.each do |suit|
(ranks.size).times do |i|
#cards.push(Card.new(ranks[i], suit,(i+1)))
end
end
#Remove a card from the top
def deal
[#cards.pop()](1)
end
#Add card to the bottom of the deck
def add_to_bottom(the_card)
#cards.insert(0, the_card)
end
#Add card to the top of the deck
def add_to_top(the_card)
#cards << the_card
end
#Shuffle the Card objects in the deck
def shuffle!
#cards.shuffle!
end
def count()
#cards.count()
end
def empty?
#cards.length == 0
end
def to_s
string = ""
#cards.each do |card|
string += card.to_s + " "
end
end
def cards
#cards
end
end
I haven't tested this very thoroughly, but it basically implements the UML diagram you linked to:
class Deck
def initialize
#ranks = %w(2 3 4 5 6 7 8 9 10 J Q K A)
#suits = %w(Clubs Diamonds Hearts Spades)
#cards = []
#ranks.each do |rank|
#suits.each do |suit|
#cards << Card.new(rank, suit)
end
end
end
def deal
#cards.shift
end
def add_to_bottom(card)
#cards.unshift(card)
end
def add_to_top(card)
#cards << card
end
def count
#cards.count
end
def empty?
#cards.empty?
end
def shuffle!
#cards.shuffle
end
def to_s
result = ''
#cards.each do |card|
result = result + card.to_s + "\n"
end
return result
end
end
class Card
attr_reader :rank, :suit, :color
def initialize(rank, suit)
#rank = rank
#suit = suit
if #rank == 'Clubs' || #rank == 'Spades'
#color = 'black'
else
#color = 'red'
end
end
def to_s
"Card: #{#color} #{#rank} of #{#suit}"
end
end
# Run it, and try some stuff...
my_deck = Deck.new
puts my_deck.to_s
my_deck.deal
my_deck.count
my_deck.shuffle!
puts my_deck.to_s
my_deck.deal
my_deck.count
Now I am trying to figure how the testing method. I have the first working
d = Deck.new
d.cards.each do |card|
puts "#{card.rank} #{card.suit}"
end
And the second method that needs to test:
tests both the Card and Deck classes using the unit test framework with assert_equal methods. Write unit tests for all methods in the Card class, but you only have to test these methods in the Deck class: new, deal, add_to_bottom, add_to_top, count, empty?
I'm creating a class that creates arrays. (Yes, I realize that's already available in ruby. This is more of an exercise.) The class, SpecialArray, creates an array based on input that's either given by the user when creating a new array or added to the array later. I'm having trouble connecting these two pieces of functionality. Creating an array works fine, but adding to it does not. I had thought that the output atrr_reader would hold the exiting array in memory, but now I'm not sure. Any idea how I can make this work?
class SpecialArray
attr_reader :input, :output
def initialize(*input)
#input = input.flatten
#output = []
generate_array
end
def generate_array
input.each do |e|
add(e)
end
output
end
#update start
def numerical(element)
element.class == Fixnum
end
def unique(element)
output.include? element ? false : true
end
def valid_e(element)
unique(element) && numerical(element)
end
def numerical(elment)
element.class == Fixnum
end
def unique(element)
output.include? element ? false : true
end
def valid_e(element)
unique(element) && numerical(element)
end
#update end
def add(element)
unless valid_e(element) == false
output.push(element)
end
output
end
end
Seems to work fine to me, both #input and #output contain the array I passed in:
irb(main):032:0> a = SpecialArray.new(1,2,3,4,5,6,7);
irb(main):034:0> puts a.inspect
#<SpecialArray:0x296e7e8 #input=[1, 2, 3, 4, 5, 6, 7],
#output=[1, 2, 3, 4, 5, 6, 7]>
=> nil
EDIT Full Code
irb(main):001:0> class SpecialArray
irb(main):002:1> attr_reader :input, :output
irb(main):003:1>
irb(main):004:1* def initialize(*input)
irb(main):005:2> #input = input.flatten
irb(main):006:2> #output = []
irb(main):007:2> generate_array
irb(main):008:2> end
irb(main):009:1>
irb(main):010:1* def generate_array
irb(main):011:2> input.each do |e|
irb(main):012:3* add(e)
irb(main):013:3> end
irb(main):014:2> output
irb(main):015:2> end
irb(main):016:1>
irb(main):017:1* #...
irb(main):018:1*
irb(main):019:1* def add(element)
irb(main):020:2> unless valid_e(element) == false
irb(main):021:3> output.push(element)
irb(main):022:3> end
irb(main):023:2> output
irb(main):024:2> end
irb(main):025:1>
irb(main):026:1* def valid_e(e)
irb(main):027:2> return true;
irb(main):028:2* end
irb(main):029:1>
irb(main):030:1* #...
irb(main):031:1* end
=> nil
irb(main):032:0> a = SpecialArray.new(1,2,3,4,5,6,7);
irb(main):034:0> puts a.inspect
#<SpecialArray:0x296e7e8 #input=[1, 2, 3, 4, 5, 6, 7],
#output=[1, 2, 3, 4, 5, 6, 7]>
=> nil
class Mycompute
def initialize(str)
#str=str
end
def values
##result=#str
end
def up
##result.upcase
end
end
irb(main):012:0> Mycompute.new("Abc").values
=> "Abc"
irb(main):013:0>
irb(main):014:0* Mycompute.new("Abc").up
=> "ABC"
irb(main):015:0> Mycompute.new("Abc").values.up
NoMethodError: undefined method `up' for "Abc":String
from (irb):15
from :0
How can I make Mycompute.new("Abc").values.up work?
The object returned from values need have up.
class Mycompute
def initialize(str)
#str=str
end
def values
##result=#str
def ##result.up
self.upcase
end
##result
end
def up
##result.upcase
end
end
This works well.
Mycompute.new("Abc").values #=> "Abc"
Mycompute.new("Abc").up #=> "ABC"
Mycompute.new("Abc").values.up #=> "ABC"