« Juli 2007 | Main | September 2007 »

August 2007 Archives

25.08.07

Flog Score

"Flog shows you the most torturous code you wrote. The more painful the code, the higher the score."

Damit ist eigentlich alles gesagt! Hier der Link: http://ruby.sadi.st/Flog.html

Die Score des Codes aus dem Posting zuvor:

ss1.rb:20: warning: `&' interpreted as argument prefix
Total score = 38.8476045651339

main#none: (11.9)
     2.7: assignment
     1.9: to_a
     1.7: flatten
     1.6: name
     1.5: map
     1.5: branch
     1.3: []
     1.3: find
     1.1: pp
     1.1: new
SecretSanta#initialize: (6.7)
     3.9: assignment
     2.8: dup
     1.3: shuffle!
     1.3: assign!
SecretSanta#no_two_indices_are_alike: (5.2)
     4.2: assignment
     1.4: ==
     1.3: branch
     1.3: all?

Und die von meinem Code:

Total score = 64.3800571683191

main#assign_santas: (27.4)
     7.0: assignment
     6.8: branch
     5.3: personal_santa
     4.7: can_be_santa_of?
     3.8: length
     3.4: rand
     2.4: each
     1.7: []
     1.5: swap_santas
     1.5: select
     1.3: delete_at
main#none: (23.6)
    10.0: assignment
     7.7: new
     3.2: personal_santa
     2.8: firstname
     2.8: lastname
     1.4: email
     1.2: puts
     1.1: each
     1.1: assign_santas
     1.1: branch
"Total score = 64.3800571683191"

Es war mir eine Ehre euch gequält zu haben...

21.08.07

Noch viel zu lernen?!?

Da bin ich grade über folgenden Ruby-Code zum Thema "Secret Santas" gestoßen und war recht beeindruckt, wie kurz dieser ist:

class Array
  def shuffle!
    replace sort_by { rand }
  end
end

class SecretSanta
  include Enumerable

  def initialize(people)
    @from, @to = people.dup.shuffle!, people.dup
    assign!
  end

  def assign!
    @to.shuffle! until no_two_indices_are_alike
  end

  def each(&block)
    @from.zip(@to).each &block
  end

private
  def no_two_indices_are_alike
    all? { |a, b| a != b }
  end
end

s = SecretSanta.new(Person.find(:all))
# Print Secret Santa pairings
pp Hash[*s.to_a.flatten.map {|person| person.name}]

Nur verstehen tue ich bis jetzt wenig. Mal sehen, ob sich das in nächste Zeit ändert, aber abgesehen davon, bin ich kein Fan von solchem sehr kompakten Code. Ich weiss ja nicht ob Ruby-Spezialisten sowas auf anhieb lesen können (auch, wenn sie nicht wissen, welches Problem gelöst werden soll), aber ich könnte es nicht. IMHO ist lesbarer Code wesentlich besser, vor allem, was die Wartbarkeit angeht. Und wenn man dafür die doppelte Anzahl Codezeilen benötigt...

Oder ist ultrakompakter Quellcode erstrebenswert?

17.08.07

The secret santas on rails

Als erstes - zugegebenerweise recht kleines - Rails Projekt bin ich grade dabei die Secret Santa Anwendung mit Rails umzusetzen. Hauptsächlich um mal zu lernen, wie der ganze Krempel in Rails so zusammenhängt und um erste Erfahrungen an einem simplen Beispiel zu sammeln.

Und ich muss zugeben, da war ich bis jetzt schon gut beschäftigt. Eigentlich ist das ja eine kleine Anwendung, aber irgendwie hab ich schon für's Grundgerüst rel. lange gebraucht (wesentlich länger als für die reine Ruby Anwendung).

Meine Hauptprobleme waren erstmal weiter mit der Syntax klar zukommen (wann nehme ich person.id, wann :id zur Übergabe von Parametern etc. - ich weiss nicht, ob ich das schon 100%ig gerafft habe), wie ich richtig auf Zeilen oder Felder in meiner Datenbank zugreife (Stichwort .find) und wie er einen Datenbankabfrage aller Datensätze in einen Array packt (nämlich als Hash - also hat man einen Hash in einem Array - im Nachhinein schon logisch, aber man muss sich erstmal dran gewöhnen) und wie ich dann auf diesen zugreife.

Naja, die signifikanten Codeauschnitte sehen dann so aus:

Die Klasse einer Person:

class Person < ActiveRecord::Base  
  has_one :person

  #do you have a correct santa assigned?
  def has_correct_santa?
    lastname != Person.find(person_id).lastname
  end

  #can one person be the santa of other?
  def can_be_santa_of?(other)
    lastname != other.lastname
  end

  #return the object behind the person_id
  def personal_santa
    Person.find(person_id)
  end
end

Die Methode swap_santas:

#switches the two personal_santas of the passed people
  def swap_santas (person1, person2)
    person1.update_attribute("person_id", person2.person_id)
    person2.update_attribute("person_id", person1.person_id)
  end

Die Methode assign_santas:

#assigns each person his secret santa
  def assign_santas
    @people = Array.new
    @people = Person.find(:all)
    @santas = Array.new(@people)
    @people.each { |person| 
            person.person_id = 
@santas.delete_at(rand(@santas.length)).id #assigns santas randomly
            person.update_attribute("person_id", person.person_id)
          }

    @people.each { |person| 
      unless person.has_correct_santa?
        candidates = @people.select { |p| 
p.personal_santa.can_be_santa_of?(person)
 && person.personal_santa.can_be_santa_of?(p) } #finds possible candidates for a swap
        swap_santas(person, candidates[rand(candidates.length)])
      end
      }
    flash[:notice] = 'The secret santas have been assigned!'
    redirect_to :action => 'list'
  end

So funktioniert es im Moment auf jeden Fall, aber das ist keine gute Lösung. In dieser Version habe ich definitiv mehr Datenbankzugriffe als nötig sind. Ich sollte besser nur einmal die Daten aus der Datenbank holen und dann mit diesen Werten arbeiten bis die Partner korrekt zugewiesen sind und dann den Kram in die Datenbank zurückschreiben (so werden die Daten 2x geschrieben: einmal beim zufälligen zuweisen und dann nochmal bei der ggf. notwendigen Korrektur). Oder nicht?

Naja, ich denke das werde ich noch verbessern und mir dann auch mal angucken, wie das mit Stylesheets und Javascript in Rails gemacht wird.

Ruby und Rails Dokumentation

Über den rubyonrails.org-Blog habe ich diesen recht schicken API-Browser gefunden: http://www.noobkit.com/
Sieht auf jedenfall schonmal besser aus, als die jeweilige API selbst.

Ferner finde ich das Widget RubySearch von Brian Guthrie ganz hilfreich.

Es gibt auch noch ein weiteres Ruby-Widget, dieses benötigt allerdings ne Internet-Verbindung: Ruby RDoc Widget

Und hier noch ein nützliches Cheat-Sheet: Ruby On Rails Cheatsheet

16.08.07

Meine Checkliste zu: 10 Tipps für effizientes Arbeiten im Home Office

Im MitraBlog gibt's 10 Tipps für effizientes Arbeiten im Home Office.
Da ich im Moment haupsächlich von zu Hause aus arbeite fand' ich das recht interessant.

Hier meine Checkliste:

zu 1.: "Schreib Deine Ziele nieder"
Ok, mache ich sogar meistens, allerdings nicht nur Kram, der mit meinem Job zu tun hat, sondern auch Sachen wie "Essen", "Wäsche waschen", "Schlafen nicht vergessen" und so weiter... ;-)

zu 2.: "Steh früh auf"
Hm...ok meistens klappt das sogar.

zu 3.: "Schalt den IM und das Telefon aus"
Mache ich eigentlich nie. Als IM benutze ich fast eh ausschließlich Skype und da ist eh nie jemand online. ;-) Und per Telefon ruft mich eh selten wer an.
Ich glaube für mich sinnvoller wär ein Punkt mit dem Titel "Schalte Mail und deinen RSS-Reader aus"

zu 4.: "Vor der Arbeit Trainieren"
Hallo? Auf keinen Fall! Ich geh doch nicht jeden morgen erstmal joggen. Da bleib ich doch lieber ne halbe Stunde länger liegen, oder les' schonmal die ganzen neuen Nachrichten, die sich in meinem RSS-Reader über Nacht angesammelt haben.

zu 5.: "Aufgeräumtes Büro"
Naja, ab und zu räume ich mal auf, aber der Zustand hält dann meistens nicht allzu lange an. Aber seht selbst:

Home Office

zu 6.: "Musik"
Ja! Natürlich. Fast immer! Nur wenn ich einen längeren Artikel oder ein Buch lese, lenkt es eher ab.
Aber sonst...man geht ja niemandem mit seinem (Zitat:) "schrecklichen Krach" auf die Nerven.

zu 7.: "Tageszeitplan"
Man sollte einen Zeitplan wie im "richtigen" Büro aufstellen mit Mittagspause etc. So in der Art mache ich das auch. Wenn ich allerdings mal wieder etwas später aufgestanden bin, verschiebt sich das Ganze. Aber meistens gibt's doch zur Bill Cosby Show Mittagessen.

zu 8.: "Einfach loslegen"
Das sollte man auf jeden Fall tun! Sonst kommt man ja zur gar nix.

zu 9.: "Arbeit auch mal abgeben"
Da ich mein eigenes Projekt habe trifft der Punkt so gar nicht auf mich zu.

zu 10.: "Schliess die Türe"
Mache ich nie. Wenn meine Freundin arbeiten ist, bin ich sowieso alleine in der Wohnung. Von daher: alles im grünen Bereich.

Wie man sieht kann ich bestimmt noch etwas tun um meine Produktivität zu verbessern, aber bis jetzt komme ich ganz gut zurecht.

Hier nochmal der Link zu dem Artikel: 10 Tipps für effizientes Arbeiten im Home Office

So, und jetzt fang ich mal wieder an zu arbeiten!

(via)

14.08.07

Learning Ruby: The secret santas [Update]

Da ich grade dabei bin Ruby zu lernen, möchte ich mal ein kleines Programm zeigen und Probleme auflisten, die ich damit hatte.

Auf rubyquiz.com gibt es sehr viele Aufgaben, die man mit Ruby lösen kann und soll. Ich kann diese Seite nur empfehlen. Von dieser stammt auch das folgende Problem: Secret Santas.

Zu deutsch würde man das wohl als "Wichteln" bezeichnen. So werden gegenseitig zufällig Wichtelpartner zugeordnet. Die Einschränkung ist, dass Personen aus der selben Familie nicht gegenseitig zugeteilt werden dürfen.

Nachdem ich das Grundgerüst relativ schnell stehen hatte und zumindest teilweise das Problem mit den gleichen Nachnamen gelöst hatte, bestand am Ende das Problem, dass manchmal noch eine Person zugeteilt werden musste, diese aber den gleichen Nachnamen hatte, wie die Person, der noch der Wichtelpartner fehlte.

So habe ich mich auf die Suche nach einer Lösung gemacht, und meinte das Problem mathematisch lösen zu können/müssen (Stichwort: Permutationen).

Nachdem ich absolut nicht auf den grünen Zweig gekommen bin, habe ich dann doch mal in die Lösung geguckt. Eine elegante Lösung ist der Hill Climbing Algorithmus. Hier werden die Wichtelpartner zunächst einfach zufällig zugewiesen und am Ende wird die Liste der Personen mit ihren Partnern durchgegangen und ggf. falsche Übereinstimmungen (gleicher Nachname) durch vertauschen der jeweiligen Partner gelöst.

Also war's doch etwas unkomplizierter, als ich es mir vorher vorgestellt hatte. Meine Lösung:

[Update:] Bei der Suche nach geeigneten Kandidaten für einen Tausch der Partner, muss auf jeden Fall noch folgender Ausdruck nach dem && hinzugefügt werden:

people.select { |p| p.personal_santa.can_be_santa_of?(person)
&& person.personal_santa.can_be_santa_of?(p) }

Ansonsten kann es trotzdem vorkommen, dass falsche Wichtelpartner zugeordnet werden.

class Person
  attr_writer :personal_santa
  attr_reader :firstname, :lastname, :email, :personal_santa

  def initialize (firstname, lastname, email)
    @firstname = firstname
    @lastname = lastname
    @email = email
  end

  def can_be_santa_of?(other)
    @lastname != other.lastname
  end
end

#switches the two personal_santas of the passed people
def swap_santas (person1, person2)
  temp = person1.personal_santa
  person1.personal_santa = person2.personal_santa
  person2.personal_santa = temp  
end

#assigns each person his secret santa
def assign_santas(people, santas)
  people.each { |person| person.personal_santa = santas.delete_at
(rand(santas.length)) } #assigns santas randomly
  people.each { |person| 
    unless person.personal_santa.can_be_santa_of? person
      #finds possible candidates for a swap
      candidates = people.select { |p|
p.personal_santa.can_be_santa_of?(person)
&& person.personal_santa.can_be_santa_of?(p) }
      swap_santas(person, candidates[rand(candidates.length)])
    end
    }
end

person1 = Person.new("Daniel","Pietzsch","[email protected]")
person2 = Person.new("...") #parameter in the above format
person3 = Person.new("...")
person4 = Person.new("...")
person5 = Person.new("...")
person6 = Person.new("...")

people = [person1, person2, person3, person4, person5, person6]
santas = Array.new(people) #Copy of the people array

assign_santas(people, santas) #assigns each person his secret santa

#output
people.each {|person| puts "#{person.firstname} #{person.lastname}:
<#{person.email}>\nPersonal Santa: #{person.personal_santa.firstname}
#{person.personal_santa.lastname}\n\n"}

04.08.07

Getting Real

Hm...da surft man so, durch Blinksale und Ruby On Rails bedingt, auch mal über die Seiten von 37signals.com und findet über nen kleinen Umweg in deren Blog sehr interessante Artikel zum Thema "Getting Real".
Was die Jungs damit meinen ist im Prinzip ein komplett umgekehrtes Konzept zum Thema Software-Development bei dem man mit dem User Interface anfängt und am Ende erst die Logik programmiert. Also quasi genau das Gegenteil von dem, was ich hier grade fabriziere...

Sehr spannendes Thema auch wenn ich mir etwas sorgen mache, dass ich irgendwie nix mitbekomme: die Artikel sind von 2005!

Getting Real Artikel: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 und wahrscheinlich gibt's noch mehr Artikel zu dem Thema...

03.08.07

Blinksale!

blinksale.png

Ich habe mir einen Account bei Blinksale eingerichtet. Blinksale ist eine Online-Verwaltung von Rechnungen und für mich (und wahrscheinlich auch für euch) definitiv einen Blick wert! (Hauptsache, ich werde jetzt nicht arbeitslos ;-) )

Die Anwendung wurde in Ruby On Rails geschrieben und somit eine gute Inspirationsquelle, auch wenn man an den Code selbst natürlich nicht rankommt. Aber was die Oberfläche und einige Zusammenhänge angeht ist das definitiv interessant, weil es zumindest teilweise das macht, was ich umzusetzen versuche.

Ich bin grade dabei da ein bisschen rumzuprobieren um zu gucken, wie die was so umgesetzt haben.
Der Ausdruck sieht schonmal nicht schlecht aus.

http://www.blinksale.com

ER-Diagramm: Bestellungen/Aufträge

Meine nächste Version des ER-Diagramms ist fertig: ER-Diagramm Version 0.4

Neu hinzu gekommen sind die Bestellungen/Aufträge. Die Daten werden hier manuell von der Bestellung des Kunden übertragen. Zusätzlich soll man den Auftrag aber auch als PDF anhängen können.
Mein Beispielauftrag bezieht sich auf ein bestimmtes Angebot, daher die Beziehung zu den Angeboten. Oder kann sich eine Bestellung sogar gelichzeitig auf mehrere Angebote beziehen?
Jetzt habe ich noch ne Frage zu der Beziehung zu den Projekten: muss diese Beziehung wirklich bestehen, oder wäre das doppelt gemoppelt? Ein Auftrag hat ja - soweit ich weiss - auch immer Bezug zu einem speziellen Projekt.

Die Entität "Mitarbeiter" hat noch ein weiteres Feld "Einsicht" bekommen für Mitarbeiter, die Einsicht in die Rechnungen haben sollen (was wohl im Moment Stefan, Phillip, Thomas und Ulf sind).

Wie man sieht, wird das Modell etwas unübersichtlich. Ich werde zusehen, dass ich die nächste Version mal geordneter darstelle...

About

DanielHi. I'm Daniel Pietzsch and this is my innoQ-Blog. I'm a 26y old student at FH Bochum and working student at innoQ.
In this blog I mainly write about the progress concerning my diploma thesis which will be an in-house application for innoQ based on Ruby on Rails, but some other (geek) stuff might appear here, too.

daniel [dot] pietzsch [alt-L] innoq [dot] com

I recommend

Categories

Recent Comments

License

Creative Commons License This weblog is licensed under a Creative Commons License.
Powered by
Movable Type 3.31