This 3-part homework gives some basic practice in Ruby as well as getting you accustomed to making testing a regular part of your workflow.
This assignment is set up for GitHub Classroom with automatic testing. When you submit your work, GitHub Actions will automatically run the tests and provide feedback.
- Accept the assignment from the provided GitHub Classroom link
- Clone your repository to your local machine
- Complete the assignment by implementing the required methods in
lib/ruby_intro.rb - Test your work locally using the commands below
- Push your changes to GitHub - tests will run automatically!
- Tests run automatically when you push to the
mainbranch - You can see test results in the "Actions" tab of your repository
- Each part of the assignment is tested separately
- All tests must pass for full credit
This assignment relies on you having some minimal background with single-user workflow in Github (clone, edit locally, commit locally, push to remote). If you haven't done it before, please search for/follow a beginner tutorial, and I and the TA are happy to explain it individually as well.
After completing this assignment, you will know how to:
- Write simple code that uses basic constructs in the Ruby language, including methods and arguments, conditionals, string and array manipulation, regular expressions, and basic object-oriented programming mechanisms
- Understand the Ruby project conventions for where code files and test files are located in a project's directory hierarchy
- Run individual tests or suites of tests using the RSpec unit testing tool
- Understand the basic syntax of RSpec unit tests
You may find the Ruby documentation at ruby-doc.org helpful to have on hand.
The repo for this assignment follows a fairly standard Ruby convention for codebases: the code
files are stored in lib/ and the test files are stored in spec/.
(We use the RSpec unit-testing framework; if we were using Ruby's default
framework, known as Test::Unit, the test files would be under
test/.)
We've placed "starter code" in lib/ruby_intro.rb; when you're all done, you
can submit this single file to the autograder.
However, you can test each of the 3 parts separately. The files
spec/part[123]_spec.rb contain RSpec tests for each of the three
parts. For example, to test your answers to Part 1, say rspec spec/part1_spec.rb. rspec with no arguments runs the tests in all
the files spec/*_spec.rb.
- The line numbers in the RSpec error report will
give you guidance as to which tests failed. (You can check the RSpec
documentation to see how the
.rspecfile can be used to customize the output format.)
| Local computer setup |
|---|
| Ensure that Ruby 4.0.2 is installed. |
To ensure you have the rspec gem installed you need bundler and can then run bundle install like so:
$ gem install bundler
$ cd hw2
$ bundleWhen the above completes successfully you'll have RSpec installed and can run rspec from the command line to test your code.
Ruby 4.0 Notes
This assignment uses Ruby 4.0, which introduces several important changes from Ruby 3.x:
- Frozen string literals by default. All string literals (e.g.
"hello") are now immutable. Code likegreeting = "Hello, "; greeting << namewill raise aFrozenError. Use string interpolation ("Hello, #{name}") or concatenation ("Hello, " + name) instead, which create new strings rather than mutating a literal.- Bundler 4 ships with Ruby 4.0 and enforces HTTPS gem sources. The project Gemfile is already configured correctly for this.
Check the Ruby 4.x documentation on Array,
Hash and Enumerable as they could help tremendously with these
exercises. Various Ruby cheatsheets are also helpful as a quick reference! Although Ruby supports looping constructs like 'for' and 'while', consider using block syntax with each for a more idiomatic use of Ruby. :-)
-
Define a method
sum(array)that takes an array of integers as an argument and returns the sum of its elements. For an empty array it should return zero. Run associated tests via:$ rspec -e '#sum ' spec/part1_spec.rb(Make sure you are in the correct directory:cd hw2and rspec is installed) -
Define a method
max_2_sum(array)which takes an array of integers as an argument and returns the sum of its two largest elements. For an empty array it should return zero. For an array with just one element, it should return that element (Consider if the two largest elements are the same value as well). Run associated tests via:$ rspec -e '#max_2_sum' spec/part1_spec.rb -
Define a method
sum_to_n?(array, n)that takes an array of integers and an additional integer, n, as arguments and returns true if any two elements in the array of integers sum to n.sum_to_n?([], n)should return false for any value of n, by definition. Run associated tests via:$ rspec -e '#sum_to_n' spec/part1_spec.rb
You can check your progress on all of the above by running $ rspec spec/part1_spec.rb.
Check the documentation on String and Regexp as they could help tremendously with these exercises. For future reference as well, check out https://rubular.com/ for regex related queries. :-)
-
Define a method
hello(name)that takes a string representing a name and returns the string "Hello, " concatenated with the name. Run associated tests via:$ rspec -e '#hello' spec/part2_spec.rb(Make sure you are in the correct directory:cd hw2) -
Define a method
starts_with_consonant?(s)that takes a string and returns true if it starts with a consonant and false otherwise. (For our purposes, a consonant is any English letter other than A, E, I, O, U.) Make sure it works for both upper and lower case and for non-letters. Run associated tests via:$ rspec -e '#starts_with_consonant?' spec/part2_spec.rb -
Define a method
binary_multiple_of_4?(s)that takes a string and returns true if the string represents a binary number that is a multiple of 4, such as '1000'. Make sure it returns false if the string is not a valid binary number. Run associated tests via:$ rspec -e '#binary_multiple_of_4?' spec/part2_spec.rb
You can check your progress on all of the above by running $ rspec spec/part2_spec.rb.
Define a class BookInStock which represents a book with an ISBN number, isbn, and price of the book as a floating-point number, price, as attributes. Run associated tests via: $ rspec -e 'getters and setters' spec/part3_spec.rb (Make sure you are in the correct directory: cd hw2)
The constructor should accept the ISBN number (a string, since in real life ISBN numbers can begin with zero and can include hyphens) as the first argument and price as second argument, and should raise ArgumentError (one of Ruby's built-in exception types) if the ISBN number is the empty string or if the price is less than or equal to zero. Include the proper getters and setters for these attributes. Run associated tests via: $ rspec -e 'constructor' spec/part3_spec.rb
Include a method price_as_string that returns the price of the book formatted with a leading dollar sign and two decimal places, that is, a price of 20 should format as $20.00 and a price of 33.8 should format as $33.80. Check out formatted string methods in Ruby. Run associated tests via: $ rspec -e '#price_as_string' spec/part3_spec.rb
You can check your progress on all of the above by running rspec spec/part3_spec.rb.