Zadania z podstaw języka ruby i programowania OO
Poniższe zadania mają na celu samodzielne przećwiczenie różnych zagadnień omawianych na zajęciach.
pokaż / ukryj wszystkie odpowiedzi
- Proszę napisać program, który będzie prosił użytkownika o podanie dwóch liczb, po czym zwróci w wyniku ich sumę, np:
>Proszę podać pierwszą liczbę: >5 >Proszę podać drugą liczbę: >3 >Wynik: 8
To proste zadanie ma na celu przypomnienie, w jaki sposób wczytujemy dane ze standardowego wejścia oraz jak konwertujemy napisy do liczb. Przykładowe rozwiązanie pokazuje, jak korzystamy z interpolowanych stringów do wypisania wyniku:puts "Podaj pierwsza liczbe:" num1=gets.to_i puts "Podaj druga liczbe:" num2=gets.to_i puts "Wynik: #{num1+num2}" - Proszę zmodyfikować powyższy program w taki sposób, aby po zwróceniu wyniku ponownie prosił użytkownika o podanie kolejnych liczb.
W tym rozwiązaniu korzystamy z pętli while do ciągłego czytania ze standardowego wyjścia. Można rozwiązać to zadanie również stosując rekurencyjne wywołania funkcji.
num1=num2=nil puts "Podaj pierwsza liczbe:" while num=gets.to_i if num1.nil? num1=num num2=nil puts "Podaj druga liczbe:" elsif num2.nil? num2=num puts "Wynik: #{num1+num2}" num1=nil puts "Podaj pierwsza liczbe:" end end - Proszę napisać program obliczający wartość ułamka i wypisujący ją z dokładnością do n liczb po przecinku. Program pobiera od użytkownika licznik, mianownik i liczbę n.
- Wskazówka: printf
Formatujemy wynik korzystając z funkcji printf, która działa podobnie jak w języku C. Przy okazji warto zwrócić uwagę na to, że któryś z argumentów dzielenia musi być liczba zmiennoprzecinkową.puts "Podaj licznik:" licznik=gets.to_f puts "Podaj mianownik:" mianownik=gets.to_f puts "Podaj ilosc miejsc po przecinku:" n=gets.to_i wynik = licznik/mianownik printf("Wynik: %.#{n}f",wynik) - Proszę napisać program wczytujący wprowadzoną z klawiatury serię liczb zakończoną -1 i wypisujący n największych.
- Wskazówka: metoda sort tablicy. Dodatkowo proszę rozważyć wariant, w którym przewidujemy wczytywanie wielu liczb i nie chcemy ich wszystkich przechowywać w pamięci, jedynie w każdym momencie n największych
Pierwsza wersja zakłada, że zapamiętujemy wszystkie liczby aż do zakończenia wpisywania i dopiero wtedy je sortujemy i prezentujemy n największych. Do przechowywania liczb używamy tablicy, a do jej sortowania używamy metody sort.W nieco trudniejszym wariancie, gdy nie chcemy przechowywać wszystkich liczb a jedynie w każdym momencie n największych, korzystamy z funkcji min dla zwrócenia najmniejszej wartości przechowywanej w tablicy, funkcji index do odnalezienia pozycji danej wartości oraz ponownie funkcji sort. Działanie programu jest obrazowane przez wypisywanie aktualnej zawartości tablicy, co można wygodnie zrobić stosując funkcję inspect (jest to funkcja, która umożliwia czytelne wypisanie zawartości dowolnego obiektu, stosuje się ją na ogół przy debugowaniu kodu). Dodatkowo w tym wariancie nie dopuszczamy umieszczania duplikatów w tablicy.nums = [] n=5 min=0 while (num=gets.to_i) != -1 nums<< num end nums.sort!{|a,b| b <=> a} puts nums[0..n-1]nums = [] n=5 min=0 while (num=gets.to_i) != -1 next if num < min || nums.index(num) if nums.size > n puts "replacing #{min} with #{num}" nums[nums.index(min)]=num else nums<< num end min = nums.min puts nums.inspect end nums.sort!{|a,b| b <=> a} puts nums - Proszę napisać program wczytujący z pliku serię liczb i wypisujący średnią arytmetyczną z tych liczb.
sum=0.0 count=0 while (num=gets.to_i) != -1 sum+=num count+=1 end puts "Srednia: #{sum/count}" - Proszę napisać program, który wczyta plik tekstowy (jego nazwa może być podana jako parametr wywołania lub zapisana w pliku) po czym wypisze na standardowe wyjście listę wyrazów i częstości ich wystąpień w podanym tekście, posortowaną malejąco pod względem częstości, np:
(dla ułatwienia w pierwszej wersji można pominąć specjalne traktowanie interpunkcji)"Ho! Ho! Ho! Merry Christmas!" Ho : 3 Christmas : 1 Merry : 1
W tym zadaniu skorzystamy z tablicy haszującej do przechowywania statystyk wystąpień słów. Dzięki podaniu wartości 0 w konstruktorze każdy nowy wpis w haszu ma wartość inicjalizowaną na 0, co jest wygodne przy inkrementowaniu ilości wystapień słowa. Korzystamy z iteratora each wczytując kolejne linie pliku. Za pomocą predefiniowaniej klasy znaków \W rozdzielamy linie tekstu po wszystkich znakach, które nie występują w słowach. Na końcu dokonujemy sortowania tablicy słów, uzyskanej w wyniku pobrania wszystkich kluczy tablicy haszującej, gdzie kryterium sortowania stanowi wartość tablicy haszującej dla danego słowa.stats = Hash.new(0) File.open("martin_fowler_ruby.txt").each do |line| words = line.split(/\W+/) words.each do |word| stats[word]+=1 end end words = stats.keys ordered_words = words.sort{|w1,w2| stats[w2] <=> stats[w1]} ordered_words.each{|w| puts "#{w}: #{stats[w]}"} - Proszę napisać klasę Square, o jednym atrybucie o nazwie "a" podawanym w parametrze konstruktora i oznaczającym długość boku kwadratu. Niech klasa implementuje metodę "area" zwracającą pole kwadratu. Np:
s1 = Square.new(5) s1.area > 25
class Square def initialize(a) @a= a end def area @a**2 end end s = Square.new(5) puts s.area - Proszę napisać klasę Guitar o jednej metodzie o nazwie "play", zwracającej napis "plonk plonk", oraz klasę Drum, która również ma metodę "play", zwracającą napis "bang bang".
g = Guitar.new g.play > "plonk plonk" d = Drum.new d.play > "bang bang"
Mozna zaimplementować te klasy na różne sposoby, przykładowo;class Guitar def play "plonk plonk" end end class Drum def play "bang bang" end end g = Guitar.new puts "guitar: "+g.play d = Drum.new puts "drums: "+d.play - Proszę do powyższych dwóch klas dodać nadklasę o nazwie Instrument, która implementuje metodę "play" w taki sposób, że możliwe jest usunięcie z Guitar i Drum definicji tej metody przy utrzymaniu dawnego zachowania.
- Wskazówka: proszę postarać się, aby rozbudowa orkiestry o kolejne instrumenty nie wymagała zmiany w klasie Instrument.
Ponieważ nie chcemy obciążać klasy nadrzędnej wiedzą o dźwiękach wydawanych przez poszczególne instrumenty, musimy zaproponować sposób przechowywania informacji o dźwięku w klasach dziedziczących. W tym rozwiązaniu skorzystamy ze stałych definiowanych w poszczególnych klasach od osiągnięcia tego celu (warto sprawdzić, dlaczego nie nadaje sie do tego celu zmienna klasowa).class Instrument SOUND="undefined sound" def play self.class::SOUND end end class Guitar < Instrument SOUND="plonk plonk" end class Drum < Instrument SOUND="bang bang" end g = Guitar.new puts "guitar: "+g.play d = Drum.new puts "drums: "+d.playAlternatywne rozwiązanie autorstwa Olka Pohla
class Instrument def self.get_sound @sound end def play self.class.get_sound end end class Guitar < Instrument @sound = "plonk plonk" end class Drum < Instrument @sound = "bang bang" end - Proszę napisać klasy Bicycle, Car i Vehicle w taki sposób, aby unikając duplikacji kodu można było uzyskać taki efekt:
b = Bicycle.new(6) b.info > "I am a Bicycle, I have 2 wheels and 6 gears" c = Car.new(5,4) c.info > "I am a Car, I have 4 wheels and 5 gears and room for 4 passengers"
- Wskazówka: w pierwszej wersji pojawiła się pomyłka w treści zadania, większość samochodów wciąż ma 5 biegów i tyle również ma mieć obiekt c, zgodnie z parametrem podanym w konstruktorze.
Podobnie jak w poprzednim przypadku, nie chcemy aby klasa Vehicle była obciążona szczegółową wiedzą o poszczególnych podklasach. Chcemy do niej wyciągnąć tylko części wspólne roweru i samochodu. W realiach tego zadania można uznać, że to co łączy rowery i samochody to posiadanie określonej ilości kół i biegów. Niech więc klasa Vehicle przyjmuje te parametry w konstruktorze. Klasy dziedziczące będą mogły skorzystać wtedy z konstruktora nadklasy, za pomocą metody super. Również za pomocą metody super samochód będzie mógł wykorzystać część wspólną komunikatu wyświetlanego po wywołaniu info i dokleić do niego specyficzna dla siebie informację o ilości pasażerów.class Vehicle def initialize(gears,wheels) @gears=gears @wheels=wheels end def info "I am a #{self.class}, I have #{@wheels} wheels and #{@gears} gears" end end class Bicycle < Vehicle def initialize(gears) super(gears,2) end end class Car < Vehicle def initialize(gears,passengers) super(gears,4) @passengers=passengers end def info super+" and room for #{@passengers} people" end end b = Bicycle.new(6) puts b.info c = Car.new(5,4) puts c.info