Zeilenumbruch programmieren

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.
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

Servus Leute. Ich muss einen String einholen in Python und dann, wenn er länger als 80 Zeichen ist, nach 80 Zeichen einen Zeilenumbruch machen.
Der Zeilenumbruch sollte aber kein Wort durchtrennen, sondern dann einfach vor dem Wort abtrennen. Wie ist das auszuführen?
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Dazu gibt es das textwrap Module.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

Das klappt ja wunderbar aber ich muss das zur Übung selbst programmieren.
Den Zeilenumbruch an sich habe ich schon:

Code: Alles auswählen

s = ("Das hier wird ein längerer Text der einem Test dienen soll, einen Zeilenumbruch zu machen. Die Zeilen dürfen 50"
     "Zeichen breit sein und müssen danach ein newline vorweisen können. Im Nachhinein muss man das Programm so "
     "verbessern, das es keine ganzen Wörter abschneidet. Viel Glück!")
j = 1
z = 50

while j <= len(s):
    for i in range (j -1 , j + z -1):
        if i < len(s):
            print(s[i],end='')
    if s[i] == " ":
        print("")
    j += 50
Aber der schneidet halt die Wörter ab und das möchte ich nicht. Wie kann das verhindert werden?
BlackJack

@nfehren: In dem Du Dir einen Algorithmus ausdenkst der sich nicht an den Zeichen, sondern an Worten orientiert. Das ist doch *Deine* Hausaufgabe. Wie würdest Du das denn Schritt für Schritt angehen, wenn Du das von Hand machen müsstest? Du musst das so beschreiben das es jemand anders nach der Anleitung machen kann, und dann noch so formalisieren, dass es der Computer versteht.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Gehts nicht einfacher mit split und mitzählen wieviel Platz noch übrig ist?

Code: Alles auswählen

line_len, COLUMN_SIZE = 0, 80
for word in s.split():
    line_len += len(word) + 1
    if line_len > COLUMN_SIZE:
        line_len = len(word) + 1
        print()
    print("%s " % word, end="")
 
Zuletzt geändert von darktrym am Montag 5. Mai 2014, 15:07, insgesamt 1-mal geändert.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

BlackJack hat geschrieben:@nfehren: In dem Du Dir einen Algorithmus ausdenkst der sich nicht an den Zeichen, sondern an Worten orientiert. Das ist doch *Deine* Hausaufgabe. Wie würdest Du das denn Schritt für Schritt angehen, wenn Du das von Hand machen müsstest? Du musst das so beschreiben das es jemand anders nach der Anleitung machen kann, und dann noch so formalisieren, dass es der Computer versteht.

Aber der Algorithmus muss sich doch dann an Worten und Zeichen orientieren oder? sonst hab ich z.B. 8 kleine Worte und 8 ganz lange Worte und dann ist das ja kein richtiger Zeilenumbruch..

Ich weiß aber leider echt nicht wie das umzusetzen ist.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

nfehren hat geschrieben:
BlackJack hat geschrieben:Ich weiß aber leider echt nicht wie das umzusetzen ist.
Ich würde von Position 80 rückwärts suchen bis ein Leerzeichen kommt.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@nfehren: Du sollst ja auch nicht statt 80 Zeichen 10 Wörter nehmen, sondern so lange Wörter aneinanderreihen, bis keins mehr in 80 Zeichen passt.
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

Könnt ihr mir bisschen mit der Umsetzung helfen?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

nfehren hat geschrieben:Könnt ihr mir bisschen mit der Umsetzung helfen?
Ja klar.

Nimm den String. Suche ab Position 80 rückwärts bis du ein Leerzeichen findest. Gib den Text bis zum Leerzeichen aus. Nimm jetzt den dahinter liegenden Teil als neuen String und beginne mit dem Algorithmus von vorne.

Du brauchst nur noch eine Abbruchbedingung wenn das Stringende erreicht ist.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wenn Du uns mal Deine Ansätze zeigst, gerne :-)

Einfach so bekommst Du von uns keine Lösung auf dem Silbertablett serviert! Das sollte mittlerweile bekannt sein ;-)

Probiere es doch mal nach EyDus Idee! Dabei musst Du ja eigentlich nur den aktuellen Trenn-Index bestimmen, der immer dem alten + 80 Zeichen und dann maximal 80 Zeichen rückwärts beträgt. So schwer klingt das für mich jetzt nicht...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

Ich bin die ganze Zeit am Probieren wie man es machen müsste versteh ich von der Logik her blos bei der Syntaxs umsetzung haperts..
Habe bis her einiges probiert und gelöscht aber soviel hab ich noch (Achtung auch schwachsinn dabei):

Code: Alles auswählen

#erste_zeile = ""
#for i in range (0,49):
#    erste_zeile += s[i]
#
#erste_zeile = erste_zeile[:-3]
#print(erste_zeile)
#
#zweite_zeile = ""
#for i in range (47,100):
#    zweite_zeile += s[i]
#
#zweite_zeile = zweite_zeile[:-6]
#print(zweite_zeile)

zeile1 = ""
for i in range (0,49):
    zeile1 += s[i]
zeile1_neu = ""
for i in range(49,0):
    while s[i] == " ":
        zeile1_neu += s[i]
        i -= 1
print(zeile1_neu)




#while erste_zeile[i] != " ":
#    i -= 1
#    print(erste_zeile[i])
    
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@nfehren: versuch mal in Worten zu beschreiben, was Du denkst, was Du da programmiert hast.
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

Ich wollte den String solange durchgehen bis ich ein Leerzeichen finde.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hyperion hat geschrieben:Probiere es doch mal nach EyDus Idee!
Manche von uns sind wohl so omnipräsent, dass sie auch Ideen äußern, obwohl sie zu einem Thema keinen Betrag geschrieben haben :mrgreen:
Das Leben ist wie ein Tennisball.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

@EyDu Das war eine Aufforderung an dich, eine Idee beizusteuern :)

@nfehren: Das ist zu Grob. Spiele das doch mal mit einem Beispieltext durch, dann siehst du auch die einzelnen Faelle an die du denken musst.
Wie stellst du fest, dass du umbrechen musst? Wie verwaltest du die Information welche Woerter du schon ausgegeben hast und welche noch kommen, etc etc
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

cofi hat geschrieben:@EyDu Das war eine Aufforderung an dich, eine Idee beizusteuern :)
So sieht es nämlich aus... außerdem wollte ich testen, ob dem OP das auffällt, indem er die bis dato vorgeschlagenen Ideen, z.B. von /me, durchgeht...

Klingt doch glaubhaft, oder? :mrgreen:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Nagut, wenn es so ist. Eigentlich lösen wir hier ja keine Hausaufgaben, aber hier können wir vielleicht mal eine Ausnahme machen.

Code: Alles auswählen

# -*- coding: utf-8 -*-
TEXT = u"Das hier wird ein längerer Text der einem Test dienen soll, einen Zeilenumbruch zu machen. Die Zeilen dürfen 50 Zeichen breit sein und müssen danach ein newline vorweisen können. Im Nachhinein muss man das Programm so verbessern, dass es keine ganzen Wörter abschneidet. Viel Glück!"

j=" ".join;w=lambda t:"\n".join(map(j,reduce(lambda l,y:(l[-1].append(y)if 80>=len(j(l[-1]+[y]))else l.append([y]),l)[1],t.split(),[[]])))

print w(TEXT)
Man kann da sicher noch ein wenig kürzen, aber ehrlich gesagt wollte ich aus einer überischtlichen Lösung keine unübersichtliche machen. Probleme mit Wörter >80 Zeichen werden natürlich ignoriert.
Das Leben ist wie ein Tennisball.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

EyDu hat geschrieben:Man kann da sicher noch ein wenig kürzen, aber ehrlich gesagt wollte ich aus einer überischtlichen Lösung keine unübersichtliche machen.
Das ist eindeutig die absolut übersichtlichste Variante die einem als erstes in den Sinn kommt. Vielleicht mag der Fragesteller trotzdem noch mal einen anderen Ansatz ausprobieren.
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

EyDu hat geschrieben:Nagut, wenn es so ist. Eigentlich lösen wir hier ja keine Hausaufgaben, aber hier können wir vielleicht mal eine Ausnahme machen.

Code: Alles auswählen

# -*- coding: utf-8 -*-
TEXT = u"Das hier wird ein längerer Text der einem Test dienen soll, einen Zeilenumbruch zu machen. Die Zeilen dürfen 50 Zeichen breit sein und müssen danach ein newline vorweisen können. Im Nachhinein muss man das Programm so verbessern, dass es keine ganzen Wörter abschneidet. Viel Glück!"

j=" ".join;w=lambda t:"\n".join(map(j,reduce(lambda l,y:(l[-1].append(y)if 80>=len(j(l[-1]+[y]))else l.append([y]),l)[1],t.split(),[[]])))

print w(TEXT)
Man kann da sicher noch ein wenig kürzen, aber ehrlich gesagt wollte ich aus einer überischtlichen Lösung keine unübersichtliche machen. Probleme mit Wörter >80 Zeichen werden natürlich ignoriert.
Natürlich sehr nett das du dir die Mühe machst und mir den Code-Schnipsel schreibst aber darauf war ich nicht wirklich aus.. Ich möchte die Sache verstehen. Sonst könnte ich ja auch einfach dieses textwrap modul benutzen. Das was du geschrieben hast verstehe ich zum großteil nicht. Trotzdem vielen dank für die Mühe
Antworten