Assignment 2: Command-line application
This assignment will require you to write a command-line application that implements a number of classes.
This assignment will have two parts: First, the main project, then a brief follow-up where you will save some of the data to a database with ActiveRecord.
The first part is available on the downloads page.
Add New Comment
Viewing 109 Comments
Thanks. Your comment is awaiting approval by a moderator.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
The error is:
NoMethodError: undefined method `method1' for []:Array
I get the error when I run the case statement. Any idea what's happening?
def thismethod()
myvariable = case
when @hand.method1() == true
something
when @hand.method2() == true
something!
else
nothing
end
end
Do you already have an account? Log in and claim this comment.
@hand.method1()
Does @hand have a method called "method1" on it?
The error message (did you read it?) says: undefined method `method1' for []:Array
So it would seem that when @hand.method1() is executed, @hand is an Array, perhaps; is it? You can find out what class it is before this statement is run by adding:
puts @hand.class
John
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
1) I cannot mixin "shuffle" due to its not being part of "Enumerable". Do I have to use "srand" or require "SecureRandom" to return integers between 0 and 52? I am having trouble imagining how to use such random number generators in a one-liner to shuffle the array.
2) I get the error "undefined method 'card_number' for 51:Fixnum". Does this mean that I have to use a Metaprogramming Singleton to create a class for the already dynamic "51"? I tried it unsuccessfully. I will try again, but just want to know if I am headed in a good direction.
Do you already have an account? Log in and claim this comment.
Simply write your own shuffle method. The shuffle could be as simple as exchanging the cards many, many times by random switches.
Regarding the undefined method card_number : Have you defined an ordinary instance method or accessor called card_number ?
It's truly not asking for anything fancy. This assignments requires not one jot of metaprogramming jujitsu.
Do you already have an account? Log in and claim this comment.
E-mail the ZIP in pkg/ to your section leader. Remember to include E168 in the subject, and submission:assignment3 in the body.
Should we do submission:assignment3 in the body or submission:assignment2 in the body since it is referenced as assignment 2 everywhere else?
Thanks!
Do you already have an account? Log in and claim this comment.
But we certainly won't refuse a submission that says submission:assignment3 !!!
Do you already have an account? Log in and claim this comment.
I'm sure I could write my own function to do this quickly, but in the spirit of code reuse...
Do you already have an account? Log in and claim this comment.
class Range
def include?(val)
if val.is_a? Array
# do your check
else
super(val)
end
end
end
Do you already have an account? Log in and claim this comment.
points = 82
grade = case points
when 90..100
'A'
when 80..89
'B'
.....
else
'E'
end
puts "Points: #{points}; Grade: #{grade}"
How can this be extended to take in an Array instead of a single FixNum ? I've tried a couple of things including === but can't get the syntax quite right. any hints would be much appreciated.
Do you already have an account? Log in and claim this comment.
Or: Is this point value within this Array?
Do you already have an account? Log in and claim this comment.
if (dealt_cards.length == 1)
@myHand.push(dealt_cards[0])
else
Similar logic works in card when trying to create a new card and parsing input. This code does not pass the unit test test_0100_hand_at_020. The array is initialized and passes the unit test before. The error I get is that <nil> not expected to be nil. Is there some more information regarding the splat operator in the pickaxe? I tried looking in there, but couldn;t find anything, maybe I misse it.
Thanks.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
So. Is this because my code is, ahem, un-optimized, or does everyone have the same execution time?
Also, I am used to stepping through a debugger to see where the clogs happen. Is there a recommended method of doing something similar in Ruby to see where my code could be improved?
EDIT: I see that test_0195_hand_strength_025, test_0193_hand_strength_023 take the longest. I put a "puts self" in the test code functions to see what was running at execution. So I took them out and ran them separately, they are all fine. The difference is I ran them without the "accept_and_check" function.
So....I wonder if accept_and_check is slowing thing down...
Removing "accept_and_check" from the two function reduced execution time for the entire script from over 60 sec to 23 sec.
Do you already have an account? Log in and claim this comment.
That said, I think you probably have something in accept_and_check that is slowing things down. These tests should run very fast. I'd send the code to your TA and see if they can spot something that might be causing your execution time to rise.
Do you already have an account? Log in and claim this comment.
I can only assume that learning the traditional Ruby will help me in this regard. Simply finding a function that works isn't good enough. Bad habits I have, I guess.
Rambling further, I think I'm just surprised that similar functionality in Ruby has such vast performance differences. I obviously don't know what I thought I knew about programming. I would think I would have had a more obvious confrontation with these issues in my past (I do C# and Java). I am now feeling humbled.
Do you already have an account? Log in and claim this comment.
Thanks!
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Maybe next time we'll blend profiling into the rake script.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
"You may also optionally add a method called strength_with_extras that reports, in addition to the number representing the type of hand, an Array for the high cards appropriate for the hand classification and an additional Array of kickers. This method would itself return an Array, the first element the value returned by strength, the other being the Array of kickers. (e.g., it might return [ 3, [ 12 ], [ 0, 1, 2 ] ], representing a Three of a Kind, a high card in the Three of a Kind (the Ace Spaces), followed by kickers of the 2, 3, and 4 of Spades. Another way to do it is to return instances of Card rather than the card numbers. It‘s up to you. "
Do you already have an account? Log in and claim this comment.
If the hand is tied, the extra cards are the "kickers" that decide the tie.
So say I have a pair of aces, and you have a pair of aces: What is the top card among the kickers (extra cards) that would decide which of us has won?
http://en.wikipedia.org/wiki/Kicker_(poker)
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
"gem install rubyzip"
found a copy of "zip.exe" In the folder of a utility called LogMeIn on my computer. I copied it to c:\windows\system32\
I can email anyone the zip.exe binary if they need it.
Rajat
Do you already have an account? Log in and claim this comment.
It may very well get returned if you send it to my gmail account . . . So try:
john at 7fff dot com
john at h3 dot com
jnorman at digitaladvisor dot com
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
The problem with the PKZIPC.exe in the code bundle is that it's not compatible with the Unix zip, so there is some code in the rake file that doesn't play nice with all versions of Windows.
So I'd like to try yours.
Do you already have an account? Log in and claim this comment.
or
http://www.hindoogle.com/Software/zip.zip
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Remember that any class (such as your implementation of Deck) can have an instance variable that can represent anything you like.
Just for example, you might have an instance variable that is an Array or a Hash or something else to represent the cards currently in the deck.
Then shuffle would (somehow) randomize that data structure.
Our reference implementation of Deck has about 12 lines of executable code (excluding "class ... end" "def cards_remaining ... end" -- and so fortth.
Don't overthink the problem.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
You can introduce all of the instance variables you want. Those are private to your implementation.
If you introduce an acessor (attr_accessor) then other classes can manipulate those items. Do you want that?
Do you already have an account? Log in and claim this comment.
For example, new in the Card class states:
If there are no args, or more than 1 arg, an ArgumentError is raised.
If there is one arg but it is not a Fixnum or a String, an ArgumentError is raised.
My classes are fully functional and pass all of the tests so do I need to implement other things on top of that such as my example above?
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
:)
Do you already have an account? Log in and claim this comment.
I always have 85 tests, but sometimes, I have 2722 assertions, other times 2720, sometimes 2718, and sometimes 2726.
Does that mean that some tests are not run. There is no indication of errors.
Thanks
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
'zip' is not recognized as an internal or external command,
operable program or batch file.
rm -f FIND_ZIP.zip
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require': no such file to load -- zip/zip (LoadError
)
from c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
from C:/harvard/CSCIE-168/assn2/bin/zip_in_ruby.rb:7
rm -f FIND_ZIP.zip
PKZIP(R) Version 2.50 FAST! Compression Utility for Windows 95/NT 4-15-1998
Copyright 1989-1998 PKWARE Inc. All Rights Reserved. Shareware Version
PKZIP Reg. U.S. Pat. and Tm. Off. Patent No. 5,051,745
Creating .ZIP: FIND_ZIP.zip
Adding File: demo.rb Deflating (50.9%), done.
Adding File: pkg/e168-assignment2-Manuel Ledesma-1.0.000/demo.rb Deflating
(50.9%), done.
rm -f FIND_ZIP.zip
Using ZIP command: "C:/harvard/CSCIE-168/assn2/bin/PKZIPC.exe" -add -dir
rake aborted!
Don't know how to build task 'README'
(See full trace by running task with --trace)
Do you already have an account? Log in and claim this comment.
(in C:/harvard/CSCIE-168/assn2)
zip -r FIND_ZIP.zip demo.rb
'zip' is not recognized as an internal or external command,
operable program or batch file.
rm -f FIND_ZIP.zip
ruby "C:/harvard/CSCIE-168/assn2/bin/zip_in_ruby.rb" -r FIND_ZIP.zip demo.rb
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require': no such file to load -- zip/zip (LoadError
)
from c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
from C:/harvard/CSCIE-168/assn2/bin/zip_in_ruby.rb:7
rm -f FIND_ZIP.zip
"C:/harvard/CSCIE-168/assn2/bin/PKZIPC.exe" -add -dir -r FIND_ZIP.zip demo.rb
PKZIP(R) Version 2.50 FAST! Compression Utility for Windows 95/NT 4-15-1998
Copyright 1989-1998 PKWARE Inc. All Rights Reserved. Shareware Version
PKZIP Reg. U.S. Pat. and Tm. Off. Patent No. 5,051,745
Creating .ZIP: FIND_ZIP.zip
Adding File: demo.rb Deflating (50.9%), done.
Adding File: pkg/e168-assignment2-Manuel Ledesma-1.0.000/demo.rb Deflating
(50.9%), done.
rm -f FIND_ZIP.zip
Using ZIP command: "C:/harvard/CSCIE-168/assn2/bin/PKZIPC.exe" -add -dir
** Invoke rdoc (first_time)
** Invoke docs/rdoc/index.html (first_time)
rake aborted!
Don't know how to build task 'README'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:1718:in `[]'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:590:in `invoke_prerequisites'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:589:in `each'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:589:in `invoke_prerequisites'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:581:in `invoke_with_call_chain'
c:/ruby/lib/ruby/1.8/monitor.rb:242:in `synchronize'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:575:in `invoke_with_call_chain'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:592:in `invoke_prerequisites'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:589:in `each'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:589:in `invoke_prerequisites'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:581:in `invoke_with_call_chain'
c:/ruby/lib/ruby/1.8/monitor.rb:242:in `synchronize'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:575:in `invoke_with_call_chain'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:568:in `invoke'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2031:in `invoke_task'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2009:in `top_level'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2009:in `each'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2009:in `top_level'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2048:in `standard_exception_handling'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2003:in `top_level'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:1982:in `run'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2048:in `standard_exception_handling'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:1979:in `run'
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/bin/rake:31
c:/ruby/bin/rake:19:in `load'
c:/ruby/bin/rake:19
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
rake aborted!
Command failed with status (1): [C:/Ruby/bin/ruby -w -Ilib/;test/ "C:/Ruby/...]
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:974:in `sh'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:987:in `call'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:987:in `sh'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:1084:in `sh'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:1019:in `ruby'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:1084:in `ruby'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake/testtask.rb:117:in `define'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:1102:in `verbose'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake/testtask.rb:102:in `define'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:621:in `call'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:621:in `execute'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:616:in `each'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:616:in `execute'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:582:in `invoke_with_call_c
hain'
C:/Ruby/lib/ruby/1.8/monitor.rb:242:in `synchronize'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:575:in `invoke_with_call_c
hain'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:568:in `invoke'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2031:in `invoke_task'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2009:in `top_level'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2009:in `each'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2009:in `top_level'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2048:in `standard_exceptio
n_handling'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2003:in `top_level'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:1982:in `run'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:2048:in `standard_exceptio
n_handling'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/lib/rake.rb:1979:in `run'
C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.2/bin/rake:31
C:/Ruby/bin/rake:19:in `load'
C:/Ruby/bin/rake:19
Can you provide some help on what this means?
Do you already have an account? Log in and claim this comment.
test_0120_hand_strength_010(HandTest)
[./test/tc_hand.rb:270:in `check_hand'
./test/tc_hand.rb:263:in `accept_and_check'
./test/tc_hand.rb:90:in `test_0120_hand_strength_010'
./test/tc_hand.rb:89:in `each'
./test/tc_hand.rb:89:in `test_0120_hand_strength_010']:
Expected S2, S2, S2, S2, S2 to be evaluated as a Royal Flush.
<9> expected but was
<5>.
According to wikipedia information this is not a Roya Flush, Roya Flush is T, J, Q, K, A
Do you already have an account? Log in and claim this comment.
accept_and_check([ suit + 'A', suit + 'K', suit + 'Q', suit + 'J', suit + 'T' ], 9)
So look at the element: suit + 'A'
In side the loop, suit is going to be 'H' or 'C' or 'D' or 'S'
So, the combination is going to be a two-letter sequence such as: 'HA' (ace of Hearts)
Go down to accept_and_check (near the bottom).
See how that two-letter sequence is used here:
def accept_and_check(abbrevs, strength, allow_ace=nil, dump=false)
cards = abbrevs.map { |a| Card.new(a) }
See Card.new(a)? What does your code do with Card.new('HA') ? It would seem that it's not working right.
THEREFORE, if your Card.initialize method is screwed up -- if it can't create a Card that represents an Ace of Hearts from the two character sequence 'HA' -- then there is going to be a problem.
In your case, it looks like your Card (no matter WHAT suit/rank is being handled) is always being created as a 2 of Spades.
Let me point out that the instructions strongly suggest that you start with the "spot" testing first -- this will verify some of the most crucial bits first. One of the earliest tests in tc_spot looks like this:
assert_equal 'DA', CARD.new(51).abbrev
assert_equal 51, CARD.new('DA').card_number
assert_equal 'Ace of Diamonds', CARD.new('DA').human_readable
That's checking to make sure that your code creates cards correctly.
I hope you read the instructions.
John
Do you already have an account? Log in and claim this comment.
Sorry for the trouble
Thanks for your quick response.
Do you already have an account? Log in and claim this comment.
Throw an exception if limit is reach and try to accept another card?
Push new card or cards to the hand and and slice out existing one?
Throw exception is passing cards are bigger than 5?
Do you already have an account? Log in and claim this comment.
In a real simulation, you could either throw an exception, or, possibly, write code to notify the other hands that one hand is illigitimately trying to accept a 6th card; then the other hands could complain and/or quit the game on the grounds that someone is cheating.
Do you already have an account? Log in and claim this comment.
In general, for this assignment, should we be limiting ourselves very strictly to the specification, or is it okay to have a little more error-checking than what's minimally required?
Do you already have an account? Log in and claim this comment.
Also, I am not sure that a hand should be responsible for such an exception. The reason is that if a 6th card is added to a hand, and that is not allowed, then, arguably, your deck is corrupted ('cos in the current model, the card is taken from the deck and THEN accepted into the hand -- there isn't a mechanism to force a card back into the deck). This suggests that if you did have a problem with a sixth card, it should be handled at a different level of abstraction. You could argue that it is the responsibility of the Dealer to not screw up a player's hand. OR, you might believe that the dealer should be able to do this, and the hand should be able to take advantage of such a bonus card . . .
Do you already have an account? Log in and claim this comment.
class TestHand < Test::Unit::TestCase
include CardTestUtils
def test_has_lowest_card?
h = Hand.new("some_player")
h.accept(shuffle(to_cards(%w{ sa sk s2 d2 da dk })))
assert(h.has_lowest_card?, "Recognize that hand contains the lowest card")
h = Hand.new("some_player")
h.accept(shuffle(to_cards(%w{ sa sk s3 d2 da dk })))
refute(h.has_lowest_card?, "Recognize that hand does not contain the lowest card")
end
end
assert() is fine but for refute() I get the following error:
test_has_lowest_card?(TestHand):
NoMethodError: undefined method `refute' for #<TestHand:0x44402b0>
lib/testpusoydos.rb:33:in `test_has_lowest_card?'
Am I doing something wrong?
Do you already have an account? Log in and claim this comment.
Here's the whole list: http://www.ruby-doc.org/stdlib/libdoc/test/unit...
Folks: Ana is writing tests because she's simulating a different game from poker.
For assignment 2, you should not need to write any of your own tests.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
I wrote a message on Thomas's "errata" page at pragprog.com asking that he flag new things a bit better.
Amy, Keith, Harlan - refute must be new?
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
I am not clear on when one should use symbol and when one should use constant.
Could you explain ?
Thanks
Do you already have an account? Log in and claim this comment.
Does that mean that we don't have to worry about rdoc - and just write document on places that might be unclear. Anything you have provided in your instruction rdoc, we don't have to repeat ?
Thanks
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
The point is this:
-- The "official" documentation, outlining how the public methods should work, has been defined through the requirements for the assignments. So, in effect, the rdoc is done.
HOWEVER, you definitely should note internals that need explanations. You would be very wise to help your grader understand where key comments are. It would be appropriate to say in the readme that you've done something brilliant in a certain section of the code (then put the comment in the code).
Truly, we will not generate rdoc for this project.
For later work, where it will be appropriate for you to write comments suitable for rdoc: Even then, you don't have to actually generate the rdoc. We will see the rdoc comments while looking at the code.
Upshot:
For Assignment 2:
1. If you do anything cool, add a comment.
2. Helpful: List such interesting bits in your readme.
3. And the readme in general. Here's what we say:
Before submitting, you will write a file called readme.txt for the root of the project. It must describe what you did, in particular how you tackled the hand evaluation methods in the Hand class. We have put a very short readme.txt in place to get you started. More on the readme.txt below.
Internal documentation and writeup (the readme.txt). Is the internal documentation concise but clarifying? Does the readme.txt explain to me, in sentences and paragraphs, how your code works?
NOTE: There is no need to write things like "The Card class represents a playing card." Please, do not state the obvious. If you feel that you need to address this briefly, you may, but do not repeat the assignment or the requirements for your implementation.
NOTE: There is no need to write RDoc (public comments before "class" and public methods) for the tested methods in Card, Deck, and Hand. Why? Because the documentation we hand out is what you must code to. If you ADD public methods, provide RDoc comments for them.
You must specifically address your strategy for evaluating hands. Not doing so will render the 15% portion of the grade devoted to documentation very close to 0.
You must discuss any additional files, classes, or methods that result in additional functionality or convenience for you as the implementer.
It is hard to imagine a readme.txt that is fewer than 350 words. Please make an ordinary text file. No Word, PDF, etc.
See below for a question regarding the readme.txt.
You may also optionally add a method called strength_with_extras that reports, in addition to the number representing the type of hand, an Array for the high cards appropriate for the hand classification and an additional Array of kickers. This method would itself return an Array, the first element the value returned by strength, the other being the Array of kickers. (e.g., it might return [ 3, [ 12 ], [ 0, 1, 2 ] ], representing a Three of a Kind, a high card in the Three of a Kind (the Ace Spaces), followed by kickers of the 2, 3, and 4 of Spades. Another way to do it is to return instances of Card rather than the card numbers. It‘s up to you.
If you attempt this, discuss your implementation thoroughly in your readme.txt.
What should the readme.txt look like?
Put your name, the course name, and the assignment number at the top of the readme.txt.
The audience of the readme.txt is yourself or another technical staff member such as yourself. The reader knows Ruby and Rails, but may not currently be coding in it. This reader will be responsible for maintaining your code in the future. The reader may be your technical manager. Therefore:
1. Your writeup must be clear.
2. Your writeup must explain where everything is. If you introduce new files, classes, or public methods, say where they are, and what they do, and why they‘re important. A good way convey this kind of information is in the form of a list.
3. If you do anything fancy, you have to explain yourself.
4. The fact that the audience is also yourself is important. Think of what you are doing as a letter to yourself, which you will read in a year long after you‘ve forgotten the code. You will kick yourself if you find your own writing unclear or confusing.
These are the criteria we will be using during grading!
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
So . . . your task is to figure out a way to permute the order of your internal representation of the deck so that the cards will come out in a different order.
One way to do it would be to pick two cards (at random); exchange them. Pick two cards (at random); exchange them. Etc.
You might be able to simulate an existing shuffle: http://www.youtube.com/watch?v=ch_SMNQ-awM
Do you already have an account? Log in and claim this comment.
It reads "Newcomers to Ruby commonly makes the mistake of setting instance variables inline in the class definition.....
The example is something like
class Test
@var = 99
def self.var
@var
end
So is @var not an instance variable. Earlier on in the chapter on classes /variables /attributes (chapter 4), we
have variables like @isbn, and that was an instance variable. It confuses me.
The other question I have is, how do you return the instance of itself (as in "this" in Java) in Ruby.
One of the questions seems to ask for it.
The "self" is not "this"
Thanks
Do you already have an account? Log in and claim this comment.
Always manipulate your instance variables (prefixed with @) inside of a method. It is inside of methods that instance variables are "scoped" to the instance.
When the @variable is outside of a method, it is a class instance variable (which is different from a class variable).
Incidentally, in the revised slides I provide an example like so:
class Player
# Next line: WRONG!!
# instance variables (@) go inside instance methods
@completed_games = 0
def initialize(first_name, number)
@first_name, @number = first_name, number
# Next line: RIGHT!!
@completed_games = 0
end
end
------
"self" means "the current object." So if you call a bare method, it will send a message to the current object. In most cases, when you are CALLING a method or need a reference to the current object, self will work like Java's this.
Do you already have an account? Log in and claim this comment.
(Not used to having class instance variable - so when people say instance variable, I automatically take it to mean the first kind).
What about for methods ? Are there also 3 types as well : instance method, and class method. Is there class instance method as well ?
class A
def methodB
...
end
The methodB is an instance method, I take an instance method to mean an object of type classA can receive the method.
class A
def self.methodB
...
end
We call it with A.methodB
w.r.t self-vs-this, I must have missed the discussion. Perhaps it is in the slides.
Thanks
Do you already have an account? Log in and claim this comment.
I will be talking self, class, and instance methods this evening.
Do you already have an account? Log in and claim this comment.
But, do we also have to define a "new" method as well. Lookint at rdoc generated, it says that we have to create a "new" method.
I am not clear on the differences between "new" and "initialize".
The other thing that I didn't understand is about self.methodA. I took it to mean that self.methodA makes methodA a class method.
So, why don't one has to say self.new ?
I guess chapter 24 (which is what we are supposed to read) is not very clear to me.
Do you already have an account? Log in and claim this comment.
You call .new on the CLASS (not on an object instance). In the typical case, you do not yourself write code for .new. Example:
Array.new
What Ruby does then is allocate memory for a new Array, and sets up the instance of the class. THEN it calls .initialize which you write. It passes the params you gave to .new right on to .iniitialize.
rdoc simply provides what you say about your implementation of initialize to its doc for new (which makes sense, because when when you want to create a new instance, you use .new, provide some params, and then those params are passed right on to initialize).
-----
As I say in my answer about "this" vs. "self" -- I said (please read it carefully), than when you are CALLING a method or need a reference to the current object, you can use self.
What you are talking about is using "self" in a method declaration. That will create a class method. I haven't discussed that yet, though I will, and you will probably not need to declare a class method in Assignment 2.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
A lot of times these things can be figured out if you think about how you would do it with a real deck of cards.
If I had a deck of 52 cards, and gave you one, how many are left?
Then if I gave you one, how many are left?
Finally, if I gave you all 52, how many are left? Can I give you any more?
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
In effect, a well-planned Deck class always knows what's in it.
In a more elaborate simulation, you could imagine a Hand class that would attempt to identify anomalies in the cards taken from the deck.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
I'm getting a goofy error I'm hoping you can help me with. It has to do with test_0195_hand_strength_025... This is a random test, so sometimes, it submits a straight flush. I return an 8 for straight flush, and it complains that it wanted a 5 (flush). I return true from Hand.can_handle_ace_low?... I'm looking for the place where you are checking for this flag in this test case, and I do not see it.
All else appears to be working.
Thanks,
Mike
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
I'll play around a bit with the hand compare thingy... That should be interesting.
Thanks!
Mike
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
It appears that it should return the Fixnum that would have been passed to Card#new to instantiate the card.
Which is correct? The specification or the tests?
Do you already have an account? Log in and claim this comment.
Note that whether or not it is the Fixnum passed in is not defined. For example, you might store the identity of the card internally as a combination of suit and rank, and compute card_number based on such internals.
Does that help?
Do you already have an account? Log in and claim this comment.
Looking further at the documentation (and my tests that are failing), it appears that even though the synopsis for Hand#accept is
"accept(*dealt_cards)", in fact what the method should be taking is either a single Card or a single Array, but not multiple Cards. E.g.
accept(c1)
or
accept( [c2, c3] )
but NOT
accept(c4, c5)
Is this correct?
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
a) the apparent ambiguity of the synopsis "accept(*dealt_cards)", and
b) demo.rb line 6, which is attempting to call Hand#accept with 5 arguments of type Card.
My implementation currently passes "rake spot" and "rake test", but fails to run demo.rb, because of this.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
The requirements and the tests say that hand#accept should accept a single card or an array into the hand.
Unfortunately, the reference implement will accept a single card, an array of cards, OR a list of more than one argument where each argument is interpreted as a card.
So . . . if you implemented it as required, and passed the tests, demo.rb should work fine if you just pass in an Array of the cards -- e.g., change from:
h.accept( Card.new('S3'), Card.new('D3'), Card.new('H3'), Card.new('D2'), Card.new('S2') )
to
h.accept( [ Card.new('S3'), Card.new('D3'), Card.new('H3'), Card.new('D2'), Card.new('S2') ])
John
Do you already have an account? Log in and claim this comment.
Can we limit ourselves to 5-card hands, here? Assume and/or enforce that a hand must have exactly 5 cards?
Or do we need to consider games like 7-card stud or Texas Hold-em, where we can choose 5 cards to score, out of a larger hand?
Do you already have an account? Log in and claim this comment.
Unless I'm mistaken, the links to Wikipedia are only for the 5 card game.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
The rdoc for Card is below. Note where I put ***. The idea here is that the an exception will be raised if the number of parameters is wrong. This is more about helping you discover raising exceptions than anything else.
---------- Card
Initializes a card.
A Fixnum argument constructs a card so that 0 creates the Two of Spades, 1 the Three of Spades,…, 12 the Ace of Spades, 13 the Two of Hearts, and so forth. For the sequence of Suits and Ranks, see constants.rb.
If there is one argument and it is a String, then it is first trimmed and uppercased. If the resultant size is 2, then an attempt is made to initialize the card so that the suit is the value of the first character, and the rank is the second character, according to the values of SUITS and RANKS in constants.rb. If the characters don‘t match the possible suits and ranks, an ArgumentError is raised.
If there are no args, or *** more than 1 arg, an ArgumentError is raised.
If there is one arg but it is not a Fixnum or a String, an ArgumentError is raised.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
>ruby demo.rb
Demonstration of instantiation of a hand, then checking how strong it is.
demo.rb:6: undefined method `accept' for #<Hand:0x2b1572c> (NoMethodError)