Vorstellung, erster Beitrag und Frage

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.
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

Sorry, jetzt verstehe ich gar nichts mehr

dieser Code:

ausgabetext = "Der Preis für 2 Socken beträgt 5 DM und 5 Paar kosten 10 DM"
ausgabetext = ausgabetext.replace("DM", "Euro")
print(ausgabetext)

bewirkt diese Ausgabe:
Der Preis für 2 Socken beträgt 5 Euro und 5 Paar kosten 10 Euro

Hier wird doch eindeutig "DM" gegen "EURO" getauscht.

Genau aus dem Grund, habe ich ja die Frage bei replace("," ,".")
Zuletzt geändert von derkai74 am Donnerstag 13. Januar 2022, 22:33, insgesamt 3-mal geändert.
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

In dem DM und EURO Beispiel kommt doch auch ein Komma vor im Ausdruck mit dem replace. Wieso verwirrt dich das Komma nicht, aber das Komma bei dem andern Ausdruck stellt ein Mysterium dar?
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

Ausgangswert ist DM -> Ergebnis ist EURO (Komma hin oder her)
Was macht denn das Komma, wenn im Ergebnis genau das geschieht
was im Argument 1 (DM) gegen Argument 2 (Euro) getauscht wird?
Also genau das, was replace("DM", "EURO") ausführen soll.

Wofür ist denn das Komma da? Was bewirkt es? außer Argument1 von Argument 2 zu trennen?

VG
Kai
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du sagst es doch selbst. Das Komma trennt die Argumente. Und das tut es in beiden Fällen. Also ist im Fall vom Komma und Punkt das zweite Komma nicht das, womit das erste ersetzt wird. Sonder der Trenner.
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

Ey Ey Ey - ich tret mal bei Seite-
dann steh ich nicht mehr auf dem Schlauch.

Danke Danke Danke
Das zweite Komma steht nicht in "" - daher ist der Trenner.
Manchmal hilft auch gucken.

Danke
Kai
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Ja, das hat mich auch schon mal verwirrt - man muss immer gut aufpassen, wo " Anführungszeichen beginnen und enden - denn dieselben Zeichen da drin haben eine andere Bedeutung als draußen. Besonders, wenn es dann noch Kommas oder sonstige Sonderzeichen sind, die man auch außerhalb benutzt.

Das gleiche gilt übrigens auch für Klammern ( und ) - hier ist auch sehr wichtig zu schauen, wo sie beginnen und enden, vor allem wenn sie auch noch mehrfach hintereinander oder sogar ineinander verschachtelt vorkommen. Das führt dann auch zur Antwort zu deiner Frage von float und replace. Aber vermutlich solltest du erstmal dein Buch weiterlesen, bis dort die Verkettung von mehreren Funktionen und ihren Ergebnissen behandelt wird.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Benutzeravatar
__blackjack__
User
Beiträge: 13102
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei das mit den Zeichenketten, was ist drin und was ausserhalb, nicht mehr so schwer auseinanderzuhalten sein sollte wie früher™, denn es gibt ja Syntaxhighlighting was einem dabei helfen sollte.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Das stimmt, das ist hilfreich. Dazu muss man allerdings einen entsprechenden Editor benutzen, der die Syntax hervorheben kann, oder hier im Forum mal den "Code" Button bemühen:

Code: Alles auswählen

replace("," ,".")
WIe sehr das grün/blau hier in diesem Fall bei so kleinen Zeichen hilft, muss dann jeder selbst entscheiden.
In den meisten Fällen erhöht es die Lesbarkeit sehr, weshalb sich der kleine Aufwand quasi immer lohnt.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

ja, da habe ich wohl gelernt, genauer hinzuschauen. Vielen Dank an Alle.
Darf ich noch was fragen? Ich mach's einfach mal.

Das das unsinnig ist, was jetzt kommt ist mir klar.
In meinem Buch wird die Aufgabe gestellt, eine Liste und ein Dictionary zu erstellen.

Dann soll die Inhalte jeweils einzeln und je Inhalt in eine neue Zeile ausgegeben werden.

Für die Liste habe ich das wie folgt gelöst:

buecher_l1 = ["der alte Mann", "Theo", 1, 19.80]
buecher_l2 = ["die alte Frau", "Sandra", 2, 32.00]
buecher_l3 = ["die alte Katze", "Leo", 3, 14.90]

neue Gesamtliste:
buecher_lg = [buecher_l1] + [buecher_l2] + [buecher_l3]

mit dieser Schleife durchlaufe ich die Gesamtliste:
a = 0
for x in buecher_lg:
a = 0
for y in x:
print((x)[a])
a += 1

Das bringt das Ergebnis, was erreicht werden soll.


Die gleiche Aufgabenstellung für das Dictionary macht mich wahnsinnig gerade:
buecher_d1 = {"Titel": "der alte Mann", "Autor": "Theo", "Nr.": 1, "Preis": 19.80}
buecher_d2 = {"Titel": "die alte Frau ", "Autor": "Sandra", "Nr.": 2, "Preis": 32.00}
buecher_d3 = {"Titel": "die alte Katze ", "Autor": "Leo", "Nr.": 3, "Preis": 14.90}

neues Gesamtdictionay:
buecher_dg = [buecher_d1] + [buecher_d2] + [buecher_d3]
ergibt folgende Ausgabe:
[[{'Titel': 'der alte Mann', 'Autor': 'Theo', 'Nr.': 1, 'Preis': 19.8},
{'Titel': 'die alte Frau ', 'Autor': 'Sandra', 'Nr.': 2, 'Preis': 32.0},
{'Titel': 'die alte Katze ', 'Autor': 'Leo', 'Nr.': 3, 'Preis': 14.9}]

Was habe ich da jetzt überhaupt erzeugt?
Denn mir gelingt es nicht, in einer Schleife einzeln auf die Schlüssel keys()) und values() zuzugreifen
um diese dann je Zeile auszugeben.

for t in buecher_dg:
print(t)

wirft aus:
{'Titel': 'der alte Mann', 'Autor': 'Theo', 'Nr.': 1, 'Preis': 19.8}
{'Titel': 'die alte Frau ', 'Autor': 'Sandra', 'Nr.': 2, 'Preis': 32.0}
{'Titel': 'die alte Katze ', 'Autor': 'Leo', 'Nr.': 3, 'Preis': 14.9}

Wie sage ich, mittels einer Schleifer ->
1. Zeile Titel
2. Zeile Wert von Titel
3. Zeile Autor
4. Zeile Wert von Autor

usw. analog dem ersten Beispiel mit der Liste.

Hat jemand Lust? zu helfen?

vg
Kai
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Ich gehe erst einmal nur auf den ersten Teil (Speicherung in einer Liste) ein.

Für die Struktur eines einzelnen Buches würde man eher keine Liste sondern ein Tupel verwenden. Gehen wir aber mal davon aus, dass das nur zu Lernzwecken sein soll. Dann haben wir auf jeden Fall noch eine schlechte Namenswahl. `buecher_l1` ist ein Buch. Eins. Nicht mehrere Bücher. Also sollte im Namen der Variable auch nicht "buecher" auftauchen. Und was soll "buecher_lg" sein. Das sind einfach Bücher, also nenn die Variable doch auch einfach so: `buecher`.

Code: Alles auswählen

buch_1 = ["der alte Mann", "Theo", 1, 19.80]
buch_2 = ["die alte Frau", "Sandra", 2, 32.00]
buch_3 = ["die alte Katze", "Leo", 3, 14.90]

buecher = [buch_1, buch_2, buch_3]

# oder besser direkt

buecher = [
    ["der alte Mann", "Theo", 1, 19.80],
    ["die alte Frau", "Sandra", 2, 32.00],
    ["die alte Katze", "Leo", 3, 14.90]]

derkai74 hat geschrieben: Freitag 14. Januar 2022, 17:48

Code: Alles auswählen

a = 0
for x in buecher_lg:
      a = 0
      for y in x:
          print((x)[a])
          a += 1
Das bringt das Ergebnis, was erreicht werden soll.
Kann sein, aber es ist völlig kurioser und übermäßig komplizierter Code. Du hast die Schleife mit `for y in x`, verwendest das `y` dann aber gar nicht und führst stattdessen manuell einen Zähler mit, um dann mit einem Indexzugriff auf `x` zu arbeiten. Deine Neigung zu nicht besonders gut gewählten Variablennamen macht dir vermutlich das Programmieren nicht einfacher. Mir erschwert es das Lesen deines Codes auf jeden Fall.

Das könnte einfach so aussehen:

Code: Alles auswählen

for buch in buecher:
    for info in buch:
        print(info)
Benutzeravatar
__blackjack__
User
Beiträge: 13102
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Für das zweite Beispiel, meinst Du das so?

Code: Alles auswählen

books = [
    {"Titel": "der alte Mann", "Autor": "Theo", "Nr.": 1, "Preis": 19.8},
    {"Titel": "die alte Frau ", "Autor": "Sandra", "Nr.": 2, "Preis": 32.0},
    {"Titel": "die alte Katze ", "Autor": "Leo", "Nr.": 3, "Preis": 14.9},
]
for book in books:
    for key in ["Titel", "Autor", "Preis"]:
        print(key)
        print(book[key])
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
wlfmario
User
Beiträge: 10
Registriert: Donnerstag 28. Juni 2018, 20:04
Wohnort: 192.168.0.1

Hallo zusammen,

hier ein mittelalter Kai aus dem Rheinland.
Bei Schinken würde man vielleicht sagen -> gut abgehangen.

Habe mir irgendwie in den Kopf gesetzt etwas programmieren zu wollen.
Ich bereue es fast jetzt schon. Puh, ist da viel zu lernen. Aber mit meinem fast
nicht vorhandenen Vorwissen, habe ich es ja so gewollt.
Hallo Kai,

es scheint wohl in Mode zu kommen, das dass Trockenfleisch aus dem Rheinland sich im Alter Problemen stellt, die man ohne Computer nie hätte ! :D
Ich bin nämlich auch so jemand und aus dem Rheinland . :lol: :lol: :lol: :lol: :lol:
Da ich zwar schon kleine Versuche in C# und Java gestartet habe, merkte ich aber sehr Schnell, das Python da schon um einiges Einsteigerfreundlich ist und schneller Erfolge liefert.
Es ist ja schon Toll, das ich lese, dass ich nicht der Einzige bin, der sich in der Mittelalterklasse noch an das Thema wagt.

Gruß Mario
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

Also, habt vielen Dank.
Ja, das zweite Beispiel war genau so gedacht.

Erkenntnis 1) Ihr seit SUPER !!! - So macht lernen echt Spaß.
Erkenntnis 2) Ich muss dringend aufhören so kompliziert zu denken.

Ich habe jetzt das dritte Beispiel des Buches > Tupel mit for durchlaufen < so gelöst:

Code: Alles auswählen

# Tupel mit for durchlaufen
buecher_tupel = [
    ("der alte Mann", "Theo", 1, 19.80),
    ("die alte Frau", "Sandra", 2, 32.00),
    ("die alte Katze", "Leo", 3, 14.90)
]

# buecher_t [0][0] = "neu"         erwartetet Fehler, da Tupel unveränderbar

for book in buecher_tupel:
    for info in book:
        print(info)
Die Variable buecher_tupel habe ich bewußt gewählt, damit ich es später
für mich besser auseinander halten kann.

Vielen Dank nochmals

Kai
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

@ Mario:

Das Problem ist halt, dass man kaum noch vor die Türe kommt und
ich - je älter - ich werde, wohl auch schwerfälliger werde :)

Gut, dass Winter ist, sonst hätte ich manchmal wohl schon aufgegeben.

Aber ich habe zwei (ehrgeizige) Pläne. Bin mal gespannt, ob ich sie verwirklichen kann.

Es macht gerade einfach mega Spass.

..... der Rhein - Sieg - Länder

Kai
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

ok, ich wäre bereit für eine weitere Lektion.

geht das besser?
was sollte ich ausbessern? kürzer, oder unkomplizierter machen?

Code: Alles auswählen

from datetime import datetime, date, timedelta
Funktion 1:

Code: Alles auswählen

# Tage zwischen 2 Datumsangaben
def dif_tage (kl_datum, gr_datum):
    kl_datum = datetime.strptime(kl_datum, "%d.%m.%Y")
    gr_datum = datetime.strptime(gr_datum, "%d.%m.%Y")
    return 1 + (gr_datum - kl_datum).days
Funktion 2:

Code: Alles auswählen

# Datum um Anzahl Tage zu verändern
def neues_datum (datum, hinzu):                           # Tage sind als int einzulesen
    datum = datetime.strptime(datum, "%d.%m.%Y")
    return (datum + timedelta(days=(hinzu-1)))
vg
Kai
Benutzeravatar
__blackjack__
User
Beiträge: 13102
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@derkai74: Keine kryptischen Abkürzungen in Namen. `kl`? `gr`? Ich rate mal ”klein…” und ”gross…”? Das wird nirgends sichergestellt. `dif`?

Bei beiden Funktionen ist es überraschend, dass die als Argumente *Texte* erwarten und keine `date`/`datetime`-Objekte.

Bei beiden ist die Anpassung um 1 verwirrend bis falsch. Die Differenz zwischen Heute und Heute ist 0 Tage und nicht 1 Tag. Und wenn ich zu Heute einen Tag addiere habe ich Morgen und nicht immer noch Heute.

`neues_datum()` beschreibt keine Tätigkeit und `hinzu` ist ein komischer Name für einen Wert.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

ok, Danke für Deine Rückmeldung.

1) kryptische Abkürzungen. Richtig geraten. Ich habe es geändert.
2) Die Differenz der Tage ist von mir falsch ausgedrückt.
Es geht nicht um die Differenz, sondern Anzahl der Tage zwischen
zwei Daten. Ich habe den Namen der Funktion korrigiert.
3) Ich habe über eine if Anweisung sichergestellt, dass die Benutzereingaben
überprüft werden. Ob es bei dem "Fehlerhinweis" in dieser Form bleibt,
muss ich mir später noch überlegen. War das so gemeint?
4) Ja, die Addition von einem Tag zu heute IST morgen.
Da habe ich mich wohl selber überlistet.
5) neues_datum beschreibt keine Tätigkeit.
Meinst Du damit, dass ich den Namen der Funktion so benennen soll,
dass die "Tätigkeit", also der Sinn der Funktion sinnvoller beschrieben ist?
Hab ich gemacht.

Herausgekommen ist dabei das hier:

Funktion 1:

Code: Alles auswählen

# Anzahl der Tage zwischen 2 Datumsangaben
def anz_tage (kleines_datum, grosses_datum):
    kleines_datum = datetime.strptime(kleines_datum, "%d.%m.%Y")
    grosses_datum = datetime.strptime(grosses_datum, "%d.%m.%Y")
    if grosses_datum >= kleines_datum:
        return 1 + (grosses_datum - kleines_datum).days
    else:
        return "Das Ende Datum ist größer als das Anfangsdatum."
Funktion 2:

Code: Alles auswählen

# Datum um Anzahl Tage zu verändern
def ber_neues_datum (datum, addieren):                           # Tage sind als int einzulesen
    datum = datetime.strptime(datum, "%d.%m.%Y")
    return (datum + timedelta(days=(addieren)))
Bei beiden Funktionen ist es überraschend, dass die als Argumente *Texte* erwarten und keine `date`/`datetime`-Objekte.
Da liegt vielleicht noch ein grundsätzliches ? bei mir vor.

Ich gehe ja davon aus, dass der Nutzer das Datum später in der Form
dd.mm.YYYY eingeben wird. So weit ich es verstanden habe, wird für
datetime, date usw ja aber ein Datum im Format YYYY-mm-dd benötigt.

Ist das falsch?

Wenn ich die Benutzereingabe -> 15.01.2022 eingebe, dann wird ja ein string eingelesen.
Muss ich dann nicht irgendwo umwandeln?

auch wenn auf die schnelle etwas "kryptisch":

Code: Alles auswählen

# Datum Benutzeringabe umwandeln in rechenbares Datum
def umw_datum_b (ben_eingabe):
    z_schritt = datetime.strptime(ben_eingabe, "%d.%m.%Y")
    return datetime.date(z_schritt)
ergibt: 2022-01-15
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Du bestätigst, dass kryptische Abkürzungen schlecht sind, benutzt sie dann aber munter weiter `umw`? Und was soll das `b` bedeuten? Wer ist Ben? Und der z-Schritt? Neben Ben gibt es auch noch Ber, ist das nun die Abkürzung für Berta oder Bärbel?
Benutzeravatar
__blackjack__
User
Beiträge: 13102
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@derkai74: Ad 5) Ja das war gemeint und `anz_tage()` ist ja auch wieder keine Tätigkeit. Dabei geht es zum einen darum, das der Leser weiss was die Funktion tut, und zum anderen dass der Leser weiss, dass es sich um eine Funktion handelt und nicht um einen eher passiven Wert. Oder aus Sicht von Werten: Wenn die Funktion nicht die Tätigkeit beschreibt, sondern eher wie ein Wert klingt, am Ende vielleicht sogar noch wie ein guter Name für den Wert den das Ergebnis dieser Funktion haben könnte, dann ”verliert” man diesen Namen für Werte. Dafür ist die erste Funktion ja ein gutes Beispiel. Mal die Abkürzung kurz ausser acht gelassen, wenn man die Anzahl der Tage ausrechnet und an einen Namen binden möchte, bietet sich ja irgendwie `anzahl_tage` dafür an. Nur heisst jetzt dummerweise die Funktion schon so und so was wie ``anzahl_tage = anzahl_tage(startdatum, enddatum)`` verwirrt im besten Fall nur den Leser, führt aber auch dazu das man nach dieser Zeile, zumindest im gleichen Namensraum, die Funktion nicht mehr benutzen kann, weil an den Namen jetzt eine Zahl gebunden ist und nicht mehr die Funktion.

Da habe ich eben gerade nebenbei auch gleich noch verraten was ich für bessere Namen als `kleines_datum` und `grosses_datum` halte, nämlich `startdatum` (oder `anfangsdatum`) und `enddatum`. Und als Funktionsname dann vielleicht `berechne_tagesanzahl()`. Bei der Funktionssignatur ``def berechne_tagesanzahl(startdatum, enddatum):`` hat der Leser sehr wahrscheinlich eine gute Vorstellung davon was die Funktion tut, was die Argumente bedeuten, und was die Funktion als Ergebnis liefert.

Eine Zahl *oder* eine Zeichenkette mit Fehlermeldung als Rückgabewert ist keine sinnvolle API. Für Fehler sind Ausnahmen da.

`addieren` ist auch kein guter Name für das alte `hinzu`. Erst mal ist das ja eine Tätigkeit, der Benutzer könnte sich also wundern was für eine Funktion er da übergeben soll, und dann sagt doch auch der Name nicht was die Bedeutung von dem Wert ist. Im simpelsten Fall könnte man das einfach `anzahl` oder `anzahl_tage` oder `tage` nennen, je nach dem was für einen Funktionsnamen man wählt und ob man in Kombination dann zumindest gut erahnen kann was da an der Stelle als Argument erwartet wird. Also beispielsweise ``def addiere_tage(datum, anzahl):`` wäre IMHO recht aussagekräftig.

Ja klar musst Du ein als Text eingegebenes Datum zum rechnen in ein Datumsobjekt umwandeln. Aber nicht in den Funktionen die mit Datumsangaben rechnen sollen. Das würde früher oder später zu einem schwer zu durchschauenden sinnlosen hin und her konvertieren zwischen Datumsobjekten und Zeichenketten führen. Zudem ist die `addiere_tage()`-Funktion ja auch ”asymmetrisch”, das heisst die erwartet ein Datum in den Argumenten und liefert ein Datum als Ergebnis — aber das Argument ist eine Zeichenkette und das Ergebnis ein Datumsobjekt. Das ist überraschend.

Ungetestet:

Code: Alles auswählen

from datetime import timedelta as TimeDelta


def berechne_tagesanzahl(startdatum, enddatum):
    if enddatum < startdatum:
        raise ValueError(
            f"enddatum ({enddatum!r}) < startdatum ({startdatum!r})"
        )

    return (enddatum - startdatum).days + 1


def addiere_tage(datum, anzahl):
    return datum + TimeDelta(days=anzahl)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
derkai74
User
Beiträge: 39
Registriert: Montag 27. Dezember 2021, 22:14

Vielen Dank __blackjack__ für Deine ausführliche Antwort.
Ich denke, ich habe jetzt verstanden, was Du meinst.
Aktuell habe ich nichts Neues beizutragen.

Außer vielleicht, warum Du timedelta as TimeDelta importiert hast.
War das n Test? :)

Ich werde jetzt erstmal die nächste Lektion lernen.

Nochmals vielen Dank.

Kai
Antworten