<type 'int'> mit <type 'bool'> addieren?

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.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Hallo,

es funktioniert, nur: Ist das ok oder kann das Probleme machen?

Code: Alles auswählen

In [21]: 1 + True
Out[21]: 2
Es geht mir darum, dass ich einen Wert (days) um 1 erhöhen möchte, wenn eine Funktion (is_leap) 'True' zurückgibt, etwas in der Art:

Code: Alles auswählen

days += is_leap(date)
Gruß
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

mutetella hat geschrieben:Ist das ok oder kann das Probleme machen?
Ist ok, macht keine Probleme.
Im Einzelfall sollte man lediglich überlegen, inwieweit es die Lesbarkeit des Codes verschlechtert.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

numerix hat geschrieben:... überlegen, inwieweit es die Lesbarkeit des Codes verschlechtert.
Also würdest Du eher

Code: Alles auswählen

if is_leap(year):
    days += 1
verwenden?
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

mutetella hat geschrieben:
numerix hat geschrieben:... überlegen, inwieweit es die Lesbarkeit des Codes verschlechtert.
Also würdest Du eher

Code: Alles auswählen

if is_leap(year):
    days += 1
verwenden?
Nö, weil ich ein Freund der Kürze bin ... :)
Mein Hinweis bezog sich eher auf Ausdrücke, die komplexer sind und deren Lesbarkeit man dann ggf. durch solche Elemente verschlechtert. Das Inkrementieren mit einem Wahrheitswert als einzelne Anweisung sollte keine Lesbarkeitsprobleme verursachen.
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

@mutetella: Wofür brauchst du das denn? Sollte es um Schaltjahre gehen, ist das 'datetime'-Modul sicherlich einen Blick wert.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@gkuhl:
Leider bietet das datetime-Modul keine Funktion, über die ich Schaltjahre abfragen kann. Das calendar-Modul hat eine isleap(), und die liefert entweder True oder False. Von daher meine Frage.
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Ich fragte, weil es so klingt, als versuchst du den Tag des Jahres zu bestimmen. Was man wie folgt lösen kann:

Code: Alles auswählen

In [2]: from datetime import datetime as DateTime

In [3]: DateTime.today().strftime('%j')
Out[3]: '293'
Grüße
Gerrit
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@gkuhl:
Ne, mir geht es um Sprünge vom 29. Februar um 1 Jahr vor oder zurück bzw. das Ermitteln des jeweils letzten Tages im Monat. Und dafür muss ich wissen, ob das Zieldatum ein Schaltjahr ist oder nicht.
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Also ich persönlich finds schon hässlich True als Shortcut für ``1`` zu mißbrauchen.

Das hat zwar dann eher was von Happy cat is happy, aber wenigstens wundert man sich nicht was der Autor da machen wollte:

Code: Alles auswählen

1 + 1 if is_leap(year) else 0
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Panke
User
Beiträge: 185
Registriert: Sonntag 18. März 2007, 19:26

mutetella hat geschrieben:@gkuhl:
Ne, mir geht es um Sprünge vom 29. Februar um 1 Jahr vor oder zurück bzw. das Ermitteln des jeweils letzten Tages im Monat. Und dafür muss ich wissen, ob das Zieldatum ein Schaltjahr ist oder nicht.
Nimm den ersten Tag des Folgemonats und ziehe davon einen Tag ab. datetime macht den Rest.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Panke hat geschrieben:Nimm den ersten Tag des Folgemonats und ziehe davon einen Tag ab.
Das wäre dann also

Code: Alles auswählen

date.replace(day=1, month=(date.month + 1)
date -= timedelta(1)
Ist 'ne funktionierende Lösung. Gefällt mir aber nicht.

Code: Alles auswählen

day = [31, 28 + is_leap(date.year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][date.month - 1]
date.replace(day=day)
Gefällt mir besser.
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Du findest eine per Hand erstellte Liste einfacher als eine gut lesbare und intuitive Lösung? Gut, noch einfacher ist natürlich eine fertige Lösung (welche man übrigens in weniger als 10 Sekunden mit einer Suche nach "days in month" findet) ;-)
Das Leben ist wie ein Tennisball.
Benutzeravatar
snafu
User
Beiträge: 6744
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

mutetella hat geschrieben:Also würdest Du eher

Code: Alles auswählen

if is_leap(year):
    days += 1
verwenden?
Ich würde es wohl tun.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

EyDu hat geschrieben:Du findest eine per Hand erstellte Liste einfacher als eine gut lesbare und intuitive Lösung?
Dann erklär' mir doch mal bitte, was calendar.monthrange() anderes macht, als aus einer "per Hand" erstellten Liste die jeweilige Anzahl der Tage pro Monat herauszupicken....


calendar.monthrange():

Code: Alles auswählen

# Constants for months referenced later
January = 1
February = 2

# Number of days per month (except for February in leap years)
mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

def monthrange(year, month):
    """Return weekday (0-6 ~ Mon-Sun) and number of days (28-31) for
       year, month."""
    if not 1 <= month <= 12:
        raise IllegalMonthError(month)
    day1 = weekday(year, month, 1)
    ndays = mdays[month] + (month == February and isleap(year))
    return day1, ndays

def isleap(year):
    """Return 1 for leap years, 0 for non-leap years."""
    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
Wobei monthrange() auch mit True/False "rechnet", also True als 1 "missbraucht". Der docstring aus isleap() ist da nicht ganz ehrlich.
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
lunar

@Leonidas: Ich wundere mich durchaus, was Du bei dieser Variante machen wolltest, liefert sie doch mithin nicht das erwartete Ergebnis. Die Addition wird nämlich vor dem bedingten Ausdruck ausgewertet, so dass der Ausdruck im Gesamten entweder 2 oder 0 ergibt, aber nicht 1.

Folglich halte ich diese Variante für die unglücklichste, bietet sie doch ganz offensichtlich Anlass zu reichlich subtilen Fehlern. Die beiden anderen Varianten sind meines Erachtens völlig gleichwertig, schließlich ist die Verwandtschaft zwischen Ganzzahlen und Wahrheitswerten eine dokumentierte Eigenschaft der Sprache, und sollte mithin bekannt sein.

@mutetella: Man hat Dir aber schon erklärt, dass es der Sinn der Bibliothek in ihrer Verwendung liegt und nicht darin, die Implementierung derselbe in den eigenen Quelltext zu kopieren?! Verzeih mir den Spott, doch ich finde es ziemlich merkwürdig, eine eigene Implementierung mit dem Verweis darauf zu verteidigen, dass die Bibliothek es exakt genauso macht. Das führt nämlich unmittelbar zur Frage, warum Du auf der erneuten Erfindung des Rades in exakt derselben Form bestehst ...

Im Übrigen ist der Docstring von "isleap()" vollauf ehrlich, da "True" und "False" echte Ganzzahlen sind, und zwar im Wert von 1 bzw. 0. Das ist dokumentiert, und lässt sich mit einem einfachen "isinstance(True, int)" auch selbst herausfinden.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

lunar hat geschrieben:..., die Implementierung derselbe in den eigenen Quelltext zu kopieren?! Verzeih mir den Spott, doch ich finde es ziemlich merkwürdig, eine eigene Implementierung mit dem Verweis darauf zu verteidigen, dass die Bibliothek es exakt genauso macht.
Wenngleich es wohl keine Rolle spielt, muss ich mich hier doch verteidigen. Dass calendar.monthrange() in derselben Weise wie ich vorgeht, habe ich gerade vor 15 Minuten entdeckt, als ich aufgrund von EyDu's Beitrag zu meiner Schande überhaupt erst erfuhr, dass es diese Funktion gibt. Von kopieren kann also keine Rede sein. Vielmehr fühle ich mich dadurch, dass die Autoren des calendar-Moduls in diesem Punkt genauso verfahren, bestätigt.
Du hast natürlich damit Recht, dass eine bereits vorhandene Bibliothek auch verwendet werden will. Allerdings versuche ich bei der Lösung eines so kleinen Problems wie der Ermittlung der Tagesanzahl eines Monats, eigene Funktionen zu verwenden. Darüber mag man geteilter Ansicht sein, ich ziehe das einem

Code: Alles auswählen

from calendar import monthrange
vor.
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Hoffentlich gehört zu der eigenen Funktion auch die entsprechende Dokumentation und Tests...
lunar

@mutetella: Das war ironisch gemeint, ich habe nicht behauptet, dass Du kopiert hättest. Ich habe mich nur über Deine Art der Verteidigung gewundert ...

Ansonsten kannst Du in Deinem eigenen Programm nach Deinem Belieben verfahren, doch wirst Du wohl hier nicht viele Anhänger für diese Einstellung gewinnen können. Ich persönlich würde die Verwendung einer eigenen Implementierung gegenüber einer Bibliothek immer kritisieren, sofern nicht Gründe gegen die Bibliothek selbst sprechen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunar hat geschrieben:@Leonidas: Ich wundere mich durchaus, was Du bei dieser Variante machen wolltest, liefert sie doch mithin nicht das erwartete Ergebnis. Die Addition wird nämlich vor dem bedingten Ausdruck ausgewertet, so dass der Ausdruck im Gesamten entweder 2 oder 0 ergibt, aber nicht 1.
Uhm, ja, Klammern eben...
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

lunar hat geschrieben:Ansonsten kannst Du in Deinem eigenen Programm nach Deinem Belieben verfahren, ...
Da hab' ich mich gestern vielleicht etwas zu absolut ausgedrückt. Es fehlt mir bei weitem die Erfahrung, aufgrund derer ich sagen könnte, es so oder anderst zu machen. In diesem konkreten Fall habe ich mich einfach sehr darüber gefreut, endlich einmal etwas in einer Art und Weise gelöst zu haben, mit der offensichtlich auch Profis das Problem angegangen sind. Und soetwas lässt man sich natürlich nicht gleich wieder nehmen... :) calendar.monthrange() nicht zu importieren war also nicht eine Entscheidung besseren Wissens, sondern schlichtweg purer Stolz auf meinen [ironie]genialen Einfall, die jeweilige Tagesanzahl eines Monats zu ermitteln.[/ironie]
lunar hat geschrieben:Ich persönlich würde die Verwendung einer eigenen Implementierung gegenüber einer Bibliothek immer kritisieren, ...
Wenn Freude und Stolz verflogen sind, werde ich also isleap() und monthrange() importieren. Bleibt für mich nur die Frage nach dem warum? Schießt man nicht mit Kanonen auf Spatzen, wenn man wegen 5 oder 6 Zeilen Programmcode auf eine externe Bibliothek zugreift? Bei einer built-in Funktion ist das ja überhaupt kein Thema, aber extra importieren?
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Antworten