Update of exercises
parent
25d5ac7ffd
commit
fe2c1c6eb6
|
@ -1,11 +1,22 @@
|
||||||
# Aufgabenblock 1: Ruby Grundlagen
|
# Splat
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Die Aufgaben in dieser Einheit beziehen sich auf die Vorlesungsfolien __Ruby Grundlagen__.
|
Sie haben ein Array mit folgendem Aufbau:
|
||||||
|
|
||||||
Folgende Themen werden durch die Aufgaben abgedeckt:
|
* Element 0: Breite
|
||||||
|
* Element 1: Länge
|
||||||
|
* Element 2: Name der Sehenswürdigkeit
|
||||||
|
* folgende Elemente: Weitere Informationen
|
||||||
|
|
||||||
* Kontrollstrukturen
|
Beispiel:
|
||||||
* Schleifen
|
|
||||||
* Ausdrücke
|
```ruby
|
||||||
|
ort = [ 49.468408, 8.482504, \
|
||||||
|
'Hochschule Mannheim', \
|
||||||
|
'Gebäude A', \
|
||||||
|
'Fakultät für Informatik', \
|
||||||
|
'Gute Ausbildung' ]
|
||||||
|
```
|
||||||
|
|
||||||
|
Lesen Sie die Elemente in _einem Schritt_ und in _einer einzigen Zuweisung_ in die Variablen `laenge`, `breite`, `name` und `attribute` ein. Verwenden Sie nicht die Indizes, sondern den Splat-Operator (`*`).
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Lösung: Splat
|
||||||
|
|
||||||
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
|
||||||
|
```ruby
|
||||||
|
ort = [ 49.468408, 8.482504, \
|
||||||
|
'Hochschule Mannheim', \
|
||||||
|
'Gebäude A', \
|
||||||
|
'Fakultät für Informatik', \
|
||||||
|
'Gute Ausbildung' ]
|
||||||
|
|
||||||
|
laenge, breite, name, *attribute = ort
|
||||||
|
```
|
|
@ -1,22 +1,13 @@
|
||||||
# Splat
|
# Symbole
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Sie haben ein Array mit folgendem Aufbau:
|
Verwenden Sie Symbole, um an eine Funktion `ansage` die Ursache für die Verspätung eines Zuges zu übergeben. Mögliche Ursachen sind
|
||||||
|
|
||||||
* Element 0: Breite
|
* Signalstörung
|
||||||
* Element 1: Länge
|
* Personen im Gleis
|
||||||
* Element 2: Name der Sehenswürdigkeit
|
* Störungen im Betriebsablauf
|
||||||
* folgende Elemente: Weitere Informationen
|
|
||||||
|
|
||||||
Beispiel:
|
Die Funktion soll dann den Text "Wir bitten um Entschuldigung, wegen ... verzögert sich unserer Weiterfahrt", wobei die Punkte durch die Ursache ersetzt werden sollen.
|
||||||
|
|
||||||
```ruby
|
Rufen Sie die Funktion dann mit den verschiedenen Ursachen testweise auf.
|
||||||
ort = [ 49.468408, 8.482504, \
|
|
||||||
'Hochschule Mannheim', \
|
|
||||||
'Gebäude A', \
|
|
||||||
'Fakultät für Informatik', \
|
|
||||||
'Gute Ausbildung' ]
|
|
||||||
```
|
|
||||||
|
|
||||||
Lesen Sie die Elemente in _einem Schritt_ und in _einer einzigen Zuweisung_ in die Variablen `laenge`, `breite`, `name` und `attribute` ein. Verwenden Sie nicht die Indizes, sondern den Splat-Operator (`*`).
|
|
|
@ -1,12 +1,26 @@
|
||||||
# Lösung: Splat
|
# Lösung: Symbole
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
|
||||||
```ruby
|
```ruby
|
||||||
ort = [ 49.468408, 8.482504, \
|
def ansage(ursache)
|
||||||
'Hochschule Mannheim', \
|
|
||||||
'Gebäude A', \
|
|
||||||
'Fakultät für Informatik', \
|
|
||||||
'Gute Ausbildung' ]
|
|
||||||
|
|
||||||
laenge, breite, name, *attribute = ort
|
text = case ursache
|
||||||
|
when :signal
|
||||||
|
"Signalstörung"
|
||||||
|
when :personen
|
||||||
|
"Personen im Gleis"
|
||||||
|
when :betrieb
|
||||||
|
"Störungen im Betriebsablauf"
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Wir bitten um Entschuldigung, wegen #{text} verzögert sich unsere Weiterfahrt" unless text.nil?
|
||||||
|
puts "Wir bitten um Entschuldigung. Unsere Weiterfahrt verzögert sich." if text.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
ansage(:signal)
|
||||||
|
ansage(:personen)
|
||||||
|
ansage(:betrieb)
|
||||||
|
ansage(:gibts_nicht) # keine Ausgabe
|
||||||
```
|
```
|
|
@ -1,13 +1,20 @@
|
||||||
# Symbole
|
# Zugriffsmethoden
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Verwenden Sie Symbole, um an eine Funktion `ansage` die Ursache für die Verspätung eines Zuges zu übergeben. Mögliche Ursachen sind
|
Gegeben sei die folgende Ruby-Klasse:
|
||||||
|
|
||||||
* Signalstörung
|
```ruby
|
||||||
* Personen im Gleis
|
class Professor
|
||||||
* Störungen im Betriebsablauf
|
def initialize(name, fach)
|
||||||
|
@name = name
|
||||||
|
@fach = fach
|
||||||
|
end
|
||||||
|
|
||||||
Die Funktion soll dann den Text "Wir bitten um Entschuldigung, wegen ... verzögert sich unserer Weiterfahrt", wobei die Punkte durch die Ursache ersetzt werden sollen.
|
def to_s
|
||||||
|
"Prof. #{@name} lehrt #{@fach}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
Rufen Sie die Funktion dann mit den verschiedenen Ursachen testweise auf.
|
Ändern Sie die Klasse so ab, dass man die das Attribut `@name` lesen und das Attribut `@fach` lesen und schreiben kann. Verwenden Sie die `attr_`-Methoden, um eine möglichst kompakte Lösung zu bekommen.
|
|
@ -1,26 +1,24 @@
|
||||||
# Lösung: Symbole
|
# Lösung: Zugriffsmethoden
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
|
||||||
```ruby
|
```ruby
|
||||||
def ansage(ursache)
|
class Professor
|
||||||
|
attr_reader :name
|
||||||
|
attr_accessor :fach
|
||||||
|
|
||||||
text = case ursache
|
def initialize(name, fach)
|
||||||
when :signal
|
@name = name
|
||||||
"Signalstörung"
|
@fach = fach
|
||||||
when :personen
|
end
|
||||||
"Personen im Gleis"
|
|
||||||
when :betrieb
|
|
||||||
"Störungen im Betriebsablauf"
|
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
|
|
||||||
puts "Wir bitten um Entschuldigung, wegen #{text} verzögert sich unsere Weiterfahrt" unless text.nil?
|
def to_s
|
||||||
puts "Wir bitten um Entschuldigung. Unsere Weiterfahrt verzögert sich." if text.nil?
|
"Prof. #{@name} lehrt #{fach}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
ansage(:signal)
|
p = Professor.new('Smits', 'PR3')
|
||||||
ansage(:personen)
|
puts p.name
|
||||||
ansage(:betrieb)
|
puts p.fach
|
||||||
ansage(:gibts_nicht) # keine Ausgabe
|
p.fach = 'WIA'
|
||||||
|
puts p.fach
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,20 +1,13 @@
|
||||||
# Zugriffsmethoden
|
# Klasse deklarieren
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Gegeben sei die folgende Ruby-Klasse:
|
Schreiben Sie eine Ruby-Klasse `Ticket`, die Tickets für Fußballspiele repräsentieren kann. Die Klasse soll das Spiel und eine übergreifende Seriennummer speichern.
|
||||||
|
|
||||||
```ruby
|
Versehen Sie die Klasse mit einem Konstruktor, um Instanzen anlegen zu können. Der Konstruktor soll nur das Spiel bekommen, die Seriennummer verwaltet die Klasse selbst und zählt sie für jedes Ticket hoch.
|
||||||
class Professor
|
|
||||||
def initialize(name, fach)
|
|
||||||
@name = name
|
|
||||||
@fach = fach
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
Überschreiben Sie die `to_s`-Methode so, dass man Tickets einfach ausgeben kann.
|
||||||
"Prof. #{@name} lehrt #{@fach}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
Ändern Sie die Klasse so ab, dass man die das Attribut `@name` lesen und das Attribut `@fach` lesen und schreiben kann. Verwenden Sie die `attr_`-Methoden, um eine möglichst kompakte Lösung zu bekommen.
|
Sehen Sie eine _statische_ Methode `verkauft` vor, um die aktuell verkaufte Anzahl von Tickets (höchste Seriennummer) auszulesen.
|
||||||
|
|
||||||
|
Testen Sie Ihre Klasse, indem Sie Objekte anlegen und ausgeben.
|
|
@ -1,24 +1,31 @@
|
||||||
# Lösung: Zugriffsmethoden
|
# Lösung: Klasse deklarieren
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
```ruby
|
class Ticket
|
||||||
class Professor
|
|
||||||
attr_reader :name
|
|
||||||
attr_accessor :fach
|
|
||||||
|
|
||||||
def initialize(name, fach)
|
attr_reader :spiel
|
||||||
@name = name
|
|
||||||
@fach = fach
|
@@seriennummer = 1
|
||||||
|
|
||||||
|
def initialize(spiel)
|
||||||
|
@spiel = spiel
|
||||||
|
@seriennummer = @@seriennummer
|
||||||
|
@@seriennummer += 1
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
"Prof. #{@name} lehrt #{fach}"
|
"#{@spiel} [#{@seriennummer}]"
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.verkauft
|
||||||
|
@@seriennummer
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
p = Professor.new('Smits', 'PR3')
|
t1 = Ticket.new('Dortmund-Schalke')
|
||||||
puts p.name
|
t2 = Ticket.new('Hoffenheim-Stuttgart')
|
||||||
puts p.fach
|
|
||||||
p.fach = 'WIA'
|
puts t1
|
||||||
puts p.fach
|
puts t2
|
||||||
|
puts Ticket::verkauft
|
||||||
```
|
```
|
|
@ -1,13 +1,5 @@
|
||||||
# Klasse deklarieren
|
# Default Parameter
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Ruby-Klasse `Ticket`, die Tickets für Fußballspiele repräsentieren kann. Die Klasse soll das Spiel und eine übergreifende Seriennummer speichern.
|
Schreiben Sie eine Methode `produkt`, der man 2, 3, oder 4 Zahlen übergeben kann. Die Methode berechnet dann das Produkt und gibt es zurück. Verwenden Sie _Default Parameter_ um diese Methode zu realisieren.
|
||||||
|
|
||||||
Versehen Sie die Klasse mit einem Konstruktor, um Instanzen anlegen zu können. Der Konstruktor soll nur das Spiel bekommen, die Seriennummer verwaltet die Klasse selbst und zählt sie für jedes Ticket hoch.
|
|
||||||
|
|
||||||
Überschreiben Sie die `to_s`-Methode so, dass man Tickets einfach ausgeben kann.
|
|
||||||
|
|
||||||
Sehen Sie eine _statische_ Methode `verkauft` vor, um die aktuell verkaufte Anzahl von Tickets (höchste Seriennummer) auszulesen.
|
|
||||||
|
|
||||||
Testen Sie Ihre Klasse, indem Sie Objekte anlegen und ausgeben.
|
|
|
@ -1,31 +1,11 @@
|
||||||
# Lösung: Klasse deklarieren
|
# Lösung: Default Parameter
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
class Ticket
|
def produkt(a, b, c = 1, d = 1)
|
||||||
|
a * b * c * d
|
||||||
attr_reader :spiel
|
|
||||||
|
|
||||||
@@seriennummer = 1
|
|
||||||
|
|
||||||
def initialize(spiel)
|
|
||||||
@spiel = spiel
|
|
||||||
@seriennummer = @@seriennummer
|
|
||||||
@@seriennummer += 1
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
"#{@spiel} [#{@seriennummer}]"
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.verkauft
|
|
||||||
@@seriennummer
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
t1 = Ticket.new('Dortmund-Schalke')
|
puts produkt(5, 7)
|
||||||
t2 = Ticket.new('Hoffenheim-Stuttgart')
|
puts produkt(5, 7, 8)
|
||||||
|
puts produkt(5, 7, 8, 3)
|
||||||
puts t1
|
|
||||||
puts t2
|
|
||||||
puts Ticket::verkauft
|
|
||||||
```
|
```
|
|
@ -1,5 +1,7 @@
|
||||||
# Default Parameter
|
# Vererbung
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Methode `produkt`, der man 2, 3, oder 4 Zahlen übergeben kann. Die Methode berechnet dann das Produkt und gibt es zurück. Verwenden Sie _Default Parameter_ um diese Methode zu realisieren.
|
Schreiben Sie eine Klasse `Mensch`, die den Namen und das Alter eines Menschen speichert. Leiten Sie davon die Klasse `Student` ab, die zusätzlich noch die Matrikelnummer enthält. Sorgen Sie dafür, dass die Objekte bei der Erzeugung korrekt initialisiert werden.
|
||||||
|
|
||||||
|
Überschreiben Sie in beiden Klassen sinnvoll die `to_s`-Methode.
|
|
@ -1,11 +1,30 @@
|
||||||
# Lösung: Default Parameter
|
# Lösung: Vererbung
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
def produkt(a, b, c = 1, d = 1)
|
class Mensch
|
||||||
a * b * c * d
|
attr_reader :name, :alte
|
||||||
|
|
||||||
|
def initialize(name, alter)
|
||||||
|
@name, @alter = name, Integer(alter)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"#{@name}, Alter: #{@alter}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
puts produkt(5, 7)
|
class Student < Mensch
|
||||||
puts produkt(5, 7, 8)
|
attr_reader :matrikel_nr
|
||||||
puts produkt(5, 7, 8, 3)
|
|
||||||
|
def initialize(name, alter, matrikel_nr)
|
||||||
|
super(name, alter)
|
||||||
|
@matrikel_nr = matrikel_nr
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
super + ", Matrikel-Nr.: #{@matrikel_nr}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
s = Student.new('Emil Meier', 22, '1822233')
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# Vererbung
|
# Keyword-Parameter
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Klasse `Mensch`, die den Namen und das Alter eines Menschen speichert. Leiten Sie davon die Klasse `Student` ab, die zusätzlich noch die Matrikelnummer enthält. Sorgen Sie dafür, dass die Objekte bei der Erzeugung korrekt initialisiert werden.
|
Schreiben Sie eine Methode `greet`, der man Name und Vorname übergeben kann und die den Aufrufer dann mit "Hello" und dem Vornamen, gefolgt vom Nachnamen begrüßt. Die Reihenfolge der Parameter `vorname` und `nachname` sollen beliebig sein. Verwenden Sie deswegen Schlüsselwort-Parameter.
|
||||||
|
|
||||||
Überschreiben Sie in beiden Klassen sinnvoll die `to_s`-Methode.
|
|
|
@ -1,30 +1,10 @@
|
||||||
# Lösung: Vererbung
|
# Lösung: Keyword-Parameter
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
class Mensch
|
def greet(vorname:, nachname:)
|
||||||
attr_reader :name, :alte
|
puts "Hello #{vorname} #{nachname}"
|
||||||
|
|
||||||
def initialize(name, alter)
|
|
||||||
@name, @alter = name, Integer(alter)
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
"#{@name}, Alter: #{@alter}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Student < Mensch
|
greet(vorname: 'Barbara', nachname: 'Liskov')
|
||||||
attr_reader :matrikel_nr
|
greet(nachname: 'Liskov', vorname: 'Barbara')
|
||||||
|
|
||||||
def initialize(name, alter, matrikel_nr)
|
|
||||||
super(name, alter)
|
|
||||||
@matrikel_nr = matrikel_nr
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
super + ", Matrikel-Nr.: #{@matrikel_nr}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
s = Student.new('Emil Meier', 22, '1822233')
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Keyword-Parameter
|
# Mixin benutzen
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Methode `greet`, der man Name und Vorname übergeben kann und die den Aufrufer dann mit "Hello" und dem Vornamen, gefolgt vom Nachnamen begrüßt. Die Reihenfolge der Parameter `vorname` und `nachname` sollen beliebig sein. Verwenden Sie deswegen Schlüsselwort-Parameter.
|
Schreiben Sie eine Klasse `Squares`, die das Mixin `Enumerable` einbindet und Quadratzahlen beginnend bei 1 bis zu einer im Konstruktor definierten Obergrenze `max` liefert.
|
|
@ -1,10 +1,21 @@
|
||||||
# Lösung: Keyword-Parameter
|
# Lösung: Mixin benutzen
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
def greet(vorname:, nachname:)
|
class Squares
|
||||||
puts "Hello #{vorname} #{nachname}"
|
include Enumerable
|
||||||
|
|
||||||
|
def initialize(max)
|
||||||
|
@max = max
|
||||||
|
end
|
||||||
|
|
||||||
|
def each
|
||||||
|
for i in 1..@max
|
||||||
|
yield i ** 2
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
greet(vorname: 'Barbara', nachname: 'Liskov')
|
s = Squares.new(20)
|
||||||
greet(nachname: 'Liskov', vorname: 'Barbara')
|
s.each { |e| puts e }
|
||||||
|
s.first
|
||||||
```
|
```
|
|
@ -1,5 +1,7 @@
|
||||||
# Mixin benutzen
|
# Modul schreiben
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Klasse `Squares`, die das Mixin `Enumerable` einbindet und Quadratzahlen beginnend bei 1 bis zu einer im Konstruktor definierten Obergrenze `max` liefert.
|
Erstellen Sie ein Modul `Chemie`, das die _Avogadro-Konstante_ (6,02214179 × 10^23) `N_a` und das Molvolumen (22,413996 l/mol) `M_v` enthält. Außerdem soll es eine Methode `volume_o2` enthalten, die für eine gegebene Masse (`m_O`) Sauerstoff das Volumen berechnet. Die Formel hierzu ist `m_O / 32 * M_v`.
|
||||||
|
|
||||||
|
Testen Sie das Modul mit eigenen Daten.
|
|
@ -1,21 +1,15 @@
|
||||||
# Lösung: Mixin benutzen
|
# Lösung: Modul schreiben
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
class Squares
|
module Chemie
|
||||||
include Enumerable
|
N_a = 6.02214179E23
|
||||||
|
M_v = 22.413996
|
||||||
|
|
||||||
def initialize(max)
|
def Chemie.volume_o2(m_O)
|
||||||
@max = max
|
m_O / 32 * M_v
|
||||||
end
|
|
||||||
|
|
||||||
def each
|
|
||||||
for i in 1..@max
|
|
||||||
yield i ** 2
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
s = Squares.new(20)
|
puts Chemie::N_a
|
||||||
s.each { |e| puts e }
|
puts Chemie::volume_o2(10.0)
|
||||||
s.first
|
|
||||||
```
|
```
|
|
@ -1,7 +1,11 @@
|
||||||
# Modul schreiben
|
# Monkey Patch
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Erstellen Sie ein Modul `Chemie`, das die _Avogadro-Konstante_ (6,02214179 × 10^23) `N_a` und das Molvolumen (22,413996 l/mol) `M_v` enthält. Außerdem soll es eine Methode `volume_o2` enthalten, die für eine gegebene Masse (`m_O`) Sauerstoff das Volumen berechnet. Die Formel hierzu ist `m_O / 32 * M_v`.
|
Schreiben Sie einen Monkey Patch, der die Klasse `String` um die Methode `to_leet` erweitert. Diese Methode gibt den Inhalt des Strings zurück, macht aber in der Rückgabe vorher die folgenden Ersetzungen:
|
||||||
|
|
||||||
Testen Sie das Modul mit eigenen Daten.
|
* `a` -> `4`
|
||||||
|
* `e` -> `3`
|
||||||
|
* `i` -> `1`
|
||||||
|
* `o` -> `O`
|
||||||
|
* `t` -> `7`
|
|
@ -1,15 +1,11 @@
|
||||||
# Lösung: Modul schreiben
|
# Lösung: Monkey Patch
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
module Chemie
|
class String
|
||||||
N_a = 6.02214179E23
|
def to_leet
|
||||||
M_v = 22.413996
|
self.tr('aeiou', '43107')
|
||||||
|
|
||||||
def Chemie.volume_o2(m_O)
|
|
||||||
m_O / 32 * M_v
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
puts Chemie::N_a
|
print "hello leet".to_leet # => h3ll0 l337
|
||||||
puts Chemie::volume_o2(10.0)
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
# Monkey Patch
|
# Geschachtelte Methoden
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie einen Monkey Patch, der die Klasse `String` um die Methode `to_leet` erweitert. Diese Methode gibt den Inhalt des Strings zurück, macht aber in der Rückgabe vorher die folgenden Ersetzungen:
|
Schreiben Sie eine Klasse `Bomb`. Diese soll eine statische Methode `activate` haben. Erst nach dem Aufruf dieser Methode soll es möglich sein, auf Objekten von `Bomb` die Methode `explode` aufzurufen.
|
||||||
|
|
||||||
* `a` -> `4`
|
|
||||||
* `e` -> `3`
|
|
||||||
* `i` -> `1`
|
|
||||||
* `o` -> `O`
|
|
||||||
* `t` -> `7`
|
|
|
@ -1,11 +1,19 @@
|
||||||
# Lösung: Monkey Patch
|
# Lösung: Geschachtelte Methoden
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
class String
|
class Bomb
|
||||||
def to_leet
|
def self.activate
|
||||||
self.tr('aeiou', '43107')
|
def explode
|
||||||
|
puts "Booooommmmm"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
print "hello leet".to_leet # => h3ll0 l337
|
b1 = Bomb.new
|
||||||
|
b2 = Bomb.new
|
||||||
|
b1.explode # Fehler
|
||||||
|
|
||||||
|
Bomb::activate
|
||||||
|
b1.explode
|
||||||
|
b2.explode
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Geschachtelte Methoden
|
# Vararg-Methoden
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Klasse `Bomb`. Diese soll eine statische Methode `activate` haben. Erst nach dem Aufruf dieser Methode soll es möglich sein, auf Objekten von `Bomb` die Methode `explode` aufzurufen.
|
Schreiben Sie eine Ruby-Methode `produkt`, die eine beliebige Anzahl von Werten nimmt, miteinander multipliziert und das Ergebnis zurück gibt. Rufen Sie Ihre Methode danach auf.
|
|
@ -1,19 +1,9 @@
|
||||||
# Lösung: Geschachtelte Methoden
|
# Lösung: Vararg-Methoden
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
class Bomb
|
def produkt(*p)
|
||||||
def self.activate
|
p.reduce { |s, e| s *= e }
|
||||||
def explode
|
|
||||||
puts "Booooommmmm"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
b1 = Bomb.new
|
puts produkt(5, 7, 8, 1)
|
||||||
b2 = Bomb.new
|
|
||||||
b1.explode # Fehler
|
|
||||||
|
|
||||||
Bomb::activate
|
|
||||||
b1.explode
|
|
||||||
b2.explode
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
# Aufgabenblock 2: Ruby Klassen
|
# Arrays
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Die Aufgaben in dieser Einheit beziehen sich auf die Vorlesungsfolien __Klassen, Module, Mixins__.
|
Simulieren Sie ein Kartendeck mit Hilfe von Arrays. Jede Karte wird durch ein Ruby-Symbol repräsentiert das aus zwei Zeichen besteht. Das erste Zeichen repräsentiert die Farbe (P, X, H, K), das zweite den Wert (7, 8, 9, 0, B, D, K, A).
|
||||||
|
|
||||||
Folgende Themen werden durch die Aufgaben abgedeckt:
|
* Erzeugen Sie einen vollständigen Kartenstapel mit 32 Karten.
|
||||||
|
* Mischen Sie die Karten.
|
||||||
* Klassen
|
* Nehmen Sie 5 Karten von oben und 5 Karten von unten ab und legen Sie sie in einen neuen Stapel
|
||||||
* Variablen
|
* Mischen Sie die abgenommenen Karten und legen Sie diese wieder auf den Stapel
|
||||||
* Methoden
|
|
||||||
* Vererbung
|
|
||||||
* Modules
|
|
||||||
* Mixins
|
|
||||||
* Duck-Typing
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Lösung: Arrays
|
||||||
|
|
||||||
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
|
stapel = []
|
||||||
|
|
||||||
|
for farbe in %w{P X H K}
|
||||||
|
for wert in %w{7 8 9 0 B D K A}
|
||||||
|
stapel << (farbe + wert).to_sym
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Mischen
|
||||||
|
stapel.shuffle!
|
||||||
|
|
||||||
|
# Karten abnehmen
|
||||||
|
neu = stapel[0..4]
|
||||||
|
neu << stapel[-5..-1]
|
||||||
|
stapel -= neu
|
||||||
|
|
||||||
|
# Karten mischen
|
||||||
|
neu.shuffle!
|
||||||
|
|
||||||
|
# Karten wieder auf den Stapel legen
|
||||||
|
stapel << neu
|
||||||
|
|
||||||
|
puts neu
|
||||||
|
puts stapel
|
||||||
|
```
|
|
@ -1,5 +1,14 @@
|
||||||
# Vararg-Methoden
|
# Callback mit Block
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Ruby-Methode `produkt`, die eine beliebige Anzahl von Werten nimmt, miteinander multipliziert und das Ergebnis zurück gibt. Rufen Sie Ihre Methode danach auf.
|
Schreiben Sie eine Funktion `rechner`, der man einen Block übergeben kann. `rechner` übergibt dem Block zwei Zahlenwerte und erwartet eine Zahl zurück. Das Ergebnis wird verdoppelt und von `rechner` zurück gegeben.
|
||||||
|
|
||||||
|
Beispiel:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
puts rechner(5, 4) { |a, b| a + b }
|
||||||
|
# -> 18
|
||||||
|
puts rechner(5, 4) { |a, b| a - b }
|
||||||
|
# -> 2
|
||||||
|
```
|
|
@ -1,9 +1,11 @@
|
||||||
# Lösung: Vararg-Methoden
|
# Lösung: Callback mit Block
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
def produkt(*p)
|
def rechner(a, b)
|
||||||
p.reduce { |s, e| s *= e }
|
ergebnis = yield a, b
|
||||||
|
ergebnis * 2
|
||||||
end
|
end
|
||||||
|
|
||||||
puts produkt(5, 7, 8, 1)
|
puts rechner(5, 4) { |a, b| a + b }
|
||||||
|
puts rechner(5, 4) { |a, b| a - b }
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
# Arrays
|
# Callback mit Proc
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Simulieren Sie ein Kartendeck mit Hilfe von Arrays. Jede Karte wird durch ein Ruby-Symbol repräsentiert das aus zwei Zeichen besteht. Das erste Zeichen repräsentiert die Farbe (P, X, H, K), das zweite den Wert (7, 8, 9, 0, B, D, K, A).
|
Schreiben Sie eine Funktion `rechner`, der man einen Block, ein Lambda oder ein Proc-Objekt übergeben kann. `rechner` übergibt dem Block/Proc/Lambda zwei Zahlenwerte und erwartet eine Zahl zurück. Das Ergebnis wird verdoppelt und von `rechner` zurück gegeben.
|
||||||
|
|
||||||
* Erzeugen Sie einen vollständigen Kartenstapel mit 32 Karten.
|
Beispiel:
|
||||||
* Mischen Sie die Karten.
|
|
||||||
* Nehmen Sie 5 Karten von oben und 5 Karten von unten ab und legen Sie sie in einen neuen Stapel
|
```ruby
|
||||||
* Mischen Sie die abgenommenen Karten und legen Sie diese wieder auf den Stapel
|
lam = ->(a, b) { a + b }
|
||||||
|
puts rechner(5, 4, lam) # -> 18
|
||||||
|
```
|
|
@ -1,28 +1,12 @@
|
||||||
# Lösung: Arrays
|
# Lösung: Callback mit Proc
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
stapel = []
|
def rechner(a, b, lam = nil, &block)
|
||||||
|
lam ||= block
|
||||||
for farbe in %w{P X H K}
|
ergebnis = lam.call(a, b)
|
||||||
for wert in %w{7 8 9 0 B D K A}
|
ergebnis * 2
|
||||||
stapel << (farbe + wert).to_sym
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Mischen
|
lam = ->(a, b) { a + b }
|
||||||
stapel.shuffle!
|
puts rechner(5, 4, lam) # -> 18
|
||||||
|
|
||||||
# Karten abnehmen
|
|
||||||
neu = stapel[0..4]
|
|
||||||
neu << stapel[-5..-1]
|
|
||||||
stapel -= neu
|
|
||||||
|
|
||||||
# Karten mischen
|
|
||||||
neu.shuffle!
|
|
||||||
|
|
||||||
# Karten wieder auf den Stapel legen
|
|
||||||
stapel << neu
|
|
||||||
|
|
||||||
puts neu
|
|
||||||
puts stapel
|
|
||||||
```
|
```
|
|
@ -1,14 +1,12 @@
|
||||||
# Callback mit Block
|
# Closure
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Funktion `rechner`, der man einen Block übergeben kann. `rechner` übergibt dem Block zwei Zahlenwerte und erwartet eine Zahl zurück. Das Ergebnis wird verdoppelt und von `rechner` zurück gegeben.
|
Schreiben Sie eine Ruby-Funktion `create_counter`, die ein Proc-Object zurück gibt. Das Proc-Objekt soll bei jedem Aufruf eine aufsteigende Zahl zurückgeben.
|
||||||
|
|
||||||
Beispiel:
|
Beispiel:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
puts rechner(5, 4) { |a, b| a + b }
|
p = create_counter
|
||||||
# -> 18
|
puts p.call # -> 1
|
||||||
puts rechner(5, 4) { |a, b| a - b }
|
puts p.call # -> 2
|
||||||
# -> 2
|
|
||||||
```
|
```
|
|
@ -1,11 +1,12 @@
|
||||||
# Lösung: Callback mit Block
|
# Lösung: Closure
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
def rechner(a, b)
|
def create_counter
|
||||||
ergebnis = yield a, b
|
n = 0 # closure
|
||||||
ergebnis * 2
|
Proc.new { n += 1 }
|
||||||
end
|
end
|
||||||
|
|
||||||
puts rechner(5, 4) { |a, b| a + b }
|
p = create_counter
|
||||||
puts rechner(5, 4) { |a, b| a - b }
|
puts p.call # -> 1
|
||||||
|
puts p.call # -> 2
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
# Callback mit Proc
|
# Hashes und Blöcke
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Funktion `rechner`, der man einen Block, ein Lambda oder ein Proc-Objekt übergeben kann. `rechner` übergibt dem Block/Proc/Lambda zwei Zahlenwerte und erwartet eine Zahl zurück. Das Ergebnis wird verdoppelt und von `rechner` zurück gegeben.
|
Realisieren Sie einen einfachen _Cache_ mit Hilfe von _Hashes_. Schreiben Sie hierzu eine Klasse `Cache`.
|
||||||
|
|
||||||
Beispiel:
|
Die Klasse `Cache` hat eine Methode zum Hinzufügen von Elementen (`add`) und eine zum Auslesen (`[]`), wobei jeweils ein String als Schlüssel verwendet wird.
|
||||||
|
|
||||||
|
Wenn ein Element nicht enthalten sein sollte, liefert die Methode `[]` nicht `nil` zurück, sondern ruft einen Block auf, der im Konstruktor der Klasse übergeben wurde. Diese Block beschafft die Daten und gibt sie zurück.
|
||||||
|
|
||||||
|
Eine beispielhafte Benutzung sähe dann wie folgt aus:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
lam = ->(a, b) { a + b }
|
c = Cache.new { |key| "Neuer Wert für key #{key}" }
|
||||||
puts rechner(5, 4, lam) # -> 18
|
c.add 'key1', 'value1'
|
||||||
|
c.add 'key2', 'value2'
|
||||||
|
puts c['key1'] # -> 'value1'
|
||||||
|
puts c['key3'] # -> 'Neuer Wert'
|
||||||
```
|
```
|
|
@ -1,12 +1,19 @@
|
||||||
# Lösung: Callback mit Proc
|
# Lösung: Hashes und Blöcke
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
def rechner(a, b, lam = nil, &block)
|
class Cache
|
||||||
lam ||= block
|
def initialize(&callback)
|
||||||
ergebnis = lam.call(a, b)
|
@data = {}
|
||||||
ergebnis * 2
|
@callback = callback
|
||||||
end
|
end
|
||||||
|
|
||||||
lam = ->(a, b) { a + b }
|
def add(key, value)
|
||||||
puts rechner(5, 4, lam) # -> 18
|
@data[key] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
def [](key)
|
||||||
|
@data[key] = @callback.call(key) unless @data.has_key?(key)
|
||||||
|
@data[key]
|
||||||
|
end
|
||||||
|
end
|
||||||
```
|
```
|
|
@ -1,12 +1,10 @@
|
||||||
# Closure
|
# Hashes
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Ruby-Funktion `create_counter`, die ein Proc-Object zurück gibt. Das Proc-Objekt soll bei jedem Aufruf eine aufsteigende Zahl zurückgeben.
|
Gegeben sei ein Array mit einigen Begriffen (siehe unten). Bitte schreiben Sie eine Funktion `de_dupe`, die ein solches Array mit Strings bekommt, die Duplikate entfernt und danach das Array sortiert wieder zurück gibt. Die Funktion soll intern mit einem _Hash_ arbeiten.
|
||||||
|
|
||||||
Beispiel:
|
|
||||||
```ruby
|
```ruby
|
||||||
p = create_counter
|
worte = %w{ Bier Schnaps Bier Vodka \
|
||||||
puts p.call # -> 1
|
Rum Baileys Rum Bier Vodka Bier Hugo }
|
||||||
puts p.call # -> 2
|
|
||||||
```
|
```
|
|
@ -1,12 +1,14 @@
|
||||||
# Lösung: Closure
|
# Lösung: Hashes
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
|
||||||
def create_counter
|
```ruby
|
||||||
n = 0 # closure
|
worte = %w{ Bier Schnaps Bier Vodka Rum Baileys Rum Bier Vodka Bier Hugo }
|
||||||
Proc.new { n += 1 }
|
|
||||||
|
def de_dupe(input)
|
||||||
|
hash = {}
|
||||||
|
input.each { |e| hash[e] = true }
|
||||||
|
hash.keys.sort
|
||||||
end
|
end
|
||||||
|
|
||||||
p = create_counter
|
puts de_dupe(worte)
|
||||||
puts p.call # -> 1
|
|
||||||
puts p.call # -> 2
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,19 +1,5 @@
|
||||||
# Hashes und Blöcke
|
# Map
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Realisieren Sie einen einfachen _Cache_ mit Hilfe von _Hashes_. Schreiben Sie hierzu eine Klasse `Cache`.
|
Schreiben Sie eine Methode `leeter`, der man ein Array von Strings übergibt und die ein Array mit den entsprechenden Strings in _"Leet Speak"_ zurück gibt. Verwenden Sie hierzu die `map`-Methode.
|
||||||
|
|
||||||
Die Klasse `Cache` hat eine Methode zum Hinzufügen von Elementen (`add`) und eine zum Auslesen (`[]`), wobei jeweils ein String als Schlüssel verwendet wird.
|
|
||||||
|
|
||||||
Wenn ein Element nicht enthalten sein sollte, liefert die Methode `[]` nicht `nil` zurück, sondern ruft einen Block auf, der im Konstruktor der Klasse übergeben wurde. Diese Block beschafft die Daten und gibt sie zurück.
|
|
||||||
|
|
||||||
Eine beispielhafte Benutzung sähe dann wie folgt aus:
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
c = Cache.new { |key| "Neuer Wert für key #{key}" }
|
|
||||||
c.add 'key1', 'value1'
|
|
||||||
c.add 'key2', 'value2'
|
|
||||||
puts c['key1'] # -> 'value1'
|
|
||||||
puts c['key3'] # -> 'Neuer Wert'
|
|
||||||
```
|
|
|
@ -1,19 +1,18 @@
|
||||||
# Lösung: Hashes und Blöcke
|
# Lösung: Map
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
|
||||||
class Cache
|
```ruby
|
||||||
def initialize(&callback)
|
def leeter(array)
|
||||||
@data = {}
|
array.map do |e|
|
||||||
@callback = callback
|
e.gsub(/[aeiot]/, { \
|
||||||
end
|
'a' => '4', \
|
||||||
|
'e' => '3', \
|
||||||
def add(key, value)
|
'i' => '1', \
|
||||||
@data[key] = value
|
'o' => '0', \
|
||||||
end
|
't' => '7'})
|
||||||
|
|
||||||
def [](key)
|
|
||||||
@data[key] = @callback.call(key) unless @data.has_key?(key)
|
|
||||||
@data[key]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test = %w{ Hello world }
|
||||||
|
puts leeter(test)
|
||||||
```
|
```
|
|
@ -1,10 +1,5 @@
|
||||||
# Hashes
|
# Map und Reduce
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Gegeben sei ein Array mit einigen Begriffen (siehe unten). Bitte schreiben Sie eine Funktion `de_dupe`, die ein solches Array mit Strings bekommt, die Duplikate entfernt und danach das Array sortiert wieder zurück gibt. Die Funktion soll intern mit einem _Hash_ arbeiten.
|
Schreiben Sie eine Methode `char_count`, der man eine Reihe von Strings übergeben kann und die am Ende die Summer der Anzahl der Zeichen in allen Strings zurück gibt. Verwenden Sie hierzu sowohl die `map`- als auch die `reduce`-Methode.
|
||||||
|
|
||||||
```ruby
|
|
||||||
worte = %w{ Bier Schnaps Bier Vodka \
|
|
||||||
Rum Baileys Rum Bier Vodka Bier Hugo }
|
|
||||||
```
|
|
|
@ -1,14 +1,12 @@
|
||||||
# Lösung: Hashes
|
# Lösung: Map und Reduce
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
|
||||||
```ruby
|
```ruby
|
||||||
worte = %w{ Bier Schnaps Bier Vodka Rum Baileys Rum Bier Vodka Bier Hugo }
|
def char_count(array)
|
||||||
|
counts = array.map { |e| e.length }
|
||||||
def de_dupe(input)
|
counts.reduce(:+)
|
||||||
hash = {}
|
|
||||||
input.each { |e| hash[e] = true }
|
|
||||||
hash.keys.sort
|
|
||||||
end
|
end
|
||||||
|
|
||||||
puts de_dupe(worte)
|
array = %w{ Free Kevin Mitnick }
|
||||||
|
puts char_count(array)
|
||||||
```
|
```
|
|
@ -1,5 +1,7 @@
|
||||||
# Map
|
# Ausnahmen
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Methode `leeter`, der man ein Array von Strings übergibt und die ein Array mit den entsprechenden Strings in _"Leet Speak"_ zurück gibt. Verwenden Sie hierzu die `map`-Methode.
|
Schreiben Sie eine Funktion `division`, die zwei Zahlen dividiert. Die Funktion soll einen `ArgumentError` werfen, wenn einer der Parameter keine Zahl ist. Außerdem soll ein `ZeroDivisionError` geworfen werden, falls versucht wird durch 0 zu dividieren.
|
||||||
|
|
||||||
|
Testen Sie die Funktion und fangen Sie die Ausnahmen, um sie auszugeben.
|
|
@ -1,18 +1,19 @@
|
||||||
# Lösung: Map
|
# Lösung: Ausnahmen
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
```ruby
|
def division(a, b)
|
||||||
def leeter(array)
|
raise ArgumentError unless (a.is_a? Numeric) && (b.is_a? Numeric)
|
||||||
array.map do |e|
|
raise ZeroDivisionError if b == 0
|
||||||
e.gsub(/[aeiot]/, { \
|
a / b
|
||||||
'a' => '4', \
|
|
||||||
'e' => '3', \
|
|
||||||
'i' => '1', \
|
|
||||||
'o' => '0', \
|
|
||||||
't' => '7'})
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test = %w{ Hello world }
|
begin
|
||||||
puts leeter(test)
|
puts division(1.0, 4.0)
|
||||||
|
puts division(1.0, 0.0)
|
||||||
|
puts division('a', 7)
|
||||||
|
rescue ArgumentError => e
|
||||||
|
puts e
|
||||||
|
rescue ZeroDivisionError => e
|
||||||
|
puts e
|
||||||
|
end
|
||||||
```
|
```
|
|
@ -1,12 +1,5 @@
|
||||||
# Aufgabenblock 3: Ruby Container
|
# Klasse Dir und IO
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Die Aufgaben in dieser Einheit beziehen sich auf die Vorlesungsfolien __Container, Blöcke und Iteratoren__.
|
Schreiben Sie Skript, das mit Hilfe der Klassen `Dir` und `IO` alle Dateien im aktuellen Verzeichnis mit der Endung `.txt` ausgibt. Dabei sollen für jede Zeile und Datei die Zeilennummern vorangestellt werden.
|
||||||
|
|
||||||
Folgende Themen werden durch die Aufgaben abgedeckt:
|
|
||||||
|
|
||||||
* Arrays
|
|
||||||
* Hashes
|
|
||||||
* Blöcke
|
|
||||||
* Iteratoren
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Lösung: Klasse Dir und IO
|
||||||
|
|
||||||
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
|
def print(f)
|
||||||
|
n = 0
|
||||||
|
puts f, "\n"
|
||||||
|
IO.foreach(f) do |line|
|
||||||
|
puts "%4d %s" % [ n, line ]
|
||||||
|
n += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "\n\n"
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
Dir.foreach('.') do |f|
|
||||||
|
print f if /.*\.txt$/ =~ f
|
||||||
|
end
|
||||||
|
```
|
|
@ -1,5 +1,5 @@
|
||||||
# Map und Reduce
|
# Iteratoren auf Zahlen
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Methode `char_count`, der man eine Reihe von Strings übergeben kann und die am Ende die Summer der Anzahl der Zeichen in allen Strings zurück gibt. Verwenden Sie hierzu sowohl die `map`- als auch die `reduce`-Methode.
|
Schreiben Sie eine Countdown von 10 auf 0. Verwenden Sie dazu die Methode `downto` von `Number`.
|
|
@ -1,12 +1,5 @@
|
||||||
# Lösung: Map und Reduce
|
# Lösung: Iteratoren auf Zahlen
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
```ruby
|
10.downto(0) { |n| puts n }
|
||||||
def char_count(array)
|
|
||||||
counts = array.map { |e| e.length }
|
|
||||||
counts.reduce(:+)
|
|
||||||
end
|
|
||||||
|
|
||||||
array = %w{ Free Kevin Mitnick }
|
|
||||||
puts char_count(array)
|
|
||||||
```
|
```
|
|
@ -1,7 +1,7 @@
|
||||||
# Ausnahmen
|
# Quine
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Funktion `division`, die zwei Zahlen dividiert. Die Funktion soll einen `ArgumentError` werfen, wenn einer der Parameter keine Zahl ist. Außerdem soll ein `ZeroDivisionError` geworfen werden, falls versucht wird durch 0 zu dividieren.
|
Schreiben Sie ein Ruby-Programm, dass sich selbst ausgibt. Es darf seinen Quelltext _nicht_ einlesen, sondern nur Ausgabeanweisungen enthalten.
|
||||||
|
|
||||||
Testen Sie die Funktion und fangen Sie die Ausnahmen, um sie auszugeben.
|
_Tipp_: Sie werden eine Variable mit dem Programm als String benötigen. In dem String selbst wird sich ein Platzhalter für einen Formatter befinden.
|
|
@ -1,19 +1,5 @@
|
||||||
# Lösung: Ausnahmen
|
# Lösung: Quine
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
def division(a, b)
|
p = "p = \"%s\"; puts p %% [ p.gsub(/[\"\\\\]/, '\"' => '\\\"', '\\\\' => '\\\\\\\\') ]"; puts p % [ p.gsub(/["\\]/, '"' => '\\"', '\\' => '\\\\') ]
|
||||||
raise ArgumentError unless (a.is_a? Numeric) && (b.is_a? Numeric)
|
|
||||||
raise ZeroDivisionError if b == 0
|
|
||||||
a / b
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
|
||||||
puts division(1.0, 4.0)
|
|
||||||
puts division(1.0, 0.0)
|
|
||||||
puts division('a', 7)
|
|
||||||
rescue ArgumentError => e
|
|
||||||
puts e
|
|
||||||
rescue ZeroDivisionError => e
|
|
||||||
puts e
|
|
||||||
end
|
|
||||||
```
|
```
|
|
@ -1,5 +1,15 @@
|
||||||
# Klasse Dir und IO
|
# Reguläre Ausdrücke: Match
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie Skript, das mit Hilfe der Klassen `Dir` und `IO` alle Dateien im aktuellen Verzeichnis mit der Endung `.txt` ausgibt. Dabei sollen für jede Zeile und Datei die Zeilennummern vorangestellt werden.
|
Schreiben Sie eine Ruby-Methode `tag?`, die angibt, ob es sich bei dem übergebenen String um ein HTML-Tag handelt. Verwenden Sie hierzu einen entsprechenden regulären Ausdruck.
|
||||||
|
|
||||||
|
Beispiel:
|
||||||
|
```ruby
|
||||||
|
tag?("<a href='xx'>") # -> true
|
||||||
|
tag?("hugo <jjj>") # -> false
|
||||||
|
tag?("<a href='xx'") # -> false
|
||||||
|
tag?("<p/>") # -> true
|
||||||
|
tag?("<p") # -> false
|
||||||
|
tag?("p>") # -> false
|
||||||
|
```
|
|
@ -1,19 +1,14 @@
|
||||||
# Lösung: Klasse Dir und IO
|
# Lösung: Reguläre Ausdrücke: Match
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
|
||||||
def print(f)
|
|
||||||
n = 0
|
|
||||||
puts f, "\n"
|
|
||||||
IO.foreach(f) do |line|
|
|
||||||
puts "%4d %s" % [ n, line ]
|
|
||||||
n += 1
|
|
||||||
end
|
|
||||||
|
|
||||||
puts "\n\n"
|
|
||||||
|
|
||||||
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
|
def tag?(text)
|
||||||
|
!!(/^<.*?>$/ =~ text)
|
||||||
end
|
end
|
||||||
|
|
||||||
Dir.foreach('.') do |f|
|
tag?("<a href='xx'>") # -> true
|
||||||
print f if /.*\.txt$/ =~ f
|
tag?("hugo <jjj>") # -> false
|
||||||
end
|
tag?("<a href='xx'") # -> false
|
||||||
|
tag?("<p/>") # -> true
|
||||||
|
tag?("<p") # -> false
|
||||||
|
tag?("p>") # -> false
|
||||||
```
|
```
|
|
@ -1,5 +1,13 @@
|
||||||
# Iteratoren auf Zahlen
|
# Reguläre Ausdrücke: Matching
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Countdown von 10 auf 0. Verwenden Sie dazu die Methode `downto` von `Number`.
|
Schreiben Sie eine Funktion `reverser`, die bei einem String, der aus zwei Wörtern besteht (durch Leerzeichen getrennt), diese umdreht. Verwenden Sie hierzu einen Regulären Ausdruck.
|
||||||
|
|
||||||
|
Beispiel:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
s = "Ruby Programmierer"
|
||||||
|
puts reverser(s)
|
||||||
|
# -> "Programmierer Ruby"
|
||||||
|
```
|
|
@ -1,5 +1,21 @@
|
||||||
# Lösung: Iteratoren auf Zahlen
|
# Lösung: Reguläre Ausdrücke: Matching
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
10.downto(0) { |n| puts n }
|
def reverser(s)
|
||||||
|
/(.*) (.*)/ =~ s
|
||||||
|
"#{$2} #{$1}"
|
||||||
|
end
|
||||||
|
|
||||||
|
puts reverser("Ruby Programmierer")
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternative Lösung:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
def reverser(s)
|
||||||
|
m = /(.*) (.*)/.match(s)
|
||||||
|
"#{m[2]} #{m[1]}"
|
||||||
|
end
|
||||||
|
|
||||||
|
puts reverser("Ruby Programmierer")
|
||||||
```
|
```
|
|
@ -1,7 +1,22 @@
|
||||||
# Quine
|
# Klassen per Reflection analysieren
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie ein Ruby-Programm, dass sich selbst ausgibt. Es darf seinen Quelltext _nicht_ einlesen, sondern nur Ausgabeanweisungen enthalten.
|
Schreiben Sie eine Methode `analyze`, der man eine Klasse übergibt und die dann folgende Informationen zu der Klasse ausgibt:
|
||||||
|
|
||||||
_Tipp_: Sie werden eine Variable mit dem Programm als String benötigen. In dem String selbst wird sich ein Platzhalter für einen Formatter befinden.
|
* Name der Klasse
|
||||||
|
* Elternklasse
|
||||||
|
* Instanzmethoden
|
||||||
|
* Statische Methoden
|
||||||
|
* Konstanten
|
||||||
|
|
||||||
|
Beispiel:
|
||||||
|
|
||||||
|
```console
|
||||||
|
> analyze(String)
|
||||||
|
Name: String
|
||||||
|
Elternklasse: Object
|
||||||
|
Instanz-Methoden: [:encode, :include?, ...]
|
||||||
|
Statische-Methoden: [:try_convert]
|
||||||
|
Konstanten: []
|
||||||
|
```
|
|
@ -1,5 +1,13 @@
|
||||||
# Lösung: Quine
|
# Lösung: Klassen per Reflection analysieren
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
p = "p = \"%s\"; puts p %% [ p.gsub(/[\"\\\\]/, '\"' => '\\\"', '\\\\' => '\\\\\\\\') ]"; puts p % [ p.gsub(/["\\]/, '"' => '\\"', '\\' => '\\\\') ]
|
def analyze(clazz)
|
||||||
|
puts "Name: #{clazz.to_s}"
|
||||||
|
puts "Elternklasse: #{clazz.superclass}"
|
||||||
|
puts "Instanz-Methoden: #{clazz.instance_methods}"
|
||||||
|
puts "Statische-Methoden: #{clazz.singleton_methods}"
|
||||||
|
puts "Konstanten: #{clazz.constants}"
|
||||||
|
end
|
||||||
|
|
||||||
|
analyze(String)
|
||||||
```
|
```
|
|
@ -1,14 +1,20 @@
|
||||||
# Aufgabenblock 4: Ruby Typen
|
# Methoden einer Klasse dynamisch erzeugen
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Die Aufgaben in dieser Einheit beziehen sich auf die Vorlesungsfolien __Standard Typen und Reguläre Ausdrücke__.
|
Schreiben Sie eine Funktion `leet_class`, die zu jeder vorhandenen (nicht geerbten) Instanzmethode eine weitere Methode hinzufügt, die den Namen der ursprünglichen Methode in _Leet Speak_ hat. Die neue Methode muss keine Funktion haben, kann aber auch gerne an die ursprüngliche Methode delegieren.
|
||||||
|
|
||||||
Folgende Themen werden durch die Aufgaben abgedeckt:
|
Beispiel:
|
||||||
|
|
||||||
* Zahlen
|
```ruby
|
||||||
* Strings
|
class M
|
||||||
* Ranges
|
def hello; end
|
||||||
* Reguläre Ausdrücke
|
def world; end
|
||||||
* Ausnahmen
|
end
|
||||||
* Input/Output
|
|
||||||
|
leet_class(M)
|
||||||
|
|
||||||
|
m = M.new
|
||||||
|
m.h3ll0
|
||||||
|
m.w0rld
|
||||||
|
```
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Lösung: Methoden einer Klasse dynamisch erzeugen
|
||||||
|
|
||||||
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
|
def to_leet(s)
|
||||||
|
s.tr('aeiou', '43107')
|
||||||
|
end
|
||||||
|
|
||||||
|
def leet_class(clazz)
|
||||||
|
clazz.instance_methods(false).each do |m|
|
||||||
|
name = m.to_s
|
||||||
|
leet_name = to_leet(name).to_sym
|
||||||
|
puts leet_name
|
||||||
|
clazz.define_method(leet_name) do |*p|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class M
|
||||||
|
def hello; end
|
||||||
|
def world; end
|
||||||
|
end
|
||||||
|
|
||||||
|
leet_class(M)
|
||||||
|
|
||||||
|
m = M.new
|
||||||
|
m.h3ll0
|
||||||
|
m.w0rld
|
||||||
|
``
|
|
@ -1,15 +1,5 @@
|
||||||
# Reguläre Ausdrücke: Match
|
# Klasse dynamisch erzeugen
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Ruby-Methode `tag?`, die angibt, ob es sich bei dem übergebenen String um ein HTML-Tag handelt. Verwenden Sie hierzu einen entsprechenden regulären Ausdruck.
|
Schreiben Sie eine Funktion `create_class`, der man den die Superklasse übergeben kann. Die Funktion erzeugt dann dynamisch die Klasse und fügt ihr eine Methode `who_am_i` hinzu, die als Text "Ich bin ein Kind von " + den Namen der Superklasse zurückgibt.
|
||||||
|
|
||||||
Beispiel:
|
|
||||||
```ruby
|
|
||||||
tag?("<a href='xx'>") # -> true
|
|
||||||
tag?("hugo <jjj>") # -> false
|
|
||||||
tag?("<a href='xx'") # -> false
|
|
||||||
tag?("<p/>") # -> true
|
|
||||||
tag?("<p") # -> false
|
|
||||||
tag?("p>") # -> false
|
|
||||||
```
|
|
|
@ -1,14 +1,15 @@
|
||||||
# Lösung: Reguläre Ausdrücke: Match
|
# Lösung: Klasse dynamisch erzeugen
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
def tag?(text)
|
def create_class(super_class)
|
||||||
!!(/^<.*?>$/ =~ text)
|
Class.new(super_class) do
|
||||||
|
def who_am_i
|
||||||
|
puts "Ich bin ein Kind von #{self.class.superclass}"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
tag?("<a href='xx'>") # -> true
|
Test = create_class(Object)
|
||||||
tag?("hugo <jjj>") # -> false
|
t = Test.new
|
||||||
tag?("<a href='xx'") # -> false
|
t.who_am_i
|
||||||
tag?("<p/>") # -> true
|
|
||||||
tag?("<p") # -> false
|
|
||||||
tag?("p>") # -> false
|
|
||||||
```
|
```
|
|
@ -1,13 +1,7 @@
|
||||||
# Reguläre Ausdrücke: Matching
|
# Methoden dynamisch aufrufen
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Funktion `reverser`, die bei einem String, der aus zwei Wörtern besteht (durch Leerzeichen getrennt), diese umdreht. Verwenden Sie hierzu einen Regulären Ausdruck.
|
Schreiben Sie eine Funktion `crazy_caller`, der man ein Objekt übergeben kann. Die Funktion schaut nach, welche Methoden auf dem Objekt aufrufbar sind und ruft dann alle Methoden auf, die keinen Parameter benötigen.
|
||||||
|
|
||||||
Beispiel:
|
Einige Methoden werden einen Fehler werfen, fangen Sie diesen ab.
|
||||||
|
|
||||||
```ruby
|
|
||||||
s = "Ruby Programmierer"
|
|
||||||
puts reverser(s)
|
|
||||||
# -> "Programmierer Ruby"
|
|
||||||
```
|
|
|
@ -1,21 +1,27 @@
|
||||||
# Lösung: Reguläre Ausdrücke: Matching
|
# Lösung: Methoden dynamisch aufrufen
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
def reverser(s)
|
def crazy_caller(obj)
|
||||||
/(.*) (.*)/ =~ s
|
# Methoden suchen
|
||||||
"#{$2} #{$1}"
|
obj.methods.each do |m|
|
||||||
|
# m enthält ein Symbol mit dem Namen der Methode,
|
||||||
|
# wir wollen aber das Methoden-Objekt
|
||||||
|
method = obj.method(m)
|
||||||
|
|
||||||
|
begin
|
||||||
|
# Methode aufrufen, wenn sie keinen Parameter hat
|
||||||
|
method.call {} if method.arity == 0
|
||||||
|
rescue
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
puts reverser("Ruby Programmierer")
|
class Test
|
||||||
```
|
def m1; puts 'm1'; end
|
||||||
|
def m2; puts 'm2'; end
|
||||||
Alternative Lösung:
|
def m3(a); puts 'm3'; end
|
||||||
|
def m4(a, b); puts 'm4'; end
|
||||||
```ruby
|
|
||||||
def reverser(s)
|
|
||||||
m = /(.*) (.*)/.match(s)
|
|
||||||
"#{m[2]} #{m[1]}"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
puts reverser("Ruby Programmierer")
|
crazy_caller(Test.new)
|
||||||
```
|
```
|
|
@ -1,22 +1,5 @@
|
||||||
# Klassen per Reflection analysieren
|
# Eigenclass einer Klasse
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Methode `analyze`, der man eine Klasse übergibt und die dann folgende Informationen zu der Klasse ausgibt:
|
Fügen Sie der Klasse `Numeric` über deren _Eigenclass_ eine _statische Methode_ `to_binary` hinzu, der man eine Zahl übergibt und diese in binärer Darstellung als String zurück bekommt.
|
||||||
|
|
||||||
* Name der Klasse
|
|
||||||
* Elternklasse
|
|
||||||
* Instanzmethoden
|
|
||||||
* Statische Methoden
|
|
||||||
* Konstanten
|
|
||||||
|
|
||||||
Beispiel:
|
|
||||||
|
|
||||||
```console
|
|
||||||
> analyze(String)
|
|
||||||
Name: String
|
|
||||||
Elternklasse: Object
|
|
||||||
Instanz-Methoden: [:encode, :include?, ...]
|
|
||||||
Statische-Methoden: [:try_convert]
|
|
||||||
Konstanten: []
|
|
||||||
```
|
|
|
@ -1,13 +1,25 @@
|
||||||
# Lösung: Klassen per Reflection analysieren
|
# Lösung: Eigenclass einer Klasse
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
def analyze(clazz)
|
class Numeric
|
||||||
puts "Name: #{clazz.to_s}"
|
class << self
|
||||||
puts "Elternklasse: #{clazz.superclass}"
|
def to_binary(n)
|
||||||
puts "Instanz-Methoden: #{clazz.instance_methods}"
|
n.to_s(2)
|
||||||
puts "Statische-Methoden: #{clazz.singleton_methods}"
|
end
|
||||||
puts "Konstanten: #{clazz.constants}"
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
analyze(String)
|
puts Numeric::to_binary(47)
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternative Lösung:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class << Numeric
|
||||||
|
def to_binary(n)
|
||||||
|
n.to_s(2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
puts Numeric::to_binary(47)
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,20 +1,10 @@
|
||||||
# Methoden einer Klasse dynamisch erzeugen
|
# Eigenclass eines Objektes
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Funktion `leet_class`, die zu jeder vorhandenen (nicht geerbten) Instanzmethode eine weitere Methode hinzufügt, die den Namen der ursprünglichen Methode in _Leet Speak_ hat. Die neue Methode muss keine Funktion haben, kann aber auch gerne an die ursprüngliche Methode delegieren.
|
Der unten stehende Code erzeugt zwei Objekte vom Typ `String`. Fügen Sie der _Eigenclass_ von `s2` eine _Methode_ `to_leet` hinzu, die den Inhalt des Objektes in "Leet Speak" ausgibt.
|
||||||
|
|
||||||
Beispiel:
|
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
class M
|
s1 = "Hallo"
|
||||||
def hello; end
|
s2 = "Welt"
|
||||||
def world; end
|
|
||||||
end
|
|
||||||
|
|
||||||
leet_class(M)
|
|
||||||
|
|
||||||
m = M.new
|
|
||||||
m.h3ll0
|
|
||||||
m.w0rld
|
|
||||||
```
|
```
|
|
@ -1,28 +1,14 @@
|
||||||
# Lösung: Methoden einer Klasse dynamisch erzeugen
|
# Lösung: Eigenclass eines Objektes
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
def to_leet(s)
|
s1 = "Hallo"
|
||||||
s.tr('aeiou', '43107')
|
s2 = "Welt"
|
||||||
end
|
|
||||||
|
|
||||||
def leet_class(clazz)
|
class << s2
|
||||||
clazz.instance_methods(false).each do |m|
|
def to_leet
|
||||||
name = m.to_s
|
self.tr('aeiou', '43107')
|
||||||
leet_name = to_leet(name).to_sym
|
|
||||||
puts leet_name
|
|
||||||
clazz.define_method(leet_name) do |*p|
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class M
|
puts s2.to_leet
|
||||||
def hello; end
|
```
|
||||||
def world; end
|
|
||||||
end
|
|
||||||
|
|
||||||
leet_class(M)
|
|
||||||
|
|
||||||
m = M.new
|
|
||||||
m.h3ll0
|
|
||||||
m.w0rld
|
|
||||||
``
|
|
||||||
|
|
|
@ -1,5 +1,17 @@
|
||||||
# Klasse dynamisch erzeugen
|
# Macro
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Funktion `create_class`, der man den die Superklasse übergeben kann. Die Funktion erzeugt dann dynamisch die Klasse und fügt ihr eine Methode `who_am_i` hinzu, die als Text "Ich bin ein Kind von " + den Namen der Superklasse zurückgibt.
|
Schreiben Sie ein Modul `Javanator`, das eine Klassen einbinden kann. Durch Aufruf der Methode `javafy` kann die Klasse sich dann die Methode `toString` hinzufügen lassen, die einfach nur `to_s` aufruft.
|
||||||
|
|
||||||
|
Beispiel:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class Test
|
||||||
|
include Javanator
|
||||||
|
Javanator::javafy
|
||||||
|
end
|
||||||
|
|
||||||
|
t = Test.new
|
||||||
|
t.toString
|
||||||
|
```
|
|
@ -1,15 +1,17 @@
|
||||||
# Lösung: Klasse dynamisch erzeugen
|
# Lösung: Macro
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
def create_class(super_class)
|
module Javanator
|
||||||
Class.new(super_class) do
|
def Javanator::javafy
|
||||||
def who_am_i
|
def toString; to_s; end
|
||||||
puts "Ich bin ein Kind von #{self.class.superclass}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Test = create_class(Object)
|
class Test
|
||||||
|
include Javanator
|
||||||
|
Javanator::javafy
|
||||||
|
end
|
||||||
|
|
||||||
t = Test.new
|
t = Test.new
|
||||||
t.who_am_i
|
t.toString
|
||||||
```
|
```
|
|
@ -1,7 +1,22 @@
|
||||||
# Methoden dynamisch aufrufen
|
# Metaprogrammierung: Die kleine Petze
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Schreiben Sie eine Funktion `crazy_caller`, der man ein Objekt übergeben kann. Die Funktion schaut nach, welche Methoden auf dem Objekt aufrufbar sind und ruft dann alle Methoden auf, die keinen Parameter benötigen.
|
Schreiben Sie eine Ruby Klasse `Snitch`, deren Objekte man an jede beliebige Ruby-Methode übergeben kann. `Snitch` soll dann auf der Konsole ausgeben, welche Methoden mit welchen Parametern auf ihm aufgerufen wurden.
|
||||||
|
|
||||||
Einige Methoden werden einen Fehler werfen, fangen Sie diesen ab.
|
Beispiel:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
snitch = Snitch.new
|
||||||
|
puts snitch
|
||||||
|
```
|
||||||
|
|
||||||
|
Ausgabe:
|
||||||
|
|
||||||
|
```console
|
||||||
|
Aufruf von Methode 'to_ary'
|
||||||
|
mit den Argumenten []
|
||||||
|
mit den Argumenten {}
|
||||||
|
und dem Block
|
||||||
|
Aufruf von Methode 'to_s'
|
||||||
|
```
|
|
@ -1,27 +1,21 @@
|
||||||
# Lösung: Methoden dynamisch aufrufen
|
# Lösung: Metaprogrammierung: Die kleine Petze
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
def crazy_caller(obj)
|
class Snitch
|
||||||
# Methoden suchen
|
def method_missing(name, *args, **keywords, &block)
|
||||||
obj.methods.each do |m|
|
puts "Aufruf von Methode '#{name}'"
|
||||||
# m enthält ein Symbol mit dem Namen der Methode,
|
puts " mit den Argumenten #{args}"
|
||||||
# wir wollen aber das Methoden-Objekt
|
puts " mit den Argumenten #{keywords}"
|
||||||
method = obj.method(m)
|
puts " und dem Block #{block}"
|
||||||
|
|
||||||
begin
|
|
||||||
# Methode aufrufen, wenn sie keinen Parameter hat
|
|
||||||
method.call {} if method.arity == 0
|
|
||||||
rescue
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
puts "Aufruf von Methode 'to_s'"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Weiter Methoden von Object überschreiben. Hier weggelassen.
|
||||||
end
|
end
|
||||||
|
|
||||||
class Test
|
snitch = Snitch.new
|
||||||
def m1; puts 'm1'; end
|
puts snitch
|
||||||
def m2; puts 'm2'; end
|
|
||||||
def m3(a); puts 'm3'; end
|
|
||||||
def m4(a, b); puts 'm4'; end
|
|
||||||
end
|
|
||||||
|
|
||||||
crazy_caller(Test.new)
|
|
||||||
```
|
```
|
|
@ -1,5 +1,10 @@
|
||||||
# Eigenclass einer Klasse
|
# Singleton Methoden
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Fügen Sie der Klasse `Numeric` über deren _Eigenclass_ eine _statische Methode_ `to_binary` hinzu, der man eine Zahl übergibt und diese in binärer Darstellung als String zurück bekommt.
|
Der unten stehende Code erzeugt zwei Objekte vom Typ `String`. Fügen Sie `s2` eine _Singleton Methode_ `to_leet` hinzu, die den Inhalt des Objektes in "Leet Speak" ausgibt.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
s1 = "Hallo"
|
||||||
|
s2 = "Welt"
|
||||||
|
```
|
|
@ -1,25 +1,12 @@
|
||||||
# Lösung: Eigenclass einer Klasse
|
# Lösung: Singleton Methoden
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
class Numeric
|
s1 = "Hallo"
|
||||||
class << self
|
s2 = "Welt"
|
||||||
def to_binary(n)
|
|
||||||
n.to_s(2)
|
def s2.to_leet
|
||||||
end
|
self.tr('aeiou', '43107')
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
puts Numeric::to_binary(47)
|
puts s2.to_leet
|
||||||
```
|
|
||||||
|
|
||||||
Alternative Lösung:
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
class << Numeric
|
|
||||||
def to_binary(n)
|
|
||||||
n.to_s(2)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
puts Numeric::to_binary(47)
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
# Eigenclass eines Objektes
|
# Struct
|
||||||
|
|
||||||
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
📆 **Fällig: ----** 📆 [Musterlösung](solution/)
|
||||||
|
|
||||||
Der unten stehende Code erzeugt zwei Objekte vom Typ `String`. Fügen Sie der _Eigenclass_ von `s2` eine _Methode_ `to_leet` hinzu, die den Inhalt des Objektes in "Leet Speak" ausgibt.
|
Verwenden Sie die Klasse `Struct`, um sehr einfach eine Klasse zur Verwaltung von Studierenden (`Studierender`) zu erzeugen. Ein Studierender hat folgende Eigenschaften:
|
||||||
|
|
||||||
```ruby
|
* Vorname
|
||||||
s1 = "Hallo"
|
* Nachname
|
||||||
s2 = "Welt"
|
* Geburtsdatum
|
||||||
```
|
* Matrikelnummer
|
||||||
|
* Fakultät
|
||||||
|
|
||||||
|
Fügen Sie eine `to_s`-Methode zur Klasse hinzu, die nur die Matrikelnummer zurückgibt.
|
||||||
|
|
||||||
|
Erzeugen Sie danach ein Objekt von Ihrer Klasse.
|
|
@ -1,14 +1,16 @@
|
||||||
# Lösung: Eigenclass eines Objektes
|
# Lösung: Struct
|
||||||
|
|
||||||
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
<div style="border: 1px solid grey;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>```ruby
|
||||||
s1 = "Hallo"
|
# Klasse (sic!) über Struct erzeugen
|
||||||
s2 = "Welt"
|
Studierender = Struct.new(:vorname, :nachname, :geboren, :matrikel, :fakultaet)
|
||||||
|
|
||||||
class << s2
|
# KLasse noch einmal öffnen und Methode hinzufügen
|
||||||
def to_leet
|
class Studierender
|
||||||
self.tr('aeiou', '43107')
|
def to_s
|
||||||
|
matrikel
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
puts s2.to_leet
|
peter = Studierender.new('Peter', 'Meier', '15.03.1998', '123222', 'I')
|
||||||
|
puts peter
|
||||||
```
|
```
|
||||||
|
|
77
readme.md
77
readme.md
|
@ -13,44 +13,39 @@ Die **Abgabedaten** haben keine Bedeutung, da der Kurs keine Prüfung beinhaltet
|
||||||
| 3. | [String-Formatierung](Assignment_003/readme.md) | **----** |
|
| 3. | [String-Formatierung](Assignment_003/readme.md) | **----** |
|
||||||
| 4. | [Parallele Zuweisung](Assignment_004/readme.md) | **----** |
|
| 4. | [Parallele Zuweisung](Assignment_004/readme.md) | **----** |
|
||||||
| 5. | [Ranges](Assignment_005/readme.md) | **----** |
|
| 5. | [Ranges](Assignment_005/readme.md) | **----** |
|
||||||
| 6. | [Aufgabenblock 1: Ruby Grundlagen](Assignment_006/readme.md) | **----** |
|
| 6. | [Splat](Assignment_006/readme.md) | **----** |
|
||||||
| 7. | [Splat](Assignment_007/readme.md) | **----** |
|
| 7. | [Symbole](Assignment_007/readme.md) | **----** |
|
||||||
| 8. | [Symbole](Assignment_008/readme.md) | **----** |
|
| 8. | [Zugriffsmethoden](Assignment_008/readme.md) | **----** |
|
||||||
| 9. | [Zugriffsmethoden](Assignment_009/readme.md) | **----** |
|
| 9. | [Klasse deklarieren](Assignment_009/readme.md) | **----** |
|
||||||
| 10. | [Klasse deklarieren](Assignment_010/readme.md) | **----** |
|
| 10. | [Default Parameter](Assignment_010/readme.md) | **----** |
|
||||||
| 11. | [Default Parameter](Assignment_011/readme.md) | **----** |
|
| 11. | [Vererbung](Assignment_011/readme.md) | **----** |
|
||||||
| 12. | [Vererbung](Assignment_012/readme.md) | **----** |
|
| 12. | [Keyword-Parameter](Assignment_012/readme.md) | **----** |
|
||||||
| 13. | [Keyword-Parameter](Assignment_013/readme.md) | **----** |
|
| 13. | [Mixin benutzen](Assignment_013/readme.md) | **----** |
|
||||||
| 14. | [Mixin benutzen](Assignment_014/readme.md) | **----** |
|
| 14. | [Modul schreiben](Assignment_014/readme.md) | **----** |
|
||||||
| 15. | [Modul schreiben](Assignment_015/readme.md) | **----** |
|
| 15. | [Monkey Patch](Assignment_015/readme.md) | **----** |
|
||||||
| 16. | [Monkey Patch](Assignment_016/readme.md) | **----** |
|
| 16. | [Geschachtelte Methoden](Assignment_016/readme.md) | **----** |
|
||||||
| 17. | [Geschachtelte Methoden](Assignment_017/readme.md) | **----** |
|
| 17. | [Vararg-Methoden](Assignment_017/readme.md) | **----** |
|
||||||
| 18. | [Aufgabenblock 2: Ruby Klassen](Assignment_018/readme.md) | **----** |
|
| 18. | [Arrays](Assignment_018/readme.md) | **----** |
|
||||||
| 19. | [Vararg-Methoden](Assignment_019/readme.md) | **----** |
|
| 19. | [Callback mit Block](Assignment_019/readme.md) | **----** |
|
||||||
| 20. | [Arrays](Assignment_020/readme.md) | **----** |
|
| 20. | [Callback mit Proc](Assignment_020/readme.md) | **----** |
|
||||||
| 21. | [Callback mit Block](Assignment_021/readme.md) | **----** |
|
| 21. | [Closure](Assignment_021/readme.md) | **----** |
|
||||||
| 22. | [Callback mit Proc](Assignment_022/readme.md) | **----** |
|
| 22. | [Hashes und Blöcke](Assignment_022/readme.md) | **----** |
|
||||||
| 23. | [Closure](Assignment_023/readme.md) | **----** |
|
| 23. | [Hashes](Assignment_023/readme.md) | **----** |
|
||||||
| 24. | [Hashes und Blöcke](Assignment_024/readme.md) | **----** |
|
| 24. | [Map](Assignment_024/readme.md) | **----** |
|
||||||
| 25. | [Hashes](Assignment_025/readme.md) | **----** |
|
| 25. | [Map und Reduce](Assignment_025/readme.md) | **----** |
|
||||||
| 26. | [Map](Assignment_026/readme.md) | **----** |
|
| 26. | [Ausnahmen](Assignment_026/readme.md) | **----** |
|
||||||
| 27. | [Aufgabenblock 3: Ruby Container](Assignment_027/readme.md) | **----** |
|
| 27. | [Klasse Dir und IO](Assignment_027/readme.md) | **----** |
|
||||||
| 28. | [Map und Reduce](Assignment_028/readme.md) | **----** |
|
| 28. | [Iteratoren auf Zahlen](Assignment_028/readme.md) | **----** |
|
||||||
| 29. | [Ausnahmen](Assignment_029/readme.md) | **----** |
|
| 29. | [Quine](Assignment_029/readme.md) | **----** |
|
||||||
| 30. | [Klasse Dir und IO](Assignment_030/readme.md) | **----** |
|
| 30. | [Reguläre Ausdrücke: Match](Assignment_030/readme.md) | **----** |
|
||||||
| 31. | [Iteratoren auf Zahlen](Assignment_031/readme.md) | **----** |
|
| 31. | [Reguläre Ausdrücke: Matching](Assignment_031/readme.md) | **----** |
|
||||||
| 32. | [Quine](Assignment_032/readme.md) | **----** |
|
| 32. | [Klassen per Reflection analysieren](Assignment_032/readme.md) | **----** |
|
||||||
| 33. | [Aufgabenblock 4: Ruby Typen](Assignment_033/readme.md) | **----** |
|
| 33. | [Methoden einer Klasse dynamisch erzeugen](Assignment_033/readme.md) | **----** |
|
||||||
| 34. | [Reguläre Ausdrücke: Match](Assignment_034/readme.md) | **----** |
|
| 34. | [Klasse dynamisch erzeugen](Assignment_034/readme.md) | **----** |
|
||||||
| 35. | [Reguläre Ausdrücke: Matching](Assignment_035/readme.md) | **----** |
|
| 35. | [Methoden dynamisch aufrufen](Assignment_035/readme.md) | **----** |
|
||||||
| 36. | [Klassen per Reflection analysieren](Assignment_036/readme.md) | **----** |
|
| 36. | [Eigenclass einer Klasse](Assignment_036/readme.md) | **----** |
|
||||||
| 37. | [Methoden einer Klasse dynamisch erzeugen](Assignment_037/readme.md) | **----** |
|
| 37. | [Eigenclass eines Objektes](Assignment_037/readme.md) | **----** |
|
||||||
| 38. | [Klasse dynamisch erzeugen](Assignment_038/readme.md) | **----** |
|
| 38. | [Macro](Assignment_038/readme.md) | **----** |
|
||||||
| 39. | [Methoden dynamisch aufrufen](Assignment_039/readme.md) | **----** |
|
| 39. | [Metaprogrammierung: Die kleine Petze](Assignment_039/readme.md) | **----** |
|
||||||
| 40. | [Eigenclass einer Klasse](Assignment_040/readme.md) | **----** |
|
| 40. | [Singleton Methoden](Assignment_040/readme.md) | **----** |
|
||||||
| 41. | [Eigenclass eines Objektes](Assignment_041/readme.md) | **----** |
|
| 41. | [Struct](Assignment_041/readme.md) | **----** |
|
||||||
| 42. | [Macro](Assignment_042/readme.md) | **----** |
|
|
||||||
| 43. | [Metaprogrammierung: Die kleine Petze](Assignment_043/readme.md) | **----** |
|
|
||||||
| 44. | [Aufgabenblock 5: Fortgeschrittene Themen](Assignment_044/readme.md) | **----** |
|
|
||||||
| 45. | [Singleton Methoden](Assignment_045/readme.md) | **----** |
|
|
||||||
| 46. | [Struct](Assignment_046/readme.md) | **----** |
|
|
||||||
|
|
Loading…
Reference in New Issue