Ruby <-> Python

Alles, was nicht direkt mit Python-Problemen zu tun hat. Dies ist auch der perfekte Platz für Jobangebote.
BlackJack

Beitragvon BlackJack » Dienstag 12. September 2006, 07:24

@jens: Das Python äquivalent zu ``if obj.nil?`` ist ``if obj is None``.

Ob die beiden Varianten undurchsichtig sind, hängt von Erfahrungen in anderen Spachen ab.

Das jedes Objekt eine `isNil` Methode hat, die nur beim `Nil` Objekt (Singleton) wahr zurückgibt und bei allen anderen falsch, ist in Smalltalk-ähnlichen Sprachen üblich. Finde ich auch nicht unbedingt schlecht; die Idee alles mit Methoden zu lösen ist eine interessante Möglichkeit. Auf dem Konzept aufbauend, kann man eine Sprache schön einfach halten und zum Beispiel auch ``if`` und Schleifen als Methoden implementieren. So lässt sich die Anzahl der Schlüsselworte in einer Sprache auf ein Minimum reduzieren. Was mich an der ersten Variante stört ist der "Perlismus" mit dem ``if``, das man an verschiedenen Stellen schreiben kann.

Die zweite Variante ist der allseits beliebte Ternäroperator aus C/Java/C# etc. So etwas hässliches bekommen wir mit Python 2.5 ja auch vorgesetzt. Das ist eine der beiden Entscheidungen von Guido, die ich absolut furchtbar finde. Die andere ist diese Inkonsistenz bei `sum()` und Zeichenketten. Über die Dekoratorsyntax bin ich mittlerweile hinweggekommen. :-)

@Zambo: Schön das Du Dich darum drückst einen Default-Parameter in Deinen Quelltext einzubauen der jeden beliebigen Wert annehmen kann und eine Ausnahme falls das Ergebnis `nil` ist und kein Default gesetzt wurde. Du hast gesagt das sieht in Python viel zu aufwändig aus, dann möchte ich das doch gerne mal mit äquivalentem Ruby vergleichen können.
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Dienstag 12. September 2006, 07:31

BlackJack hat geschrieben:@jens: Das Python äquivalent zu ``if obj.nil?`` ist ``if obj is None``.

Das hatte ich vermutet. Aber da ich Ruby nicht kenne und es auch nicht wirklich darum geht, hatte ich einfach "nil" (als String) übernommen...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Zambo
User
Beiträge: 9
Registriert: Montag 11. September 2006, 06:48
Wohnort: Düsseldorf
Kontaktdaten:

Beitragvon Zambo » Dienstag 12. September 2006, 08:32

Hallo BlackJack,

ich habe den Default-Parameter nicht eingebaut, weil ich ihn überflüssig finde. Aber wenn du umbedingt eine 1 zu 1 übersetzung haben willst:

Code: Alles auswählen

def my_sum(iterable,default=nil)
  ergebnis = iterable.inject { |v,n| v+n }
 
  if ergebnis.nil? then 
    raise "empty iterable without default" if default.nil?
    return default
  else
    return ergebnis
  end
end

print my_sum(['H', 'a', 'l', 'l', 'o'])     # -> 'Hallo'
print my_sum(1..5)                          # -> 15
print my_sum([],0.0)                        # -> 0.0
print my_sum('')                            # -> Raises Exception.


Meiner Meinung nach ist das Programm immer noch um einiges verständlicher als

Code: Alles auswählen

import operator

NO_DEFAULT = object()

def my_sum(iterable, default=NO_DEFAULT):
    iterator = iter(iterable)
    try:
        first = iterator.next()
    except StopIteration:
        if default is NO_DEFAULT:
            raise TypeError('empty iterable without default')
        else:
            return default
    return reduce(operator.add, iterator, first)

print my_sum(('H', 'a', 'l', 'l', 'o')) # -> 'Hallo'
print my_sum(xrange(6))                 # -> 15
print my_sum([], 0.0)                   # -> 0.0
print my_sum('')                        # Raises Exception.


Aber mal davon abgesehen. Du hast glaube ich den Anfang unserer Unterhaltung vergessen. Ich habe dir ein Beispiel gezeigt, wie ich die inneren Klassen von Ruby durch Mix-Ins erweitert habe. Du hast mir bis jetzt kein Beispiel in Python zeigen können, dass das kann?

Gruß
Zambo
Zuletzt geändert von Zambo am Dienstag 12. September 2006, 11:09, insgesamt 1-mal geändert.
Benutzeravatar
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Beitragvon mitsuhiko » Dienstag 12. September 2006, 11:04

Zambo hat geschrieben:Meiner Meinung nach ist das Programm immer noch um einiges verständlicher als ...

Tut auch was anders.... :roll:

Dein Quelltext sieht in Python so aus:

Code: Alles auswählen

def my_sum(iterable, default=None):
    try:
        return reduce(lambda a, b: a + b, iterable)
    except TypeError:
        if default is None:
            raise ValueError('iterable required')
        return default


Zambo hat geschrieben:Aber mal davon abgesehen. Du hast glaube ich den Anfang unserer Unterhaltung vergessen. Ich habe dir ein Beispiel gezeigt, wie ich die inneren Klassen von Ruby durch Mix-Ins erweitert habe. Du hast mir bis jetzt kein Beispiel in Python zeigen können, dass das kann?


Für was include() wenn du Mixin Klassen in Python hast? Schau dir einfach mal in SimpleHTTPServer um, da findest du beispielsweise Threadin Mixins. Es gibt in Python einfach keine Verwendung für include() weil wir keine Verkrüppelte Vererbung haben :D
Aber wie ich dir gezeigt habe kann man wunderbar ein include() für Python nachbauen. :roll:

@jedie: das then kannst du in Ruby fallen lassen
TUFKAB – the user formerly known as blackbird
Zambo
User
Beiträge: 9
Registriert: Montag 11. September 2006, 06:48
Wohnort: Düsseldorf
Kontaktdaten:

Beitragvon Zambo » Dienstag 12. September 2006, 11:32

blackbird hat geschrieben:
Zambo hat geschrieben:Meiner Meinung nach ist das Programm immer noch um einiges verständlicher als ...

Tut auch was anders.... :roll:


Ach ja :?

blackbird hat geschrieben:Dein Quelltext sieht in Python so aus:

Code: Alles auswählen

def my_sum(iterable, default=None):
    try:
        return reduce(lambda a, b: a + b, iterable)
    except TypeError:
        if default is None:
            raise ValueError('iterable required')
        return default



Das ist auch eine Möglichkeit.

blackbird hat geschrieben:Für was include() wenn du Mixin Klassen in Python hast? Schau dir einfach mal in SimpleHTTPServer um, da findest du beispielsweise Threadin Mixins. Es gibt in Python einfach keine Verwendung für include() weil wir keine Verkrüppelte Vererbung haben :D
Aber wie ich dir gezeigt habe kann man wunderbar ein include() für Python nachbauen. :roll:


Ich glaube du willst einfach nicht verstehen, das es Vorteile haben kann, die interne Klassenstruktur von einer Programmiersprache zu erweitern. Aber jetzt habe ich echt keine Lust mehr zu schreiben. Schaut euch Ruby einfach mal an. Es ist wirklich eine sehr einfache, klare und gute Programmiersprache und wer noch was wissen will, kann mir gerne eine Nachricht schicken.
Benutzeravatar
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Beitragvon mitsuhiko » Dienstag 12. September 2006, 12:28

Zambo hat geschrieben:
blackbird hat geschrieben:
Zambo hat geschrieben:Meiner Meinung nach ist das Programm immer noch um einiges verständlicher als ...

Tut auch was anders.... :roll:


Ach ja :?

Ja :evil:

Zambo hat geschrieben:Das ist auch eine Möglichkeit.

Das ist dein Quelltext. Das was BlackJack gemacht hat sieht in Ruby so aus:

Code: Alles auswählen

NO_DEFAULT = Object.new

def my_sum iterable, default=NO_DEFAULT
  result = iterable.inject { |a, b| a + b }
  if result.nil?
    if default === NO_DEFAULT
      raise 'empty iterable without default'
    end
    default
  end
  result
end


Wobei das auch nicht ganz richtig ist. Da Ruby keine Iteratoren als solches kennt und "for i in iterable" das gleich ist wie "iterable.each { |i| }" kann ich nicht das erste Element anfordern wie BlackJack das mit seinem Python Code gemacht hat. Das heißt BlackJacks Code sieht jetzt etwa so aus:

Code: Alles auswählen

NO_DEFAULT = object()

def my_sum(iterable, default=NO_DEFAULT):
    try:
        return reduce(lambda a, b: a + b, iterable)
    except TypeError:
        if default is NO_DEFAULT:
            raise TypeError('empty iterable without default')
        return default


Zambo hat geschrieben:Ich glaube du willst einfach nicht verstehen, das es Vorteile haben kann, die interne Klassenstruktur von einer Programmiersprache zu erweitern. Aber jetzt habe ich echt keine Lust mehr zu schreiben. Schaut euch Ruby einfach mal an.

Hab ich schon getan. Ich lästere nicht über Programmiersprachen von denen ich keien Ahnung habe.

Zambo hat geschrieben:Es ist wirklich eine sehr einfache, klare und gute Programmiersprache und wer noch was wissen will, kann mir gerne eine Nachricht schicken.

Ich finde sie weder einfach, noch klar. Ich gebe zu das Ruby auch Tolle Dinge hat: Blöcke, die ich in python gerne als Syntax für anonyme Funktionen hätte, Regexes mit hilfe von // statt re.compile() zu erstellen aber das wars auch schon. Ruby regt mich schon deswegen auf weil es keine Klammern hat. Manche mögen das an Ruby toll finden, mich schränkt es ein weil ich Die Klasse eine Funktion nur durch den Class.method(:name) Umweg bekomme. Auch fehlt mir die Unicode Unterstützung, die Iteratoren und Generatoren.
TUFKAB – the user formerly known as blackbird
BlackJack

Beitragvon BlackJack » Mittwoch 13. September 2006, 13:37

Zambo hat geschrieben:Ich glaube du willst einfach nicht verstehen, das es Vorteile haben kann, die interne Klassenstruktur von einer Programmiersprache zu erweitern.


Ich verstehe das. Und bin in anderen Sprachen auch schon drüber gestolpert, nämlich genau dann, wenn man zwei Bibliotheken hat, die beide der Meinung sind, ein `Integer` müsste eine `foo()` Methode haben.

Wobei das in Python keine Einschränkung von der Sprachspezifikation ist, sondern von der Implementierung in CPython. Die Spezifikation verbietet das Setzen von zusätzlichen Attributen bei den Grunddatentypen nicht.

Schaut euch Ruby einfach mal an. Es ist wirklich eine sehr einfache, klare und gute Programmiersprache [...]


Es gibt einfachere und klarere. Von der Syntax her ist Python einfacher und konsistenter was das Verhalten von Typen und Sprachkonstrukten angeht. Unter den Smalltalk-ähnlichen Programmiersprachen gibt es auch wesentlich einfachere und konsistentere, z.B. Io.
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Freitag 27. Oktober 2006, 07:49

Passt jetzt nicht so super hier rein, aber fast.

Unter http://wiki.ubuntuusers.de/Perl steht u.a. das von Perl:

Durch die vorherige Kompilation in Bytecode werden jedoch Syntaxfehler und andere Fehler vor der Ausführung des Skriptes gefunden. Weiterhin wurden schon einige Optimierungen vorgenommen. Wenn man einen Ausdruck wie "10*1024*1024*1024*8" schreibt, um z.B. 10GB in Bit darzsutellen, dann berechnet Perl diesen Ausdruck bloß einmal. Auch Kommentare werden in diesem Zwischencode heraus gefiltert. Bei einer reinen interpretierten Sprache müsste dieser Ausdruck immer wieder neu berechnet werden, sobald der Interpreter diese Zeile erreicht. Jedesmal, wenn der Interpreter eine neue Zeile einliest, muss er erkennen, ob es sich um ein Kommentar handelt, was Performance kostet. Bei Perl müssen man sich um solche Dinge keine Gedanken machen und kann auch Kommentare innerhalb von Schleifen setzen, ohne das die Performance darunter leidet.

Im grunde macht alles das Python auch, insbesondere den fett gedrukten Teil... oder nicht?

Wenn man die Wikiseite bei ubuntuusers liest, hört sich Perl sogar gut an... Naja, vielleicht doch nicht so richtig... :wink:

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Beitragvon BlackJack » Freitag 27. Oktober 2006, 08:09

Diese Optimierung ist relativ neu. Python 2.4.3:

Code: Alles auswählen

In [4]: def f():
   ...:     return 10*1024*1024*1024*8
   ...:

In [5]: dis.dis(f)
  2           0 LOAD_CONST               1 (10)
              3 LOAD_CONST               2 (1024)
              6 BINARY_MULTIPLY
              7 LOAD_CONST               2 (1024)
             10 BINARY_MULTIPLY
             11 LOAD_CONST               2 (1024)
             14 BINARY_MULTIPLY
             15 LOAD_CONST               3 (8)
             18 BINARY_MULTIPLY
             19 RETURN_VALUE


Python 2.5b2:

Code: Alles auswählen

>>> def f():
...     return 10*1024*1024*1024*8
...
>>> dis.dis(f)
  2           0 LOAD_CONST               7 (85899345920L)
              3 RETURN_VALUE
rolgal_reloaded
User
Beiträge: 309
Registriert: Dienstag 24. Oktober 2006, 19:31

Beitragvon rolgal_reloaded » Dienstag 14. November 2006, 20:58

Also mich hat bei Ruby das end genervt.

Wo kein begin, da braucht es auch kein end. Wie man an Python sieht braucht es auch kein begin, daher konsequneterweise auch kein end :D

Wie nennt man das Sprachdesign?
Wie auch immer, es gefällt mir bei Ruby nicht.

Zum Thema Mixins, den Sinn habe ich nicht sofort verstanden, das Prinzip der Mehrfachvererbung (das wird ja gerne miteinander verglichen) hingegen sofort (heisst nicht dass ich OOP sofort insgesamt verstehen im Sinne von anwenden konnte).

Liebe Grüße

rolgal_reloaded
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Samstag 18. November 2006, 16:51

rolgal, genau diese end hat mich schon immer genervt (z.B. bei Basic). Dan lieber geschweifte Klammern.

Code: Alles auswählen

int main ()
{
}


Aber die beste Lösung ist die von Python das Einrückung ein Bestandteil der Syntax ist. :)

Aber wie immer alles reine Geschmacksachen ;)

lg
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Samstag 18. November 2006, 17:32

Naja, das 'End' ist in Turbo Pascal schlimmer, dort gibt es sogar zwei Variationen davon: 'End' und 'End.' (also mit Punkt hintendran).
My god, it's full of CARs! | Leonidasvoice vs Modvoice
BlackJack

Beitragvon BlackJack » Samstag 18. November 2006, 17:54

Es gibt nur ein ``End``, der Punkt beendet das Programm.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Beitragvon Y0Gi » Montag 20. November 2006, 16:25

Was an Ruby mit @, @@, {|x| x}, :foo und dergleichen leicht oder auch nur leichter verständlich sein soll, bleibt mir schleierhaft. Dieses Sonderzeichenmassaker ist genau das, was ich an Perl schon nicht leiden konnte (=~ und Regex als /foo/ gehören auch dazu).

Python kann man für nicht allzu extreme Fälle hervorragend als Pseudocode benutzen, bei Ruby scheitert man da schon, sobald z.B. OOP ins Spiel kommt. Ich wüsste gerne mal, wieviele Monate die ganzen Java-Leute für den Einstieg in Ruby gebraucht haben, die momentan alle Rails so hypen.

IMHO ist eine Programmiersprache letztlich nur so gut wie der Zugang zu ihr. Und ohne Rails, das als durchdachtes Framework mit vielen Konventionen und Helpern glänzt, dürfte da langfristig nicht ausreichen.
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Montag 20. November 2006, 17:28

Wie ich schon unter http://www.python-forum.de/post-49671.html#49671 geschrieben hab, können wir nun eine "Gegenseite" aufbauen:

[wiki]von Ruby zu Python[/wiki]

Also bitte loslegen und dort fleißig Fakten sammeln :lol:

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder