:: Topo :: doCoding :: Linguagens de Programação :: Ruby :: FORPC101 ::

Week-03

Aprendizagem

  1. 'string' vs “string” - a primeira forma requer menos processamento e é mais simples, enquanto que a segunda forma efectua também substituição (“\”) e interpolação (”#{…}”).
  2. statement modifiers - possibilidade de alterar a execução de uma instrução com base no teste lógico.
  3. method_missing() - este método evita que a evocação de um método inexistente na classe despolete a excepção NoMethodError.
  4. nil - é um objecto, e pode-se evocar métodos de nil.
  5. Array - é uma classe “colecção” ou vector, que armazena qualquer tipo de Objecto.
  6. ARGV é um Array cujos items são todos os argumentos passados ao programa.
  7. methods() - mostra todos os métodos de uma classe.
  8. instance_methods() - mostra todos os métodos das instâncias da classe.

Exercícios

Exercício 1

Como converter de String para Array?

exercise-01.rb

=begin
Write a program that processes a string s = "Welcome to the forum.\nHere you can learn Ruby.\nAlong with other members.\n"
a line at a time, using all that we have learned so far. The expected output is:
  >ruby tmp.rb
  Line 1: Welcome to the forum.
  Line 2: Here you can learn Ruby.
  Line 3: Along with other members.
  >Exit code: 0
=end
 
s = "Welcome to the forum.\nHere you can learn Ruby.\nAlong with other members.\n"
 
# Iterating through String with method each().
line_number = 0
s.each do | line |
  line_number += 1
  # puts "Line #{line_number}: " + line
  puts 'Line ' + line_number.to_s + ': ' + line
end
 
# Converting from String to Array,
# and then iterated with method each().
line_number = 0
a = s.split("\n")
a.each do | line |
  line_number += 1
  # puts "Line #{line_number}: " + line
  puts 'Line ' + line_number.to_s + ': ' + line
end
 
# From Michael Uplawski:
s.split("\n").each_with_index do | line, line_number |
  puts "Line %d: %s" % [line_number += 1, line]
end
 
# Improved from Michael Uplawski:
s.each_with_index do | line, line_number |
  puts 'Line ' + (line_number + 1).to_s + ': ' + line
end

Exercício 2

exercise-02.rb

=begin
Run the following two programs and try and understand the difference in the outputs of the two programs.
=end
 
def mtdarry
  10.times do | num |
    puts "\tOutput Number: #{num}"
  end
end
 
puts 'Calling Method, only:'
mtdarry
 
puts '-' * 40
 
puts 'Calling Method, with puts:'
puts mtdarry

Qual a diferença entre mtdarry e puts mtdarry?

A primeira forma imprime os número de 0 até 9 (iterar 10 vezes, a começar do zero) enquanto a segunda forma imprime o mesmo seguido do resultado da última instrução do método mtdarry(): puts num, quando num tem o valor seguinte ao fim da iteração, neste caso 10.
Michael Uplawski, após ler a documentação do método times() apresenta um código de demonstração: o método retorna o número inicial de iterações a realizar.

Exercício 3

Como calcular se um ano é ou não bissexto?

Usei o código do tutorial Simple Constructs, sem esquecer a conversão de String para Integer.

exercise-03.rb

=begin
Write a Ruby program (p016leapyear.rb) that asks for a year
and then displays to the user whether the year entered by him/her is a leap year or not.
=end
 
def is_leap_year?(year)
  check = case
    when year % 400 == 0 : true
    when year % 100 == 0 : false
    when year % 4   == 0 : true
  else
    false
  end
end
 
print 'Input Year to Check: '
STDOUT.flush
year = gets.chomp
 
if is_leap_year?(year.to_i) then
  puts 'True. ' + year + ' is a Leap Year.'
else
  puts 'False. ' + year + ' isn\'t a Leap Year.'
end

Exercício 4

exercise-04.rb

=begin
Write a method leap_year.
Accept a year value from the user, check whether it's a leap year
and then display the number of minutes in that year - program p017leapyearmtd.rb.
=end
 
def is_leap_year?(year)
  check = case
    when year % 400 == 0 : true
    when year % 100 == 0 : false
    when year % 4   == 0 : true
  else
    false
  end
end
 
print "Input Year to Check: "
STDOUT.flush
year = gets.chomp
 
# Using if
days = 365
days += 1 if is_leap_year?(year.to_i)
puts year + " has #{days * 24 * 60} minutes."
 
# Using unless
days = 366
days -= 1 unless is_leap_year?(year.to_i)
puts year + " has #{days * 24 * 60} minutes."

Exercício 5

exercise-05.rb

=begin
Given a string, let us say that we want to reverse the word order (rather than character order).
You can use String.split, which gives you an array of words.
The Array class has a reverse method; so you can reverse the array and join to make a new string.
Write this program.
=end
 
def reversed(s, separator = ' ')
  s.split(separator).reverse.join(separator)
end
 
s = 'One Two Three Four Five'
 
# Step-by-Step
a = s.split(' ')
r = a.reverse
puts r.join(' ')
 
# One-Liner
puts s.split(' ').reverse.join(' ')
 
# method, with default separator
puts reversed(s)
 
csv = 'Field1,Field2,Field3,Field4,Field5'
puts reversed(csv, ',')

Exercício 6

exercise-06.rb

=begin
Write a Ruby program (p020arraysum.rb) that,
when given an array as collection = [1, 2, 3, 4, 5]
it calculates the sum of its elements.
=end
 
a = [1, 2, 3, 4, 5]
sum = 0
a.each do | item |
  sum += item
end
puts "Sum = #{sum}"
 
# Using inject() - http://rubylearning.org/class/mod/resource/view.php?id=183
sum = a.inject(0) { | accumulator, element | accumulator + element }
puts "Sum = #{sum}"
 
 
 
# Evaluating why this "swapped-form" of inject works:
 
[1, 2, 3, 4, 5].inject do | element, sum |
  puts "#{element} and #{sum}"
  element += sum
end
 
[1, 2, 3, 4, 5].inject(0) do | element, sum |
  puts "#{element} and #{sum}"
  element += sum
end

Exercício 7

exercise-07.rb

=begin
=begin
Write a Ruby program (p021oddeven.rb) that,
when given an array as collection = [12, 23, 456, 123, 4579]
it displays for each number, whether it is odd or even.
=end
 
a = [12, 23, 456, 123, 4579]
a.each do | item |
  if item % 2 != 0 then
    puts "#{item} is Odd"
  else
    puts "#{item} is Even"
  end
end
 
# By Fran Souto
def is_odd?(number)
  (number % 2 != 0) ? true : false
end
 
a.each { | element | puts is_odd?(element) ? "#{element} is Odd" : "#{element} is Even" }

WeekendProblem

WeekendProblem.rb

=begin
I have a database of all the FORPC101 course participants.
I want to know the number of participants who have not attempted Quiz 1 (is it so scary smile ?).
A student writes a nifty Ruby program and creates an array of 0's and 1's.
0's indicate that the participant has not attempted the Quiz and the 1's have attempted.
 
You have to use this array quiz: quiz = [0,0,0,1,0,0,1,1,0,1]
and write another nifty program to solve my problem namely,
display the number of participants who have not attempted Quiz 1.
 
The output of your program should be as follow:
The number of participants who did not attempt Quiz 1 are x out of y participants.
=end
 
quiz = [0,0,0,1,0,0,1,1,0,1]
total_participants = quiz.length
 
participants_with_quiz_attempt = quiz.inject(0) do | accumulator, element |
  accumulator + element
end
puts 'The number of participants who did not attempt Quiz 1 are ' +
      (total_participants - participants_with_quiz_attempt).to_s  +
      ' out of ' + total_participants.to_s + ' participants.'
 
# From Alyssa Siegel
participants_without_quiz_attempt = quiz.inject(0) do | accumulator, element |
  element == 0 ? accumulator += 1 : accumulator
end
puts 'The number of participants who did not attempt Quiz 1 are ' +
      participants_without_quiz_attempt.to_s  +
      ' out of ' + total_participants.to_s + ' participants.'
 
# From Brad Coish
puts "The number of participants who did not "    +
     "attempt Quiz 1 are #{(quiz-[1]).size} out " +
     "of #{quiz.size} participants"
 
# From Ron Given
puts "The number of participants who did not attempt Quiz 1 are" +
      " #{(quiz.find_all { | x | x == 0 }).size} out of "        +
      "#{quiz.size} participants."
 
# From Satoshi Asakawa
puts "The number of participants who did not attempt Quiz 1 are " +
     "#{quiz.join.count('0')} out of #{quiz.size} participants."

SundayBrainTeaser

SundayBrainTeaser.rb

=begin
A student has written the following program.
The above program displays the value 10000200001.
Is the program in-efficient?
If yes, analyze the program and make it more efficient.
Remember that the variables i, x and y need to be used.
=end
 
# Student's Code
i = x = y = 0
while (i < 1000000)
 i += 1
 x += 1
 y += 1
 tmp = x * y
 puts tmp if (i > 100000 && i < 100002)
end
 
=begin
Decoding Line by Line:
i, x and y start at 0
i, x and y end at 1000000
tmp is used at each iteration, although it used only once
That "once" is when i (and x and y) are 100001
 
There are only 2 "arguments" to this code:
  100001 and 1000000
=end
 
# Method Version
def sunday_brain_teaser(val1, val2, a = 0, b = 0, c = 0)
  a = b = c = val1
  puts b * c if (a == val1)
  a = b = c = val2
end
 
i = x = y = 0
i = x = y = sunday_brain_teaser(100001, 1000000, i, x, y)
 
# Optimized Version
i = x = y = 100001
puts x * y if (i == 100001)
i = x = y = 1000000

Questionário

Referências

Considerações

Pontos Altos

Esta secção regista o que considero serem os pontos altos da linguagem Ruby quando comparada com outras linguagens que conheço.

Pontos Baixos

Esta secção regista o que considero serem os pontos baixos da linguagem Ruby quando comparada com outras linguagens que conheço.

 
docoding/languages/ruby/forpc101/week-03.txt · Modificado em: 2008/09/25 10:09 por straider     Voltar ao topo