Twitter (was mache ich gerade?)

    Suche

     

    Credits

    Archiv

    Dezember 2024
    Mo
    Di
    Mi
    Do
    Fr
    Sa
    So
     
     
     
     
     
     
     1 
     2 
     3 
     4 
     5 
     6 
     7 
     8 
     9 
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
     
     
     
     
     
     
     

    Status

    Online seit 6952 Tagen
    Zuletzt aktualisiert: 17. Apr, 22:03

    Counter & Co.

    Egoload - Verträumter Idealist
    Mein
Koordinaten auf der EgoMap:  93,2
    100% Heidnisch

    Locations of visitors to this page

    Python

    Dienstag, 16. Mai 2006

    Funktionen

    Bei den globalen und lokalen Namespaces gab es ja schon eine Funktion, hier die Vertiefung dazu:
    
    #!/usr/bin/env python
    
    def getkey(prompt="Yes/no: ",allow=('y','n')):
        while True:
            query=raw_input(prompt)
            if query in allow:
                return query
            else:
                print "Please answer ",allow,", only!"
    
    print "This is a test question."
    print getkey()
    
    print "This is an alternative text:"
    print getkey("Please answer Yes or No: ")
    
    print "Use the function above to do something entirely different:"
    print getkey("0-9? ",str(range(10)))
    
    Das Beispiel zeigt sehr schön, wie Funktionen in Python funktionieren. Es handelt sich um eine einfache Tastaturabfrage-Routine, die die Eingabe überprüft.
    Der Prompt, also das, was zur Aufforderung angezeigt wird, sowie die möglichen Antworten, werden bereits in der Funktionsdefinition angelegt, wobei allow nur zum Zuge kommen, wenn keine Parameter übergeben werden, wie das beim ersten Aufruf von range()-Anweisung ins Spiel, deren Ausgabe mittels getkey()-Funktion selbst besteht aus einer raw_input() ist für Tastaturabfragen zuständig, und die in lediglich nachgeschaut, ob die Antwort in return verlassen und die Eingabe an die aufrufende Funktion zurück gegeben, wo sie einfach nur ausgegeben wird.

    Mehr dazu gibt es im Python Tutorial

    range() und for

    Die for-Schleife in Python arbeitet ähnlich wie die in Unix-Shells: Anstelle von einer Startbedingung zu einer Endbedingung hochzuzählen, wobei die Schrittweise festlegbar ist, wie das bei C der Fall ist, geht Pythons for durch eine Menge von Elementen, wobei es egal ist, von welchem Typ diese Elemente sind:
    
    >>> for x in ("Douglas Adams","Per Anhalter durch die Galaxis",42):
    ...    print x
    ...
    Douglas Adams
    Per Anhalter durch die Galaxis
    42
    
    Beim Programmieren ist das natürlich angenehm, weil man Tupel und Listen einfach nur angeben muß, um alle darin enthaltenen Elemente verarbeiten zu können.

    Möchte man irgendwas hochzählen, braucht man eine Hilfe, und genau dafür ist range() da:
    
    >>> for x in range(10):
    ...     print x,
    ...
    0 1 2 3 4 5 6 7 8 9
    
    Es fällt auf, das range bei 0 anfängt zu zählen, aber bei 9 aufhört, statt bis 10. Möchte man eine Ausgabe inklusive der 10, und die 0 möchte man auch nicht sehen, muß man entsprechende Änderungen vornehmen:
    
    >>> max=10
    >>> for x in range(1,max+1):
    ...     print x,
    ...
    1 2 3 4 5 6 7 8 9 10
    
    max ist die Obergrenze, bis zu der ich zählen möchte, und da ich diese inklusive haben möchte, inkrementiere ich den Ausdruck von max um 1.
    Der Ausdruck range(a,b) bedeutet, zähle von a nach b, ein range(b) ist also gleichbedeutend mit range(0,b).
    Es gibt noch eine dritte Möglichkeit, mit range() zu arbeiten:
    
    >>> for x in range(1,32,2):
    ...     print x,
    ...
    1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31
    
    Der dritte Wert gibt also die Schrittweite an, mit der hochgezählt werden soll. Übrigens funktioniert nicht die Kombination range(Obergrenze,Schrittweite), weil Python hier nicht wissen kann, ob nicht range(Startwert,Obergrenze) gemeint ist. Allerdings wird Python hier auch nicht sauer und haut einem Fehlermeldungen um die Ohren, es passiert nur nichts:
    
    >>> for x in range(32,2):
    ...     print x,
    ...
    >>>
    
    range() funktioniert natürlich auch "subtrahierend:", wobei hier die Schrittweite auf jeden Fall angegeben werden muß, weil Python ansonsten davon ausgeht, dass wir eine Schrittweite von +1 haben wollen. Warum das so ist, werden wir später noch sehen:
    
    >>> for countdown in range(10,-1):
    ...     print countdown
    ...
    >>> for countdown in range(10,-1,-1):
    ...     print countdown,
    ...
    10 9 8 7 6 5 4 3 2 1 0
    
    for ist bei weitem nicht das einzige Einsatzgebiet für range(), vielmehr können hier auch Listen mit befüllt werden:
    
    >>> countdown=range(10,-1,-1)
    >>> countdown
    [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
    

    Verarbeitung von Argumenten

    Die Übergabe von Argumenten und Parametern in Programmen ist eine nicht unwichtige Angelegenheit. In der Shellprogrammierung liegen die Argumente in $0, $1, $2... $*, die meisten Programmiersprachen bieten ein Array ARGV oder so ähnlich an (Perl, C...).
    Python macht das ähnlich:
    
    #!/usr/bin/env python
    
    import sys
    
    print "My Filename: ",sys.argv[0]
    print "No. of args: ",len(sys.argv)-1
    print "Arguments  : ",sys.argv[1:]
    
    if len(sys.argv)-1 >= 1:
       print "Processing arguments..."
       for x in range(1,len(sys.argv)):
           print "Argument ",x,": ",sys.argv[x]
    else:
       print "Nothing to do."
    
    In Python wird das Tupel argv vom Modul sys zur Verfügung gestellt, deshalb sys.argv. Wie unter Unix üblich (sofern man unter Unix programmiert), steht in argv[0] der Filename drin, mit dem das Programm aufgerufen wurde, oder der entsprechende Parameter, wenn man eben kein python-Script vorliegen hatte.
    Die Konstruktion weiter unten gibt einfach nochmal alle Argumente der Reihe nach aus, sofern mehr als ein Argument übergeben wurde.
    Wird das Script aufgerufen, sieht das z.B. so aus:
    
    $ ./03_argv.py dies ist einer dieser typischen tests.
    My Filename:  ./03_argv.py
    No. of args:  6
    Arguments  :  ['dies', 'ist', 'einer', 'dieser', 'typischen', 'tests.']
    Processing arguments...
    Argument  1 :  dies
    Argument  2 :  ist
    Argument  3 :  einer
    Argument  4 :  dieser
    Argument  5 :  typischen
    Argument  6 :  tests.
    
    Hm, if, range() und for folgen im nächsten Beitrag.

    Lokale und globale Namespaces

    
    #!/usr/bin/env python
    
    # Namespaces
    # In Funktionen gibt es lokale Namensraeume,
    # soll ein Objekt global uebernommen werden, muss dies
    # mittels global geschehen.
    
    #  - Objekte aus dem Hauptprogramm bleiben auch in
    #    Unterfunktionen lesend global, beim Schreibzugriff
    #    werden sie aber lokal, es sei denn, es wird explizit
    #    "global " angegeben.
    #  - (Streng genommen wird beim Schreibzugriff auf ein
    #    Objekt aus dem globalen Namespace ein zweites Objekt
    #    mit gleichem Namen im lokalen Namespace erzeugt,
    #    welches das Objekt aus dem globalen Namespace
    #    ueberdeckt.
    
    
    def test():
        print "Funktionseinstieg"
        print locals()
        print globals()
        print "Globalisierung..."
        a = "Ciao"
        global b
        b = "Erde"
        c = "Universum"
        print "Gaendert: a=",a,", b=",b,", c=",c
        print locals()
        print globals()
    
    print "Programmstart"
    print locals()
    print globals()
    
    a = "Hallo"
    b = "Welt"
    
    print "Variablendefinition"
    print "Objekte am Programmanfang: a=",a,", b=",b
    print locals()
    print globals()
    test()
    print "Objekte am Programmende  : a=",a,", b=",b
    print locals()
    print globals()
    
    Das Script verwendet das erste Mal eine selbstgeschriebene Funktion, die durch def angelegt wird. Ihr Name ist test, und die leere Klammer bedeutet, dass sie erstmal keine Variablen oder Variablenwerte aus den aufrufenden Funktionen übernimmt.
    Interessant sind die Befehle locals() und globals(), die jeweils den Inhalt des lokalen und globalen Namespace ausgeben, wobei natürlich festzustellen ist, dass es einen globalen Namespace nur innerhalb von Funktionen geben kann, weil das Hauptprogramm nur über einen Namensraum verfügt.

    Führt man das Programm aus, gibt es folgendes aus:

    Programmstart
    {'__builtins__': , '__name__': '__main__', '__file__': './02_namespaces.py', 'test': , '__doc__': None}
    {'__builtins__': , '__name__': '__main__', '__file__': './02_namespaces.py', 'test': , '__doc__': None}
    Variablendefinition
    Objekte am Programmanfang: a= Hallo , b= Welt
    {'a': 'Hallo', 'b': 'Welt', '__builtins__': , '__file__': './02_namespaces.py', 'test': , '__name__': '__main__', '__doc__': None}
    {'a': 'Hallo', 'b': 'Welt', '__builtins__': , '__file__': './02_namespaces.py', 'test': , '__name__': '__main__', '__doc__': None}
    Funktionseinstieg
    {}
    {'a': 'Hallo', 'b': 'Welt', '__builtins__': , '__file__': './02_namespaces.py', 'test': , '__name__': '__main__', '__doc__': None}
    Globalisierung...
    Gaendert: a= Ciao , b= Erde , c= Universum
    {'a': 'Ciao', 'c': 'Universum'}
    {'a': 'Hallo', 'b': 'Erde', '__builtins__': , '__file__': './02_namespaces.py', 'test': , '__name__': '__main__', '__doc__': None}
    Objekte am Programmende : a= Hallo , b= Erde
    {'a': 'Hallo', 'b': 'Erde', '__builtins__': , '__file__': './02_namespaces.py', 'test': , '__name__': '__main__', '__doc__': None}
    {'a': 'Hallo', 'b': 'Erde', '__builtins__': , '__file__': './02_namespaces.py', 'test': , '__name__': '__main__', '__doc__': None}


    Die ersten beiden Zeilen zeigen, wie der Namespace aussieht, wenn noch nicht viel passiert ist: Es gibt ein paar eingebaute Module, das File, das das Programm enthält, heißt 02_namespace.py, und es gibt eine definierte Funktion test.
    Interessant wird es das erste Mal nach der Deklaration der Variablen a und b, die nun in den globalen Namespace einfliessen (der an der Stelle wiederrum identisch ist mit dem lokalen).
    Richtig spannend wird es dann nach dem Funktionsaufruf: Hier ist der lokale Namespace plötzlich leer, wie die der erste Satz geschweifter Klammern anzeigt, währen der globale sich nicht verändert hat.
    Dann geschieht zweierlei: Durch die Anweisung global b wird die Variable b von der Funktion test() aus beschreibbar, außerdem wird die Variable a neu deklariert, und c kommt hinzu.
    Nach der Globalisierung sieht der lokale Namespace schon anders aus, er enthält a und c, aber immer noch nicht b. Dafür ist im globalen Namespace ersichtlich, dass die Änderung b='Erde' ihre Wirkung nicht verfehlt hat. Wenn sich die Funktion beendet, ist b immer noch 'Erde', aber nicht 'Welt', wie es noch am Anfang der Fall war.
    Das c als neue Variable im lokalen Namespace ist, ist nicht verwunderlich, man sieht aber auch sehr schön, dass die lokale Variable a, deren Wert nun 'Ciao' ist, das global deklarierte a überlagert. In der Funktion test hat man nun keinen Zugriff mehr auf die globale Variable a.

    Variablen: Boolean und None

    Python kennt wie viele andere Programmiersprachen auch, Variablen vom Typ Boolean, die die Werte True oder False annehmen können. Dabei ist das noch nicht mal unbedingt nötig, weil in Python jede Variable als Boolean gewertet werden kann: Variablen mit nicht definiert sind, oder den Wert 0 haben, sind False, während alle anderen True sind, wie das folgende Beispiel zeigt:
    
    >>> x = 20
    >>> while x:
    ...     print x,
    ...     x=x-1
    ...
    20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
    
    Die while-Schleife arbeitet also auf Basis von Boolean und läuft solange, wie die Bedingung wahr ist.

    Daneben gibt es noch den Variablentyp None, den ich vorher noch nicht kannte. Damit können Variablen defklariert werden, ohne jedoch Werte zuzuweisen. Sinn macht das z.B. in Situationen, wo man im Programm eine Variable benötigt, jedoch jeder zugewiesene Wert nur stören würde.

    Freitag, 12. Mai 2006

    Listen

    Tupel sind zur Programmierung also schonmal nicht schlecht, zumindest solange es sich um statische Daten handelt. In der Praxis will man aber komplexe Daten verarbeiten, worunter neben Ergänzungen und Löschungen auch die Veränderung einzelner Datenteile gehört, wie z.B. bei einer Kundenverwaltung die Möglichkeit, bei einem Umzug lediglich die Adresse des Kundens zu ändern, anstatt den Kunden neu anlegen zu müssen.
    Dazu bietet Python Listen an, die ähnlich wie Tupel funktionieren, jedoch auch wilde Veränderungen erlauben:
    
    >>> begruessungen=["Guten Morgen",'Moin',"Hello","Guten Abend"]
    >>> print begruessungen
    ['Guten Morgen', 'Moin', 'Hello', 'Guten Abend']
    >>> print begruessungen[1]
    Moin
    >>> len(begruessungen)
    4
    >>> len(begruessungen[0])
    12
    >>> begruessungen[0:2]
    ['Guten Morgen', 'Moin']
    >>> begruessungen[3]
    'Guten Abend'
    >>> begruessungen[2]
    'Hello'
    >>> begruessungen[2]="Hallo"
    >>> begruessungen
    ['Guten Morgen', 'Moin', 'Hallo', 'Guten Abend']
    
    Listen werden also über eckige Klammern erzeugt, wobei der Inhalt, genauso wie bei Tupeln, unterschiedliche Typen umfassen darf. Mittels len() läßt sich die Anzahl Elemente der gesamten Liste, oder einzelner Listenelemente, ausgeben. Genau wie bei Tupeln kann man auf einzelne Elemente, oder auf eine Reihe von Elemente via [x:y] zugreifen.
    Mehrdimensionale Listen sind ebenfalls möglich, wobei auch hier dasselbe gilt wie bei Tupeln.

    Aliasing
    Einen Unterschied gibt es, der als Aliasing bezeichnet wird: Was bei Strings und gewöhnlichen Variablen zu einer Kopie des Wertes (Objektes) führt, führt bei Listen lediglich zu einer weiteren Namenszuweisung:
    
    >>> a=1
    >>> b=a
    >>> print a,b
    1 1
    >>> b=2
    >>> print a,b
    1 2
    >>> voelker=['Vulkanier','Klingonen','Bajoraner','Borg']
    >>> anderesicht=voelker
    >>> anderesicht[3]
    'Borg'
    >>> anderesicht[3]='Spezies123'
    >>> voelker
    ['Vulkanier', 'Klingonen', 'Bajoraner', 'Spezies123']
    
    Bei a und b, zwei normalen Variablen sieht man, dass zuerst b den Wert von a zugewiesen bekommt, der dann aber verändert wird, ohne das dies zu einer Veränderung von a führt.
    Listen verfügen aber über eine sogenannte Identität, die bei einer Zuweisung übergeben wird. Dadurch greift man über zwei verschiedene Namen auf dieselben Objekte zu, wie das Beispiel weiter unten zeigt: Borg wird gegen Spezies123 ersetzt, und zwar in der Liste anderesicht. Dies ändert aber auch voelker.

    Donnerstag, 11. Mai 2006

    Variablen II: Mehrdimensionalität

    Es kommt häufiger vor, dass man nicht einfache Datenreihen speichern will, sondern komplexe, zusammenhängende Datensätze. In diesem Fall ist man mit mehrdimensionalen Feldern ganz gut bedient:
    
    >>> aufzaehlung=((3.491,"Pi"),(42,"Anhalter"))
    >>> aufzaehlung
    ((3.4910000000000001, 'Pi'), (42, 'Anhalter'))
    >>> aufzaehlung[0]
    (3.4910000000000001, 'Pi')
    >>> aufzaehlung[0][1]
    'Pi'
    
    Verwendet man in einem mehrdimensionalen Tupel also lediglich eine "Koordinate", wird der gesamte darin enthaltene Tupel ausgegeben, die zweite Koordinate bestimmt das auszugebende Objekt innerhalb des Tupels.
    Im Gegensatz zu einigen anderen Sprachen kann die Anzahl der Dimensionen in einem Tupel variieren, was auf der einen Seite positiv für den Speicherverbrauch ist, andererseits aber natürlich bedeutet, dass man selbst dafür Sorge tragen muß, nur auf gültige Daten zuzugreifen. Beispiel:
    
    >>> netzdaten=(("cptsalek","https://cptsalek.twoday.net","cptsalekweb.de"),
    ...            ("cptcalhoun","https://cptcalhoun.twoday.net"))
    
    Hier haben wir einen Tupel namens "netzdaten", der zwei Datensätze enthält, wobei der erste drei Strings umfaßt, der zweite jedoch nur zwei. Es wäre also schön eine Möglichkeit zu haben, sich das im Programm auch ausgeben zu lassen. Gibt es auch:
    
    >>> len(netzdaten)
    2
    >>> len(netzdaten[0])
    3
    >>> len(netzdaten[1])
    2
    >>> len(netzdaten[1][0])
    10
    
    Der Befehl len() gibt die Länge eines Objektes zurück. Wird nur "netzdaten" angegeben, umfaßt das Objekt in der Tat zwei Tupel. Der erste Datensatz, bezeichnet durch netzdaten[0], seinem Index, enthält die besagten drei Strings. Der len()-Befehl funktioniert auch bei reinen Strings, wie das letzte Beispiel zeigt, das die Länge des Namens "cptcalhoun" zurückliefert.

    Variablen

    Python benötigt keine Variablendeklaration am Anfang einer Funktion, wie das z.B. bei C der Fall ist. Typenänderungen werden entweder automatisch vorgenommen, oder müssen vom Programmierer per Funktion vorgenommen werden, z.B. wenn eine Zahl an einen String angehängt werden sollen.
    Neben Variablen mit unterschiedlichen Wertebereichen, gemäß den Definitionen für Integer, Long Integer und einigen anderen mehr, kennt Python auch "Sequenzen", wozu Strings, Tupel und Listen gehören.
    Strings sind einfache Zeichenketten wie z.B.
    
    >>> begruessung="Hallo Welt"
    
    Hierauf lassen sich einfache Operationen anwenden:
    
    >>> begruessung="Hallo Welt"
    >>> satzzeichen="!"
    >>> begruessung=begruessung+satzzeichen
    >>> print begruessung
    Hallo Welt!
    >>> print begruessung[0]
    H
    >>> print begruessung[0:5]
    Hallo
    >>> print begruessung[:5]
    Hallo
    >>> print begruessung[6:]
    Welt!
    >>> print begruessung[-5:]
    Welt!
    >>> print begruessung[-5:-1]
    Welt
    
    Die ">>>" stehen für eine interaktive Interpretersession, man kann Python also einfach so aufrufen, und Befehle eingeben. Zum Demonstrieren und Experimentieren reicht das oftmals aus.
    Übrigens kann man den print-Befehl zur Anzeige auch weglassen, wenn man nur einen Variablennamen angibt, unterstellt einem Python, dass man das/die Objekte angezeigt bekommen möchte.

    Tupel sind Aneinanderreihungen von Werten, wobei diese unterschiedlicher Art sein können. Genau wie bei Strings kann man auch bei Tupeln auf einzelne Elemente zugreifen:
    
    >>> aufzaehlung=(3.491, "Wort", 42)
    >>> aufzaehlung
    (3.4910000000000001, 'Wort', 42)
    >>> aufzaehlung[0]
    3.4910000000000001
    >>> aufzaehlung[1]="Ein Satz."
    Traceback (most recent call last):
      File "", line 1, in ?
    TypeError: object doesn't support item assignment
    
    Das Beispiel zeigt etwas, was auch für Strings gilt: Sie lassen sich nicht verändern, sobald man versucht, einzelne Elemente zu ändern, gibt es eine Fehlermeldung. Verändert man augenscheinlich einen ganzen String oder Tupel, z.B. mittels aufzaehlung=, so wird ein neues Objekt angelegt, und das alte der Garbage Collection zugeführt.

    Mittwoch, 10. Mai 2006

    Schlangefraß

    Da ich mich seit einer Weile beruflich mit Zope, bzw. dem darauf aufsetzendem Plone auseinander setzen muß, habe ich die Gelegenheit beim Schopfe ergriffen, mich ordentlich in die verwendete Programmiersprache Python einzuarbeiten.
    Meine Erkenntnisse und Notizen werden ich also in Zukunft hier in loser Folge ablegen bzw. präsentieren.
    Als Dokumentation dient mir das Python Tutorial for Programmers sowie "Python Gepackt" von Michael Weigend, erschienen im mitp-Verlag, ISBN 3-8266-1512-3.
    Man kann auch genau erkennen, wann ich mich auf welche Dokumentation beziehe, weil ein Teil meiner Experimente auf Englisch gehalten sind, andere auf Deutsch... ;-)

    Hier einige Kurzinfos:
    Python ist eine objektorientierte Skriptsprache, d.h. die in Form von Textdateien gespeicherten Programme werden zur Laufzeit in ein ausführbares Programm übersetzt, ähnlich wie das bei Shell-Skripten, Perl und Java der Fall ist.
    Im Gegensatz zu den meisten anderen Sprachen verwendet Python keine Klammern, um zusammenhängende Befehlsblöcke, wie z.B. in Schleifen, Funktionen und dergleichen, zu kennzeichnen. Außerdem markiert das Zeilenende das Ende einer Anweisung, zusätzliche Zeichen, wie z.B. das oftmals verwendete Semikolon, werden nicht benötigt. Hier mal ein abstraktes Beispiel:
    
    # Dieses Beispiel enthaelt keinen ausfuehrbaren Python-Code
    # Zeilen die mit einerm # anfangen sind Kommentare
    Befehl 1
    Ein weiterer Befehl
    Hier koennte eine Schleife anfangen
       Alle Befehle, die in der Schleife ausgefuehrt werden sollen,
       muessen einheitlich eingerueckt werden
       Wird z.B. eine Bedingung innerhalb der Schleife eingefuehrt,
          werden die Anweisungen, die zu der Bedingung gehoeren,
          noch weiter eingerueckt
       Diese Zeile wuerde also nicht mehr zur Bedingung gehoeren,
       sondern zur Schleife
    Und diese hier auch nicht mehr zur Schleife.
    
    Auch wenn das hier unverständlich erscheint, es macht Python sowohl übersichtlich wie auch einfach - wer einmal in einem längeren Sourcecode einen Klammerfehler eingebaut hat, und diesen stundenlang gesucht hat, wird wissen, was ich meine.
    Umgekehrt verleiten die unterschiedlichen Einrückungen natürlich zu Fehler ganz eigener Art.
    Übrigens ist die Art der Einrückung - Tabulatoren oder Leerzeichen - frei wählbar, es empfiehlt sich nur nicht, beides zu mischen, weil der Python-Interpreter zur Laufzeit Tabulatoren in Leerzeichen umwandelt. Wer Leerzeichen verwendet darf sich auch pro Einrückung überlegen, wieviele Leerzeichen es sein sollen. Im obigen Beispiel verwende ich drei pro Einrückung, aber auch nur eines oder mehr als drei wären erlaubt.

    Aktuelle Beiträge

    Im happy I finally registered
    Excellent write-up. I absolutely love this site. Continue...
    http://mittenmail3.isblog.net/pick-a-winner-via-hashtag-entry-for-twitter-and-instagram-woobox-bl... (Gast) - 17. Apr, 22:03
    Just want to say Hi!
    I all the time emailed this blog post page to all...
    how to get instagram likes (Gast) - 30. Mär, 23:20
    Im happy I now signed...
    Hello, There's no doubt that your website could possibly...
    buy instagram followers cheap (Gast) - 30. Mär, 09:27
    Hallo Miau!
    Ich will einen schönen Tag wünschen, mit unseren Schmusekatzen....
    SCHLAGLOCH - 4. Apr, 14:51
    Sehe hier nut Tag und...
    Wo ist das Jahr an dem der Text geschrieben wurde?
    Gast (Gast) - 3. Mär, 20:38

    User Status

    Du bist nicht angemeldet.

    ...wenn man trotzdem lacht
    Atari Mega ST
    Auf Arbeit
    Bloggen
    Bookmarks & Links
    BSD
    Bundeswehr
    CCC07
    Computing
    Contentmafia
    Datenschutz
    DRM
    Fahrrad
    Finanzkrise
    Fundsachen
    G8
    ... weitere
    Profil
    Abmelden
    Weblog abonnieren