Ruby-Programmierung: Aufgaben
Zurück zum Inhaltsverzeichnis.
Dieses Kapitel soll dieses Buch mit Aufgaben zu verschiedenen Themen abschließen. Dabei können Sie versuchen die verschiedenen Aufgaben an jeder Stelle des Buches versuchen zu lösen, eventuell ist es dadurch jedoch schwerer oder unmöglich die Aufgabe zu lösen, da Ihnen bestimmte Mittel aus späteren Kapiteln fehlen. Das kann auch dazu führen, dass Sie eventuell die vorgestellte Lösung nicht nachvollziehen können.
Mindestens sollten Sie an dieser Stelle den Abschnitt Grundlagen durchgearbeitet haben, um die Aufgaben lösen zu können.
Die Aufgaben bestehen aus einem Thema und einer Aufgabenbeschreibung, sowie Gedanken zur Lösung des Problems. Wenn Sie eine Aufgabe bearbeiten sollten Sie das tun, ohne auf die hier vorgestellte Lösung zu schauen, um am meisten aus der Bearbeitung der Aufgabe zu lernen.
Passwortgenerator
BearbeitenDiese Aufgabe besteht darin ein Programm zu entwickeln, das zufällig generierte Passwörter ausgibt. Dabei könnte das Programm den folgenden Funktionsumfang haben:
- Variable Länge der Passwörter
- Auswahl legitimer Zeichen
- Speichern der letzten Einstellungen
- Erneutes Erzeugen von Standardeinstellungen
Musterlösung
#Encoding: utf-8
require "yaml"
require "set"
class Preferences < Hash
def initialize
super
self[:length] = 10
self[:chars] = ::Set.new
("a".."z").each { |c| self[:chars] << c }
("A".."Z").each { |c| self[:chars] << c }
"!\"§$%&/()=?*_:;{[]}\\+#-.,".split("").each { |c| self[:chars] << c }
end
end
class Password
def self.gen(pref)
pw = ""
pref[:length].times { pw << pref[:chars].to_a.shuffle[0] }
pw
end
end
if File.file? ".pref"
pref = YAML.load_file(".pref")
else
pref = Preferences.new
end
catch :exit do
input = ""
loop do
input = gets.chomp
value = input[/[^=]+$/]
case input
when /!e/
throw :exit
when /!n/
pref = Preferences.new
when /!a/
value.split("").each { |c| pref[:chars] << c }
when /!r/
value.split("").each { |c| pref[:chars].delete c }
when /!l/
pref[:length] = value.to_i
else
puts "Generated password: " + Password.gen(pref)
end
end
end
open(".pref","w") { |f| YAML.dump(pref,f) }
Primzahlprüfer
BearbeitenDas Programm soll bei Eingabe einer Zahl überprüfen, ob es sich um eine Primzahl handelt oder nicht. Es kann sowohl als Kommandozeilenapplikation, als auch als interaktive Applikation gestalltet werden.
Musterlösung
#Encoding: utf-8
require "prime"
class PrimeChecker
def self.run(argv)
if argv.empty?
interactive_prime_checker
else
prime_checker(argv.map(&:to_i))
end
end
def self.prime_checker(numbers)
numbers.each do |num|
puts "#{ num } #{ Prime.prime?(num) ? "is a prime." : "isn't a prime." }"
end
end
def self.interactive_prime_checker
puts "Please enter some numbers or nothing to exit."
loop do
input = gets.chomp
break if input.empty?
numbers = input.split(/\s+/).map(&:to_i)
prime_checker(numbers)
end
end
end
PrimeChecker::run(ARGV)
Konvertieren in das metrische System
BearbeitenIm amerikanischen Sprachraum wird häufig anstelle des metrischen das imperiale Einheitensystem verwendet, was bei Menschen zu Konfusionen führen kann, die die Einheiten nicht gewohnt sind. Die Aufgabe ist es also einen Konverter für imperiale Einheiten wie Zoll, Fuß, Gallonen und so weiter zu schreiben, der dann eine metrische Ausgabe vornimmt. Bedenken Sie, dass es viele solcher Einheiten gibt und das die Struktur ihres Program das Hinzufügen neuer Einheiten so leicht wie möglich machen sollte. Die Beispiellösung erlaubt das Aufrufen des Programms mittels ruby converter.rb 200lbs 6ft 3inch
.
Musterlösung
module Converter
def self.run(args)
puts convert(args)
end
def self.convert(args)
args.map { |arg| Unit.parse(arg).to_metric }
end
class Unit
def self.units
{
"lbs" => Pound,
"ft" => Feet,
"inch" => Inch
}
end
def self.parse(arg)
unit = arg[/\D+\Z/i]
value = arg[/\d+(\.\d+)?/].to_f
units.fetch(unit).new(value)
end
def initialize(value)
@value = value
end
def to_s
"#{ @value }#{ unit_string }"
end
end
class Kilogram < Unit
def to_metric
self
end
def unit_string
"kg"
end
end
class Pound < Unit
def to_metric
Kilogram.new(@value * 0.454)
end
def unit_string
"lbs"
end
end
class Meter < Unit
def to_metric
self
end
def unit_string
"m"
end
end
class Feet < Unit
def to_metric
Meter.new(@value * 0.3048)
end
def unit_string
"ft"
end
end
class Inch < Unit
def to_metric
Meter.new(@value * 0.0254)
end
def unit_string
"inch"
end
end
end
Converter::run(ARGV)