Category:I704 Ruby
About this course
This course teaches the Ruby programming language. By the end of the course you'll hopefully have a good understanding of:
- the basics of Ruby,
- tools commonly used in the Ruby ecosystem,
- written a few small Ruby applications,
- know about unit testing,
- know how to use third-party code (Ruby gems),
- know how to write web applications using Ruby.
Lecture Recordings
You can find recordings of the lectures here:
https://echo360.e-ope.ee/ess/portal/section/b02ab032-010b-4111-a53d-2f5a47db1fdd
About yourself
To help me make this course interesting for you and meet your expectations, please fill out this survey if you haven't done so already:
Reference material
Here you find a list of useful links to things that have been mentioned or discussed during the lectures:
Editors/IDEs
Grading
Students develop several small projects during the lectures and independent study. At the end of the course students pick one of their projects and are assigned a feature request to implement in their project and a set of questions about the code in their project.
Points are awarded for the following:
- 50 points for a working implementation of the feature request
- 40 points for an implementation of the feature request that works only for expected inputs
- 20 points for a running unfinished implementation (i.e. feature not fully implemented, but the program still runs)
- 10 points for an unfinished implementation (i.e. feature not fully implement and the program does not run).
- 20 points for providing automated tests for their implementation
- 10 points for proper use of version control
- 10 points for adhering to common Ruby coding standards
- 20 points for answering 80% of the questions correctly
The student needs at least 60 points in order to pass the course.
2017-02-02: Lecture and Lab
Analyzing bank statements
Given the following contents of a file called input.csv
transaction_id,date,amount,credit 1,2017-02-02 12:40,1.30,debit 2,2017-02-02 12:55,2.50,debit 3,2017-02-02 13:00,1.00,credit
Goal: find the amount of money left on your bank account.
Steps:
- read the data line by line
- analyze each line to find out whether it's credit or debit and the amount of money
- add all the debit transaction amounts (money lost)
- add all the credit transaction amounts (money gained)
- Output money gained - money lost
Our code so far:
File.open('input.csv', 'r') do |the_file|
lines = the_file.readlines.map do |line|
line.chomp.split(',')
end
lines = lines[1..-1]
debit_total = ''
lines.each do |line|
debit_total = debit_total + line[2]
end
puts debit_total
end
2017-02-09 Lecture
require 'minitest'
require 'minitest/autorun'
class BankAccount
class Error < StandardError; end
class BalanceNegative < Error; end
def initialize
@balance = 0
end
def deposit!(amount)
increse_balance!(amount)
self
end
def withdraw!(amount)
if enough_money?(amount)
reduce_balance!(amount)
else
raise StandardError, 'Not enough money!'
end
self
end
def balance
@balance
end
private
def enough_money?(amount)
balance >= amount
end
def reduce_balance!(amount)
@balance = @balance - amount
end
def increse_balance!(amount)
@balance = @balance + amount
end
end
class BankAccountTest < Minitest::Test
def setup
@account = BankAccount.new
end
def test_if_decreses_the_balance_when_withdrawing_money
@account.deposit!(101).withdraw!(50)
assert_equal 51, @account.balance
end
def test_if_increses_the_balance_when_depositing_money
@account.deposit!(196583)
assert_equal 196583, @account.balance
end
def test_if_account_does_not_go_in_to_negative
assert_raises BankAccount::BalanceNegative do
@account.deposit!(1).withdraw!(20)
end
end
def test_it_raises_bank_account_error_when_withdrawing_too_much_money
@account.deposit!(1).withdraw!(20)
rescue BankAccount::Error => err
assert true, 'everything is ok'
end
end
2017-02-16 Lecture and Lab: using modules and bundler
Modules in Ruby
- Modules are a collection of methods that can be included in another class
- By including the module in a class, objects belonging to that class get access to the methods defined in the module
- If multiple included modules define the same method, the method from the module that was included last counts
Example
module ModuleExample
def foo
'foo'
end
end
# Including modules binds their methods to the class instances
# Extending modules binds their methods to the class itself
class Person
include ModuleExample
end
class Book
extend ModuleExample
end
Person.foo # => NoMethodError: undefined method `foo' for Person:Class
Person.new.foo # => 'foo'
Book.foo # => 'foo'
Book.new.foo # => NoMethodError: undefined method `foo'
Structuring a project with bundler
- bundler is a Ruby program for managing dependencies in your ruby project
- bundler also helps you with creating a template for a project
- redistributable projects/libraries are called "gems" in ruby
- You can start your own project by running
bundle gem YOUR_PROJECT_NAME_HERE
. ReplaceYOUR_PROJECT_NAME_HERE
with the lower-cased name of your project.
Example structure of a project, as generated by bundler
$ tree . ├── bin │ ├── console │ └── setup ├── Gemfile ├── Gemfile.lock ├── I704.gemspec ├── lib │ ├── I704 │ │ ├── bank_account.rb │ │ └── version.rb │ └── I704.rb ├── LICENSE.txt ├── Rakefile ├── README.md └── test ├── I704 │ └── bank_account_test.rb ├── I704_test.rb └── test_helper.rb 5 directories, 14 files
Rule of thumb: put your code into the lib/YOUR_PROJECT_NAME
directory, one file per class (like bank_account.rb
in the example above)
2017-03-02 Lecture & Lab
Word count example
text = "Burning Rangers is a 1998 3D action video game developed by Sonic Team and published by Sega for the Sega Saturn. The game is set in a futuristic society threatened by frequent fires. Players control one of an elite group of firefighters, the Burning Rangers, who extinguish the fires and rescue civilians from burning buildings. Most of the tasks the players complete are centred around collecting energy crystals used to transport civilians to safety. Development began shortly after the release of Christmas Nights in November 1996, when Yuji Naka started working on a game focused on saving people rather than killing them. Sonic Team chose the themes of firefighting and heroism. Burning Rangers received mostly positive reviews, especially for the game's soundtrack and audio. Responses to the graphics were mixed; while some critics asserted that the game had the best visuals on the Saturn, others faulted its poor collision detection and occasional glitching. The game was among the final five Saturn titles released in America."
words = text.split(' ')
words_without_punctuation = words.map do |word|
word.sub(/[.,;?!:]/, '').downcase
end
word_count = words_without_punctuation.reduce({}) do |result, word|
if result.key?(word)
result[word] = result[word] + 1
# also possible: result[word] += 1
else
result[word] = 1
end
result
end
puts word_count
Reference material: making HTTP requests in Ruby
- Require the "net/http" library in your program
- Use that library to make HTTP requests for fetching the HTML code behind a website
- See https://ruby-doc.org/stdlib-2.3.0/libdoc/net/http/rdoc/Net/HTTP.html for more examples of how to use this library
require 'net/http'
google_html = Net::HTTP.get(URI('http://google.com'))
# "<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\n<TITLE>302 Moved</TITLE></HEAD><BODY>\n<H1>302 Moved</H1>\nThe document has moved\n<A HREF=\"http://www.google.ee/?gfe_rd=cr&ei=o6KlWKCGA9Oq8wfoq5OQAg\">here</A>.\r\n</BODY></HTML>\r\n"
# Now you can work with the HTML returned by the server
Reference material: parsing HTML using Nokogiri
Once you have received some HTML from a web server, you most likely want to analyze it. Use the library nokogiri for this. You can find installation instructions and tutorials here: http://www.nokogiri.org/tutorials/
Reference material: map and reduce
# map: takes a list and a block
# returns: a list, where each element of the original list has been
# passed to block
#
# reduce: takes list, an initial value and a block
# returns: block applied to initial value and each element of the list
numbers = [1, 2, 3]
sum = numbers.reduce(0) do |current_sum, number|
current_sum + number
end
puts "Sum: #{sum}"
####
numbers = [1, 2, 3]
sum = 0
numbers.each do |number|
sum = sum + number
end
This category currently contains no pages or media.