string kürzen

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
Mundm28
User
Beiträge: 3
Registriert: Donnerstag 5. Mai 2016, 08:14

Hi Leute ich habe für einen twitterbot eine funktion geschrieben die tweets auf 140 zeichen kürzt, da der bot bei retweeteten tweets ein"RT NameDesRetweeteten: " aus dem Twitterstream liest. Allerdings kürzt meine Kürzungsvorrichtung nicht.. ich hoffe nur, dass mein Fehler nicht allzu dämlich ist :)

Code: Alles auswählen

def on_data(self,data):
        try:
            tweet = json.loads(data)
            tweettext= tweet["text"]
            usernamen = tweet["user"]
            username = usernamen["id"]
            tweetstr = str(tweettext.replace("@", "|"))
            dellen = len(tweetstr) - 139
        except:
            print("Fehlercode 1")
            tweetstr2 = "dem Programm ist ein Fehler unterlaufen #stopbotshaming"
            pass
        if len(tweetstr) > 140:
            tweetstr2 = tweetstr.replace(tweetstr[:dellen],"~")
        else:
            tweetstr2 = tweetstr
Hier nochmal wie ein empfangener tweet in Json notierung aussieht:

Code: Alles auswählen

{"created_at":"Tue Jul 15 14:19:30 +0000 2014","id":489051636304990208,"id_str":"489051636304990208","text":"Yaayyy I learned some JavaScript today! #thatwasntsohard #yesitwas #stoptalkingtoyourself #hashbrown #hashtag","source":"\u003ca href=\"http:\/\/twitter.com\/download\/iphone\" rel=\"nofollow\"\u003eTwitter for iPhone\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":2301702187,"id_str":"2301702187","name":"Toni Barlettano","screen_name":"itsmetonib","location":"Greater NYC Area","url":"http:\/\/www.tonib.me","description":"So Full of Art   |   \nToni Barlettano Creative Media + Design","protected":false,"followers_count":8,"friends_count":25,"listed_count":0,"created_at":"Mon Jan 20 16:49:46 +0000 2014","favourites_count":6,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":20,"lang":"en","contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_image_url_https":"https:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_tile":false,"profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/425313048320958464\/Z2GcderW_normal.jpeg","profile_image_url_https":"https:\/\/pbs.twimg.com\/profile_images\/425313048320958464\/Z2GcderW_normal.jpeg","profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":true,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":0,"favorite_count":0,"entities":{"hashtags":[{"text":"thatwasntsohard","indices":[40,56]},{"text":"yesitwas","indices":[57,66]},{"text":"stoptalkingtoyourself","indices":[67,89]},{"text":"hashbrown","indices":[90,100]},{"text":"hashtag","indices":[101,109]}],"symbols":[],"urls":[],"user_mentions":[]},"favorited":false,"retweeted":false,"filter_level":"medium","lang":"en"}
[/size]
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Um Text auf 140 Zeichen zu kürzen, kann man Slicing gut nutzen:

Code: Alles auswählen

truncated_text = text[:140]
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@Mundm28: Fehlerbehandlung, die nur neue Fehler produziert ist dämlich. Man sollte nie nackte excepts benutzen. Welche Ausnahmen können denn auftreten? data könnte kein valides JSON sein -> ValueError. Einer der Keys könnte nicht existieren -> KeyError. Es könnte sich um keine Wörterbuch handlen -> TypeError, tweettext könnte kein String sein -> AttibuteError. Ist dann Deine Fehlerbehandlung durchgelaufen, ist tweetstr undefiniert, da tritt also gleich in der nächsten Zeile ein NameError auf. Wenn Du Zeichen kürzen willst, kannst Du ja gleich mit Indexzugriff arbeiten, statt den Teil, der gedellt werden soll zu ersetzen und dabei vielleicht auch noch ganz andere Sachen mit. Stell Dir vor, Du willst nur ein "e" am Anfang abschneiden ...
BlackJack

@Mundm28: Was heisst der kürzt nicht? Wie hast Du das denn überprüft? Wie sieht denn `tweetstr2` am Ende aus? Du gibst das ja weder aus, noch machst Du irgend etwas anderes damit.

Ein ”nacktes” ``except:`` ohne Angabe von einer oder mehreren konkreten Ausnahmen erschwert die Fehlersuche ungemein. Du bekommst so wie dass da steht ja nur mit *das* etwas nicht funktioniert hat, aber nicht *was* und *wo* nicht funktioniert hat. Wenn man keine konkrete Ausnahme oder ganz allgemein `Exception` behandelt, ist es eigentlich immer sinnvoll die Ausnahme samt Traceback zu protokollieren, damit man sinnvoll nach Fehlern suchen kann. Das `logging`-Modul hat dafür eine `exception()`-Funktion und eine gleichnamige Methode auf `Logger`-Exemplaren.

`dellen` ist ein komischer Name den man leicht missverstehen kann. Der Wert wird an einer Stelle definiert an der noch gar nicht klar ist, ob er überhaupt benötigt wird. Und letztlich ist diese Rechnung sowieso nicht nötig, weil man einfach von vorne 139 Zeichen von einer Zeichenkette ”slicen” kann ohne irgendeine Anzahl ausrechnen zu müssen. Bei Deiner `replace()`-Variante kann es sogar passieren das da nicht am Ende sondern mitten im Tweet etwas rausgekürzt wird wenn der Tweet entsprechend ”ungünstig” aussieht. Das ist also auf jeden Fall ein Programmierfehler.

Was denkst Du was das ``pass`` dort bewirkt?
Mundm28
User
Beiträge: 3
Registriert: Donnerstag 5. Mai 2016, 08:14

nach meinem Code hab ich

Code: Alles auswählen

 api.update_status(status = tweetstr2)
 print(tweetstr2)
die sachen mit dem try und so funktionieren da liegt der fehler nicht
except hab ich universell gemacht da das programm bei jeder art von fehler den ignorieren und weitermachen soll weil es 24/7 laufen soll und ich dann einfach nach ner zeit gucke ob fehler da sind und dann kann ich gucken woran sie liegen, außerdem kommen manche fehler durch übertragungsfehler vom twitterstream und lassen sich so nicht vermeiden
(ausser dass tweetstr2 da eigentlich tweetstr heißen sollte)
ich hab das mit dem kürzen erst nachträglich reingebaut hab und er hat vorher die tweets die den kriterien entsprachen ungekürzt gepostet hat wie er es halt immer noch tut auch wenn er die zu langen tweets ja eigentlich kürzen sollte.
meine vermutung ist die dass die if abfrage oder die buchstabenzählung vom tweet irgendwie falsch ist aber ich hab keine ahnung warum

dellen steht für DeleteLenght also die länge die halt gelöscht werden soll
Zuletzt geändert von Mundm28 am Donnerstag 5. Mai 2016, 13:49, insgesamt 3-mal geändert.
Mundm28
User
Beiträge: 3
Registriert: Donnerstag 5. Mai 2016, 08:14

snafu hat geschrieben:Um Text auf 140 Zeichen zu kürzen, kann man Slicing gut nutzen:

Code: Alles auswählen

truncated_text = text[:140]
ja das wäre sehr einfach aber leider muss ich die ersten zeichen kürzen da die informationen dort unrelevant sind und am ende meistens ein link ist der halt bei deinem beispiel abgeschnitten würde und unbrauchbar würde auch wenn er das meist wichtigste des tweets darstellt
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@Mundm28: man kann auch von links kürzen: text[-140:].
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Dann halt so:

Code: Alles auswählen

truncated_text = text[-140:]
BlackJack

Du kannst eben nicht später mal schauen woran die Ausnahmen liegen, denn diese Information gibt es da ja nicht mehr, weil Du sie unterdrückst. Es ist ja okay wenn Du die Ausnahme für den Programmablauf nicht berücksichtigen möchtest, aber Du solltest sie an der Stelle halt protokollieren, damit Du am Ende auch mal schauen kannst *was* da Probleme bereitet hat.

Ich habe schon verstanden wofür die Beulen, äh, `dellen` stehen (sollen), aber nicht wegen dem Namen sondern weil ich darüber nachdenken musste. Namen sollten nicht zum rätselraten animieren müssen, sondern dem Leser klar vermitteln was der Wert bedeutet. Wenn es eigentlich `delete_length` bedeutet, sollte man es nicht `dellen` nennen. `usernamen` und `username` ist auch nicht gut. Bei ersterem erwartet man eine Datenstruktur weil es Mehrzahl ist und beim zweiten einen Benutzernamen und keine ID/Zahl.

Wenn Du eine Vermutung hast, dann überprüfe die doch einfach mal. Dazu wäre es hilfreich wenn Du den Code nicht zu sehr verteilst, also `delete_length` nicht an einer Stelle ermittelst wo es nichts zu suchen hat, sondern den Code zum Kürzen an einer Stelle konzentrierst. Vielleicht sogar eine Funktion daraus machst, die Du dann unabhängig von dem ganzen Bot- und Twitter-Kram einzeln entwickeln und testen kannst. Dann könntest Du auch Code zum testen zeigen den jeder einfach selber ausführen kann, auch ohne den Rest von Deinem Programm zu kennen.

Du könntest die einzelnen Schritte auch interaktiv in einer Python-Shell durchführen und schauen ob denn die Zwischenergebnisse mit dem übereinstimmen was Du erwartest.

Auch wenn Du von vorne kürzen möchtest, kannst Du ganz einfach eine fixe Anzahl „slicen“, nämlich von hinten. Man kann ja auch negative Indizes angeben:

Code: Alles auswählen

In [10]: 'abcdefghijklmnopqrstuvwxyz'[-10:]
Out[10]: 'qrstuvwxyz'
Antworten