Python-Spickzettel für PHP-Entwickler

Gute Links und Tutorials könnt ihr hier posten.
marcel.normann
User
Beiträge: 5
Registriert: Montag 10. April 2006, 17:29
Wohnort: Kirchen (Sieg)
Kontaktdaten:

Hallo!

Ich habe ein kleines Spickzettel-PDF erstellt, in dem die meiner
Meinung nach wichtigsten Unterschiede, Fallstricke und Standardfunktionen dokumentiert sind. Ich selbst habe während meiner Einstiegsphase in Python immer wieder nach diesen Schnipseln gesucht, möge es zukünftigen Einsteigern eine kleine Hilfe sein:

http://www.experimentierkasten.de/python_php.pdf (~120 KB)

Ich bitte um Korrekturen und Erweiterungsvorschläge. Was für meinen
Geschmack jetzt schon fehlt, ist die Anlage assoziativer Arrays. Insgesamt soll das Dokument nicht grösser als eine Doppelseite Din-A4 werden, aber bis jetzt ist mit einer Seite noch genug Platz für Ergänzungen.

Danke und Gruß,
Marcel
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Ich finde das cool.
Ich habe keine ahnung wie "pythonic" es ist, aber mir gefällt die Zuweisung von Werten in ein Tupple ohne die Klammern nicht.

Bei den Rechenproblemen halte ich es auch für stilvoller die Null aus zu schreiben: 7.0/4.0


OT:
wäre lustig sowas auch für Python - Ruby bzw Python - Perl zu haben.

Edit:
Wie unhöflich von mir - herzlich willkommen im Forum!
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Auch von mir erstmal ein Herzliches Willkommen!
Mr_Snede hat geschrieben: OT:
wäre lustig sowas auch für Python - Ruby bzw Python - Perl zu haben.
Ich fände sowas für Pythn-C/C++ sehr gut!
mfg

Thomas :-)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

marcel.normann hat geschrieben:Ich bitte um Korrekturen und Erweiterungsvorschläge.
Hi Marcel!

Nette Seite, aber die Wahrheitswerte würde ich anders beschreiben:

Falsch:
0; False; ""; []; (); {}

Richtig:
Alles was nicht *Falsch* ist:
-3; 1; 2; 3; True; "asdf"; [0]; (0); {0: 0}

mfg
Gerold
:-)

Edit: Sorry, hatte einen Beistrich zu viel.
Zuletzt geändert von gerold am Montag 10. April 2006, 22:03, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
marcel.normann
User
Beiträge: 5
Registriert: Montag 10. April 2006, 17:29
Wohnort: Kirchen (Sieg)
Kontaktdaten:

Danke erst mal an alle für die Willkommensgrüsse.
Mr_Snede hat geschrieben:...aber mir gefällt die Zuweisung von Werten in ein Tupple ohne die Klammern nicht.
Mir gefällt die Version mit Klammern nicht, weil hier dieses seltsame Komma am Ende auftaucht. PHP-Umsteiger kennen den Unterschied zwischen Tupel/Liste ja garnicht, deshalb fand ich es sinnvoll, die gängigen Methoden aufzuschreiben.
Mr_Snede hat geschrieben:Bei den Rechenproblemen halte ich es auch für stilvoller die Null aus zu schreiben: 7.0/4.0
Ich werde es als zusätzliche Schreibweise aufnehmen.
gerold hat geschrieben:Falsch:
0; False; ""; []; (,); {}

Richtig:
Alles was nicht *Falsch* ist:
-3; 1; 2; 3; True; "asdf"; [0]; (0); {0: 0}
Sicher?

>>> False == 0
False
>>> True == ""
False

Oder habe ich jetzt was falsch verstanden?

Mal gucken wie ich das mit dem Platz mache. Für eine Doppelseite habe ich viel zu wenig, für eine einzelne Seite etwas zuviel. Die assoziativen Arrays sollen aber auf jeden Fall noch mit rein. Vielleicht nehme ich beim PHP-Code die if-Klammern raus, was ich eigentlich sehr hässlich finde.

Mal eine Frage nebenbei: Gibt es eigentlich in Pyhton Ternär-Operatoren, also sowas wie:

echo ('a' == 'a' ? 'a' : 'b');

?

Gruß, Marcel
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Oder habe ich jetzt was falsch verstanden?
Ja.

Python vergleicht bei einem Vergleich nicht den Wahrheitswert des Objekts, sondern die Objekte selbst. Das Objekt False ist sicherlich nicht gleich dem Objekt leere Zeichenkette (besser gesagt, es hat sicherlich nicht den gleichen Wert, der Vergleich ob es das selbe Objekt ist wird mittels is gemacht).

Beide sind aber, als Wahrheitswert ausgewertet, falsch.

Was Du aber machen kannst um rauszufinden was für einen Wahrheitswert ein Objekt hat:

Code: Alles auswählen

print bool(False)
print bool("")
print bool([])
...
oder aber:

Code: Alles auswählen

if "":
    print "True"
else:
    print "False"
Ersetze im letzten Beispiel "" durch ein Objekt Deiner Wahl das Du testen willst.

Zum ternären Operator: Ja und nein.

Einen ternären Operator per se gibt es nicht, es gibt aber eine ganze Menge Möglichkeiten (also Idiome) etwas derartiges zu schreiben. Zum Beispiel:

Code: Alles auswählen

x = 1
print x and "wahr" or "falsch"
print ["falsch","wahr"][bool(x)]
print {False:"falsch",True:"wahr"}[bool(x)]
print [lambda:"falsch",lambda:"wahr"][bool(x)]()
Wobei nur der erste und letzte Short-Circuting sind, und der erste _nur_ funktioniert wenn der Wahrheitswert von "wahr" selbst wahr ist, sprich folgendes geht nicht (beziehungsweise liefert nicht das gewünschte Ergebnis):

Code: Alles auswählen

x = 1
print x and 0 or 1
liefert immer 1, weil das "wahr"-Objekt in diesem Beispiel selbst falsch ist, also x and 0 niemals wahr werden kann.
--- Heiko.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

marcel.normann hat geschrieben:Sicher?

>>> False == 0
False
>>> True == ""
False

Oder habe ich jetzt was falsch verstanden?
Bis ptyhon2.3 gabs gar kein True/False. Da wurde einfach ein objekt auf länge > 0, obj.__nonzero__() == 1 ausgewertet.
Mal eine Frage nebenbei: Gibt es eigentlich in Pyhton Ternär-Operatoren, also sowas wie:

echo ('a' == 'a' ? 'a' : 'b');
ja und nein.

In python2.5 gibts welche (ich glaub schon implementiert), aber es gibt folgende "Lösung":

Code: Alles auswählen

>>> True and "TRUE" or "FALSE"
'TRUE'
>>> False and "TRUE" or "FALSE"
'FALSE'
Solange der wert nach "and" nicht false ist, funktioniert es wie gewünscht.
TUFKAB – the user formerly known as blackbird
marcel.normann
User
Beiträge: 5
Registriert: Montag 10. April 2006, 17:29
Wohnort: Kirchen (Sieg)
Kontaktdaten:

modelnine hat geschrieben:Python vergleicht bei einem Vergleich nicht den Wahrheitswert des Objekts, sondern die Objekte selbst. Das Objekt False ist sicherlich nicht gleich dem Objekt leere Zeichenkette (besser gesagt, es hat sicherlich nicht den gleichen Wert, der Vergleich ob es das selbe Objekt ist wird mittels is gemacht).
Man lernt nie aus. Danke für den Tipp. PHP castet bei solchen Vergleichen ziemlich freizügig - was ich in der Regel kofortabel finde, jedoch auch zu unerwünschten Ergebnissen führen kann.

Ich lasse die Liste aber wahrscheinlich trotzdem in der jetzigen Form, da es mir vor allem um die korrekte Groß-/Kleinschreibung der beiden Werte geht.

Gruß, Marcel
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

PHP castet bei solchen Vergleichen ziemlich freizügig - was ich in der Regel kofortabel finde, jedoch auch zu unerwünschten Ergebnissen führen kann.
Jupp. Man sagt deswegen auch dass Python stark und dynamisch typisiert ist, während PHP (und auch Perl) schwach und dynamisch typisiert sind.

Im Endeffekt kannst Du bei Python davon ausgehen dass eine Typkonversion (außer bei Zahlen) niemals ohne Dein direktes Eingreifen stattfinden wird.
--- Heiko.
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

marcel.normann hat geschrieben:
Mr_Snede hat geschrieben:...aber mir gefällt die Zuweisung von Werten in ein Tupple ohne die Klammern nicht.
Mir gefällt die Version mit Klammern nicht, weil hier dieses seltsame Komma am Ende auftaucht.
Habe selber nie ein Komma am Ende benutzt:

Code: Alles auswählen

>>> mytuple = ('a','b','c')
>>> mytuple
('a', 'b', 'c')
Edit:
Im Python Tutorial werden Tuples ohne Komma am Ende verwendet:
http://docs.python.org/tut/node7.html#S ... 0000000000
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Der einzige Ort wo man mit einer Klammer abschließen muß ist wenn man ein Tupel der Länge eins haben will:

Code: Alles auswählen

print repr(("hello"))
print repr(("hello",))
Die Klammern haben in Python nämlich einmal die Bedeutung eine Berechnung zu gruppieren (also Präzedenz zu verteilen), und zum anderen die Bedeutung dass ein Tupel daraus gemacht wird. Sonst, wenn man ein Tupel erstellen will, ist es gute Praktik immer Klammern zu verwenden. Ohne Klammern macht man eigentlich nur wenn man direkt Tupel-Unpacking verwenden will, wie zum Beispiel in:

Code: Alles auswählen

x, y = y, x
um zwei Variablen zu vertauschen.

Ein (halbwegs abschreckendes) Beispiel für Tupel-Entpacken:

http://www.python-forum.de/post-34778.html#34778
--- Heiko.
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Das Komma taucht nur auf, wenn das Tupel nur ein Wert besitzt, weil es sonst ein String wäre:

Code: Alles auswählen

a=('a',)
b=('b')
type(a)
(type 'tupel')
type(b)
(type 'str')
/edit: Oh ich sehe gerade Modelnine war etwas schneller! :)
mfg

Thomas :-)
marcel.normann
User
Beiträge: 5
Registriert: Montag 10. April 2006, 17:29
Wohnort: Kirchen (Sieg)
Kontaktdaten:

Dafür liebe ich Python: Jeden Tag entdeckt man etwas, womit man seinen Code noch pythonischer machen kann :D

Das letzte Komma beim Tuple nehme ich dann raus, ansonsten lasse ich beide Schreibweisen drin. Vielleicht nehme ich sogar nochg ein Tuple mit einem Element hinzu.

Das PDF hat natürlich keinerlei Anspruch in irgendeiner Weise komplett zu sein. Es soll nur PHP-Entwicklern eine erste Hilfe an die Hand geben, um erste kleine Codebröckchen zu schreiben. Die dargestellten Lösungen sollten einerseits PHP-nah sein, aber gleichzeitg auch auf Pyhton-Leckerlies hinweisen.

Gruß, Marcel


Edit: Die neue Version ist unter gleicher URL online
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

So, ein paar kleine Korrekturen/Ergänzungen noch:

1)

print "abcd".replace("a","b") ---> # bbcd

2)

Rechenprobleme ist falsch. Sollte eher sowas wie "Integer-Division" heißen (bei der Python aus historischen Gründen die Typen nicht promoviert ---> float, wenn das Ergebnis nicht in einen Integer passt).

3)

print "Die Zahl ist %s" % (zahl,) hat nichts mit Zeichenverkettung zu tun, sondern bemüht den String-Formatting-Operator von Python (eben das %), der ähnlich wie printf("blah %s, %s",blubb,blubb) in C funktioniert, wobei %s bedeutet dass das Objekt zuerst mittels str(zahl) in einen String gecastet wird bevor es eingefügt wird, es gibt aber zum Beispiel %f um Floats zu formatieren, %i um Integer zu formatieren, etc. Unabhängig davon gibts in Python auch nichts vergleichbares wie "blah $blubb hastenichgesehen" in PHP; das geht eben nur über String-Formatting, womit ich %s in Python am ehesten vergleichen würde.

4)

+= ist im Normalfall ungleich .=, die Äquivalenz gilt nur für Zeichenketten. Denn "$a .= $b;" in PHP für zwei Zahlen liefert eine String-Konkatenation der beiden Zahlen, während in Python einfach die Summe der beiden Zahlen bei "a += b" gebildet wird und an a gebunden ist.

5)

'''
blah
'''

ist kein mehrzeiliger Kommentar, sondern einfach ein mehrzeiliger String. Da Du ihn nichts zuweist fungiert er wie ein Kommentar, es sollte aber irgendwie klarer herauszustellen sein dass ''' ''' identisch ist mit """ """ (so wie " und ' in Python für Strings absolut identisch sind, man benutzt den einen wenn man den anderen schreiben will, sprich es gibt keine Unterschiede beim Escaping zwischen den beiden Arten der String-Schreibweise, dafür gibts Präfixe wie u"" für Unicode-Strings, und r"" für "Rohe-Strings", die sich mehr oder weniger wie Strings ohne Escaping-Regeln verhalten).

6)

for-Schleife: Python besitzt keine Zählschleife, Python besitzt nur so etwas was ich Iterator-Schleife nennen würde (also was über alle Elemente eines gegebenen Objekts iteriert). range(5) -> [0,1,2,3,4] (also die Liste mit den Elementen 0-4), und über diese Liste wird iteriert, ein Element nach dem anderen. Ganz allgemein kann man über viele Dinge iterieren, wie zum Beispiel:

for x in "hello":
print x

Oder auch:

for x in {"blah":"blubb","asta":"lavista","baby":"!"}:
print x

(ausprobieren ;-) !) Diesen massiven Unterschied sollte man sinnigerweise irgendwie darstellen würde ich mal sagen...

7)

Wahrheitswerte vergleicht man in Python nicht. Sondern, man benutzt logische Operatoren. Wenn zum Beispiel gefragt ist dass zwei Objekte wahr sind, dann benutzt man "and", wenn eines der beiden mindestens wahr sein soll "or", oder eben auch not.

8 )

Soweit ich weiß heißt das Ding nicht Trinitäts-Operator, sondern auch auf Deutsch Ternärer Operator, einfach weil er drei Argumente nimmt.

Wenn mir noch was einfällt poste ich es gerne (wenn Du noch was hören magst ;-)), und nimm mir das viele Geschreibsel nicht übel; ich weiß dass es teilweise nicht für so einen Cheatsheet geeignet ist, aber vielleicht lässt sich trotzdem was davon integrieren, eben weil Python in einigen/vielen Dingen eine komplett andere Philosophie als PHP verfolgt, und man sowas durchaus rausstellen sollte aus meiner Sicht.
--- Heiko.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

modelnine hat geschrieben:Unabhängig davon gibts in Python auch nichts vergleichbares wie "blah $blubb hastenichgesehen" in PHP; das geht eben nur über String-Formatting, womit ich %s in Python am ehesten vergleichen würde.
Doch, seit PEP 292 (= Python 2.4) hat Python etwas vergleichbares, die Template-Strings. Verhält sich wie eben ein sehr simples Templating-System. Es ist zwar nicht exakt gleich wie z.B "Der Wert ist #{value}" in Ruby-Strings zum Beispiel, aber vergleichbar.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Doch, seit PEP 292 (= Python 2.4) hat Python etwas vergleichbares, die Template-Strings.
Stimmt. Nur, da sie nicht intrinsisch in der Sprache eingebaut sind (wie String-Formatting), sondern man eine separate Klasse braucht, seh ich sie eigentlich nicht als direkten Vergleich zu "blah $blubb xyz", welches eben keine zusätzlichen Sprachelemente benötigt (auch wenn es von der Syntax her ähnlich ist, aber das krieg ich mit String-Formatting und dicts auch hin dass es so ähnlich aussieht).
--- Heiko.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Okay, dann versuch ichs noch damit:

Code: Alles auswählen

value = 10
print 'Value %(value)s' % locals()
Auch nicht ganz vergleichbar, aber immerhin in der Sprache eingebaut.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

Python Master 47 hat geschrieben:
Mr_Snede hat geschrieben: OT:
wäre lustig sowas auch für Python - Ruby bzw Python - Perl zu haben.
Ich fände sowas für Pythn-C/C++ sehr gut!
Ein Python-C Spickzettel ist nicht so einfach, weil C nicht über so "fortgeschrittene" Datentypen verfügt, wie Python oder sogar PHP.

C Felder kennen zum Beispiel ihre Länge nicht, die muss man sich entweder gesondert merken, oder eine Endmarkierung benutzen, die nicht regulär im Feld vorkommen darf. Bei Zeichenketten, die eigentlich nur Felder vom Typ `char` sind, ist das zum Beispiel das Nullbyte.

Während ein Feld anlegen noch einfach ist...

Code: Alles auswählen

char *array[] = {"foo", "bar", "frobnitz"};
...muss man für einen Test auf "enthalten sein" schon eine komplette Funktion schreiben, die das Feld, seine Grösse, das was man sucht und eine Vergleichsfunktion als Argumente entgegen nimmt, um den ``in`` Operator von Python nachzubilden:

Code: Alles auswählen

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TRUE 1
#define FALSE 0
typedef int bool;

typedef int (*cmp_func)(const void *a, const void *b);

bool in_array(const void **array,
              const unsigned int array_size,
              const void *needle,
              const cmp_func cmp)
{
    unsigned int i;
    for (i=0; i < array_size; ++i) {
        if (cmp(needle, array[i]) == 0) {
            return TRUE;
        }
    }
    return FALSE;
}
Benutzen kann man das dann so:

Code: Alles auswählen

if (in_array(array, 3, "bar", strcmp)) {
    puts("Ist drin");
}
Das `count()` (PHP) bzw. `len()` (Python) Beispiel geht mit C Feldern so nicht, weil die wie schon gesagt, nicht "wissen" wie lang sie sind. Deshalb musste ich die Feldlänge ``3`` oben auch explizit angeben.

`join()` ist dann wegen der Speicherverwaltung, um die man sich bei C selbst kümmern muss, noch umfangreicher. Für das Ergebnis muss man soviel Speicher anfordern, das alle Zeichenketten plus den Seperatoren hineinpassen, also muss man in einem ersten Schritt ersteinmal die Längen der einzelnen Zeichenketten herausfinden. Dann kann man den Speicher anfordern und die einzelnen Zeichenketten und Seperatoren dort hin kopieren.

Code: Alles auswählen

char* str_join(const char *separator,
               const char **strings,
               const unsigned int array_size)
{
    unsigned int i, separator_length, *lengths;
    unsigned int new_size;
    char *result, *ptr;
    
    separator_length = strlen(separator);
    new_size = 1 + (array_size - 1) * separator_length;
    
    lengths = malloc(array_size * sizeof(unsigned int));
    for (i=0; i < array_size; ++i) {
        lengths[i] = strlen(strings[i]);
        new_size += lengths[i];
    }
    
    result = malloc(new_size * sizeof(char));
    ptr = result;
    for (i=0; i < array_size; ++i) {
        memcpy(ptr, strings[i], lengths[i]);
        ptr += lengths[i];
        if (i != array_size - 1) {
            memcpy(ptr, separator, separator_length);
            ptr += separator_length;
        }
    }
    *ptr = '\0';
    
    free(lengths);
    return result;
}
Und man muss natürlich auf die ganzen Grenzfälle achten. Der Quelltext da oben funktioniert nicht für `array_size == 0`. Das liesse sich durch den Einsatz des ternären Operators in einer Zeile beheben, aber das überlasse ich dem Leser als Übung. ;-)

Anwendung der Funktion:

Code: Alles auswählen

char *str;

str = str_join("-", array, 3);
puts(str);
free(str);
Noch eine Implementierung für `split()` und dann höre ich auch auf, versprochen. :-)

Code: Alles auswählen

char** str_split(const char *string,
                 const char *separator,
                 unsigned int *result_size)
{
    unsigned int i, str_length, separator_length;
    char **result, *str, *start, *end;
    
    str = strdup(string);
    str_length = strlen(str);
    separator_length = strlen(separator);
    
    i = 0;
    result = malloc((str_length / 2) * sizeof(char**));
    start = str;
    while ((end = strstr(start, separator))) {
        *end = '\0';
        result[i++] = strdup(start);
        start = end + separator_length;
    }
    result[i++] = strdup(start);
    
    free(str);
    result = realloc(result, i * sizeof(char**));
    *result_size = i;
    return result;
}
Um Grenzfälle habe ich mir jetzt auf die Schnelle keine Gedanken gemacht und benutzt wird es so:

Code: Alles auswählen

char **strings;
unsigned int i, size;

strings = str_split("foo<->bar<->frobnitz", "<->", &size);
for (i=0; i < size; ++i) {
    puts(strings[i]);
    /* free(strings[i]); */
}
/* free(strings); */
Man sieht, das ist nicht wirklich etwas für einen Spickzettel sondern eher für ein "Cookbook".
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Danke für den ausführlichen Beitrag!Python-C geht ziehmlich schwierig, dennoch wäre ein Vergleich Python-C++ sehr interresant!Das wäre dann auch nicht so schwierig wie mit C! :)
mfg

Thomas :-)
BlackJack

Ob das in C++ so viel einfacher wird, wage ich zu bezweifeln. Klar man hat Objekte, aber mit Objekten und Templates bekommt man auch sehr viel mehr Komplexität mit der man sich herumschlagen muss.

Einer Python-Liste am nächsten kommt wohl der `vector` in C++:

Code: Alles auswählen

    char *tmp[] = {"foo", "bar", "frobnitz"};
    vector<string> array(&tmp[0], &tmp[3]);
Wenn man das temporäre `char`-Feld nicht haben möchte, dann könnte man alternativ auch die drei Zeichenketten einzeln an den `vector` anhängen:

Code: Alles auswählen

    vector<string> array;
    array.push_back("foo");
    array.push_back("bar");
    array.push_back("frobnitz");
Schon wenn man den ``in`` Operator aus Python als Funktion für einen beliebigen Container aus der STL von C++ implementieren möchte, wird man mit Templates konfrontiert:

Code: Alles auswählen

template<class Iterable, class T>
bool contains(Iterable iterable, const T& element)
{
    return find(iterable.begin(), iterable.end(), element) != iterable.end();
}
Man kann `find()` natürlich auch direkt in ``if``-Abfragen benutzen. Den Fall habe ich im folgenden auskommentiert:

Code: Alles auswählen

    // if (find(array.begin(), array.end(), "bar") != array.end()) {
    if (contains(array, "bar")) {
        cout << "Ist drin" << endl;
    }
Die Länge eines Containers kann man natürlich sehr schön ermitteln, da die Objekte eine entsprechende Methode besitzen:

Code: Alles auswählen

    cout << array.size() << endl;
`join()` und `split()` muss man sich aber selbst schreiben.

Code: Alles auswählen

template<class Iter>
string join(const string& separator, const Iter& begin, const Iter& end)
{
    string result;
    
    for (Iter i=begin; i != end; ++i) {
        result += *i;
        if (i != (end - 1)) {
            result += separator;
        }
    }
    return result;
}

template<class StringContainer>
StringContainer split(const string& str, const string& separator)
{
    StringContainer result;
    size_t start, end;
    
    start = 0;
    while ((end = str.find(separator, start)) != str.npos) {
        result.push_back(str.substr(start, end - start));
        start = end + separator.length();
    }
    result.push_back(str.substr(start));
    
    return result;
}
Zu benutzen sind die beiden so:

Code: Alles auswählen

    cout << join("-", array.begin(), array.end()) << endl;

    list<string> splitted = split<list<string> >("foo<->bar<->frobnitz", "<->");
Ob das nun einfacher ist als bei C!? Ich finde C++ auf jeden Fall hässlicher. Insbesondere Fehlermeldungen, die mit Templates zusammenhängen und die Komplexität von Templates im allgemeinen. Ein verkorkster Versuch das starre Typsystem aufzubrechen, IMHO.

Zu den Template-Fehlermeldungen hier ein nettes Beispiel, welches mir beim Schreiben der Beispiele untergekommen ist:

Code: Alles auswählen

test.cpp: In function `int main()':
test.cpp:55: error: could not convert `std::find [with _InputIterator =
__gnu_cxx::__normal_iterator<std::string*, std::vector<std::string,
std::allocator<std::string> > >, _Tp = char[4]]((&array)->std::vector<_Tp,
_Alloc>::begin [with _Tp = std::string, _Alloc = std::allocator<std::string>](),
(&array)->std::vector<_Tp, _Alloc>::end [with _Tp = std::string, _Alloc =
std::allocator<std::string>](), ((const char (&)[4])"bar"))' to `bool'
Da weiss man doch sofort was man falsch gemacht hat, oder!?


Nochmal zum PHP-Python Spickzettel: Bei dem `substr()` Beispiel sollte auf jeden Fall ein Satz erklären, dass die beiden Argumente bei PHP Start und Länge, bei Python aber Start und Ende darstellen. Aus den angegebenen Beispielen wird das nämlich nicht unbedingt klar.
Antworten