Tabela de Conteúdos
:: Topo :: doCoding :: Linguagens de Programação :: Ruby :: FORPC101 ::
Week-03
Aprendizagem
- '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 (”#{…}”).
- statement modifiers - possibilidade de alterar a execução de uma instrução com base no teste lógico.
- method_missing() - este método evita que a evocação de um método inexistente na classe despolete a excepção NoMethodError.
- nil - é um objecto, e pode-se evocar métodos de nil.
- Array - é uma classe “colecção” ou vector, que armazena qualquer tipo de Objecto.
- ARGV é um Array cujos items são todos os argumentos passados ao programa.
- methods() - mostra todos os métodos de uma classe.
- 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.