textwrap modul

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
kevind
User
Beiträge: 71
Registriert: Montag 22. Oktober 2012, 20:23
Wohnort: /dev/null

Hallo Zusammen,

versuche für mein Text Adv n kleines Dialog System zubasteln. Nun scheitere ich daran das ich in einen Fehler laufe sobald ich verschiedene Objekt Typen übergebe... kann mir hier jemand n Tipp in die richtige Richtung geben ?

Das Prozedere...
Ich rufe aus meinem main.py Script aus folgende Funktion aus dialog.py auf:

Code: Alles auswählen

dialog.msg((characters_status(), "Ein paar einzelne text ausgaben in form eines Strings"))
characters_status() enthält n Tuple mit 2 Strings:

Code: Alles auswählen

('Dude Vitality: 100/100', 'EnemyONE Vitality: 100/100')
Funktion msg aus dialog.py:

Code: Alles auswählen

def msg(message_block):
        #frame setup
        box_width = 50
        box_symbol_horizontal = "-"
        box_symbol_side = "|   "

        #cls()
        print(box_symbol_horizontal * box_width)  # outer horizontal border
        print(box_symbol_side)

        if type(message_block) == str: 
            wraped_text = textwrap.wrap(message_block, 20)  
            # wrap long string into a list of short ones
            for string in wraped_text:
                print("{0} {1}".format(box_symbol_side, string))

        elif type(message_block) == tuple:
            for obj in message_block:  
            # loop through objects of message_block and check type
                if type(obj) == str:
                    wraped_text = textwrap.wrap(obj, 20)
                    # wrap long string into a list of short ones
                    for string in wraped_text:
                        print("{0} {1}".format(box_symbol_side, string))
                elif type(obj) == tuple:  #if obj is tuple go through every tuple       
                    for obj in message_block:
                        wraped_text = textwrap.wrap(obj, 20)
                        for string in wraped_text:
                            print("{0} {1}".format(box_symbol_side, string))

        print(box_symbol_side)  # outer symbols
        print(box_symbol_horizontal * box_width)
message_block ist also ein Tuple welches ein Tuple und ein String enthält.

Fehler ist folgender:

Code: Alles auswählen

 File "C:\Python32\lib\textwrap.py", line 126, in _munge_whitespace
   text = text.expandtabs()
ttributeError: 'tuple' object has no attribute 'expandtabs'
Na da bin ich mal gespannt ob da jemand durchblickt... :P

Danke schonmal für die Mühe.

Greetz Kev.

Achja ich hab schon versucht Expand_tabs auf False zu setzen aber dann kommt n fehler mit "translation" wozu ich in der Doku garnichts gefunden habe... (bei bedarf kann ich den genaue Wortlaut nachreichen)
BlackJack

@kevind: Wenn in dem Tupel ein Tupel gefunden wird, solltest Du über *dessen* Inhalt iterieren und nicht über den vom Argument welches an die Funktion übergeben wurde. Beim ersten Tupel kracht es dann, weil `textwrap` nun mal nicht mit Tupeln funktioniert.

Mal davon abgesehen ist diese Typtesterei nicht schön. Weder die technische Umsetzung (da hätte man `isinstance()` nehmen sollen) noch generell. Wie Du siehst führt so etwas schnell zu unübersichtlichem Quelltext, der nicht mehr so leicht nachvollziehbar ist.
Benutzeravatar
kevind
User
Beiträge: 71
Registriert: Montag 22. Oktober 2012, 20:23
Wohnort: /dev/null

Kacke.. das ärgert mich jetzt, sorry da hätte ich wohl einfach etwas abstand nehmen sollen und dann später nochmal drüber schauen.

Ist in meinem Fall isinstance() wirklich soviel besser ? Vererbung gibt es ja keine. (soviel ich gelesen habe ist das der hauptvorteil von isinstance() gegenüber von type().

Ich gebe zu, isinstance() war mir vorher unbekannt.

Bzgl. unübersichtlichkeit... Danke BlackJack, ich war bereits stolz darauf dass ich sowas ansatzweise selbst hinbekommen habe was auch Cross-platform tauglich ist ;) Idee wie es einfacher geht ?

Danke dir !
BlackJack

@kevind: Woher weisst Du das es keine Vererbung gibt? Der Funktion sieht man das nicht an. Könnte ja gut sein, dass da mal jemand etwas mit ausgeben will was von `tupel` oder `str` abgeleitet ist. `collections.namedtuple` oder irgend etwas live aus einer Webseite „gekratztes” mit `BeautifulSoup` (AFAIK liefert das einen abgeleiteten `NavigatableString` oder so ähnlich).

Ansonsten könnte man mit `isinstance()` auf `str`, oder `str` und `unicode` testen und im anderen Fall einfach über das Objekt drüber iterieren. Denn das willst Du ja eigentlich machen wenn es keine Zeichenkette ist. Dann gehen *alle* Objekte solange sie die Bedingung erfüllen entweder Zeichenketten oder wieder „iterables” von Zeichenketten zu liefern. Also Tupel, Listen, zu Lesen geöffnete Textdateien, Datenströme von Webanfragen, und so weiter.

Allerdings würde ich es nicht so kompliziert machen. Warum muss man da überhaupt so viele verschiedene und verschachtelte Dinge übergeben können?
Benutzeravatar
kevind
User
Beiträge: 71
Registriert: Montag 22. Oktober 2012, 20:23
Wohnort: /dev/null

Aha! Sieht so aus als müsste ich mir das noch genauer ansehen ;)

Ich will das der Output einheitlich aussieht.
Der Inhalt der Konsole wird immer per cls oder clear (je nach OS) gelöscht damit immer nur das umrandete Fenster zu sehen ist. (Was durch dialog.msg gebildet wird)
Da übergebe ich Situationsabhängig mehrere Daten, ich meine vl. könnte ich erst alles in 1 Liste packen... aber so ist es flexibler, finde ich.

Auch versuche ich Text und Berechnungen zu trennen damit ich es später vl. doch noch mit ner GUI aufpeppen kann.

Für dieses Lernprojekt würde es den Zweck vermutlich auch so erfüllen.

Edit:

hast du noch ne Idee warum sich

Code: Alles auswählen

        dialog.msg(characters_status())
        dialog.msg("{0}".format(characters_status()))
diese 2 Arten in der Ausgabe unterscheiden ?

Code: Alles auswählen

--------------------------------------------------
|
|    dude Vitality: 100/100
|    EnemyONE Vitality: 100/100
|
--------------------------------------------------
--------------------------------------------------
|
|    ('dude Vitality: 100/100', 'EnemyONE
|    Vitality: 100/100')
|
--------------------------------------------------



Danke und Gruss !
Antworten